main.js 769 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977
  1. /*!
  2. * jQuery JavaScript Library v3.2.1
  3. * https://jquery.com/
  4. *
  5. * Includes Sizzle.js
  6. * https://sizzlejs.com/
  7. *
  8. * Copyright JS Foundation and other contributors
  9. * Released under the MIT license
  10. * https://jquery.org/license
  11. *
  12. * Date: 2017-03-20T18:59Z
  13. */
  14. ( function( global, factory ) {
  15. "use strict";
  16. if ( typeof module === "object" && typeof module.exports === "object" ) {
  17. // For CommonJS and CommonJS-like environments where a proper `window`
  18. // is present, execute the factory and get jQuery.
  19. // For environments that do not have a `window` with a `document`
  20. // (such as Node.js), expose a factory as module.exports.
  21. // This accentuates the need for the creation of a real `window`.
  22. // e.g. var jQuery = require("jquery")(window);
  23. // See ticket #14549 for more info.
  24. module.exports = global.document ?
  25. factory( global, true ) :
  26. function( w ) {
  27. if ( !w.document ) {
  28. throw new Error( "jQuery requires a window with a document" );
  29. }
  30. return factory( w );
  31. };
  32. } else {
  33. factory( global );
  34. }
  35. // Pass this if window is not defined yet
  36. } )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
  37. // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
  38. // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
  39. // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
  40. // enough that all such attempts are guarded in a try block.
  41. "use strict";
  42. var arr = [];
  43. var document = window.document;
  44. var getProto = Object.getPrototypeOf;
  45. var slice = arr.slice;
  46. var concat = arr.concat;
  47. var push = arr.push;
  48. var indexOf = arr.indexOf;
  49. var class2type = {};
  50. var toString = class2type.toString;
  51. var hasOwn = class2type.hasOwnProperty;
  52. var fnToString = hasOwn.toString;
  53. var ObjectFunctionString = fnToString.call( Object );
  54. var support = {};
  55. function DOMEval( code, doc ) {
  56. doc = doc || document;
  57. var script = doc.createElement( "script" );
  58. script.text = code;
  59. doc.head.appendChild( script ).parentNode.removeChild( script );
  60. }
  61. /* global Symbol */
  62. // Defining this global in .eslintrc.json would create a danger of using the global
  63. // unguarded in another place, it seems safer to define global only for this module
  64. var
  65. version = "3.2.1",
  66. // Define a local copy of jQuery
  67. jQuery = function( selector, context ) {
  68. // The jQuery object is actually just the init constructor 'enhanced'
  69. // Need init if jQuery is called (just allow error to be thrown if not included)
  70. return new jQuery.fn.init( selector, context );
  71. },
  72. // Support: Android <=4.0 only
  73. // Make sure we trim BOM and NBSP
  74. rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
  75. // Matches dashed string for camelizing
  76. rmsPrefix = /^-ms-/,
  77. rdashAlpha = /-([a-z])/g,
  78. // Used by jQuery.camelCase as callback to replace()
  79. fcamelCase = function( all, letter ) {
  80. return letter.toUpperCase();
  81. };
  82. jQuery.fn = jQuery.prototype = {
  83. // The current version of jQuery being used
  84. jquery: version,
  85. constructor: jQuery,
  86. // The default length of a jQuery object is 0
  87. length: 0,
  88. toArray: function() {
  89. return slice.call( this );
  90. },
  91. // Get the Nth element in the matched element set OR
  92. // Get the whole matched element set as a clean array
  93. get: function( num ) {
  94. // Return all the elements in a clean array
  95. if ( num == null ) {
  96. return slice.call( this );
  97. }
  98. // Return just the one element from the set
  99. return num < 0 ? this[ num + this.length ] : this[ num ];
  100. },
  101. // Take an array of elements and push it onto the stack
  102. // (returning the new matched element set)
  103. pushStack: function( elems ) {
  104. // Build a new jQuery matched element set
  105. var ret = jQuery.merge( this.constructor(), elems );
  106. // Add the old object onto the stack (as a reference)
  107. ret.prevObject = this;
  108. // Return the newly-formed element set
  109. return ret;
  110. },
  111. // Execute a callback for every element in the matched set.
  112. each: function( callback ) {
  113. return jQuery.each( this, callback );
  114. },
  115. map: function( callback ) {
  116. return this.pushStack( jQuery.map( this, function( elem, i ) {
  117. return callback.call( elem, i, elem );
  118. } ) );
  119. },
  120. slice: function() {
  121. return this.pushStack( slice.apply( this, arguments ) );
  122. },
  123. first: function() {
  124. return this.eq( 0 );
  125. },
  126. last: function() {
  127. return this.eq( -1 );
  128. },
  129. eq: function( i ) {
  130. var len = this.length,
  131. j = +i + ( i < 0 ? len : 0 );
  132. return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
  133. },
  134. end: function() {
  135. return this.prevObject || this.constructor();
  136. },
  137. // For internal use only.
  138. // Behaves like an Array's method, not like a jQuery method.
  139. push: push,
  140. sort: arr.sort,
  141. splice: arr.splice
  142. };
  143. jQuery.extend = jQuery.fn.extend = function() {
  144. var options, name, src, copy, copyIsArray, clone,
  145. target = arguments[ 0 ] || {},
  146. i = 1,
  147. length = arguments.length,
  148. deep = false;
  149. // Handle a deep copy situation
  150. if ( typeof target === "boolean" ) {
  151. deep = target;
  152. // Skip the boolean and the target
  153. target = arguments[ i ] || {};
  154. i++;
  155. }
  156. // Handle case when target is a string or something (possible in deep copy)
  157. if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
  158. target = {};
  159. }
  160. // Extend jQuery itself if only one argument is passed
  161. if ( i === length ) {
  162. target = this;
  163. i--;
  164. }
  165. for ( ; i < length; i++ ) {
  166. // Only deal with non-null/undefined values
  167. if ( ( options = arguments[ i ] ) != null ) {
  168. // Extend the base object
  169. for ( name in options ) {
  170. src = target[ name ];
  171. copy = options[ name ];
  172. // Prevent never-ending loop
  173. if ( target === copy ) {
  174. continue;
  175. }
  176. // Recurse if we're merging plain objects or arrays
  177. if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
  178. ( copyIsArray = Array.isArray( copy ) ) ) ) {
  179. if ( copyIsArray ) {
  180. copyIsArray = false;
  181. clone = src && Array.isArray( src ) ? src : [];
  182. } else {
  183. clone = src && jQuery.isPlainObject( src ) ? src : {};
  184. }
  185. // Never move original objects, clone them
  186. target[ name ] = jQuery.extend( deep, clone, copy );
  187. // Don't bring in undefined values
  188. } else if ( copy !== undefined ) {
  189. target[ name ] = copy;
  190. }
  191. }
  192. }
  193. }
  194. // Return the modified object
  195. return target;
  196. };
  197. jQuery.extend( {
  198. // Unique for each copy of jQuery on the page
  199. expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
  200. // Assume jQuery is ready without the ready module
  201. isReady: true,
  202. error: function( msg ) {
  203. throw new Error( msg );
  204. },
  205. noop: function() {},
  206. isFunction: function( obj ) {
  207. return jQuery.type( obj ) === "function";
  208. },
  209. isWindow: function( obj ) {
  210. return obj != null && obj === obj.window;
  211. },
  212. isNumeric: function( obj ) {
  213. // As of jQuery 3.0, isNumeric is limited to
  214. // strings and numbers (primitives or objects)
  215. // that can be coerced to finite numbers (gh-2662)
  216. var type = jQuery.type( obj );
  217. return ( type === "number" || type === "string" ) &&
  218. // parseFloat NaNs numeric-cast false positives ("")
  219. // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
  220. // subtraction forces infinities to NaN
  221. !isNaN( obj - parseFloat( obj ) );
  222. },
  223. isPlainObject: function( obj ) {
  224. var proto, Ctor;
  225. // Detect obvious negatives
  226. // Use toString instead of jQuery.type to catch host objects
  227. if ( !obj || toString.call( obj ) !== "[object Object]" ) {
  228. return false;
  229. }
  230. proto = getProto( obj );
  231. // Objects with no prototype (e.g., `Object.create( null )`) are plain
  232. if ( !proto ) {
  233. return true;
  234. }
  235. // Objects with prototype are plain iff they were constructed by a global Object function
  236. Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
  237. return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
  238. },
  239. isEmptyObject: function( obj ) {
  240. /* eslint-disable no-unused-vars */
  241. // See https://github.com/eslint/eslint/issues/6125
  242. var name;
  243. for ( name in obj ) {
  244. return false;
  245. }
  246. return true;
  247. },
  248. type: function( obj ) {
  249. if ( obj == null ) {
  250. return obj + "";
  251. }
  252. // Support: Android <=2.3 only (functionish RegExp)
  253. return typeof obj === "object" || typeof obj === "function" ?
  254. class2type[ toString.call( obj ) ] || "object" :
  255. typeof obj;
  256. },
  257. // Evaluates a script in a global context
  258. globalEval: function( code ) {
  259. DOMEval( code );
  260. },
  261. // Convert dashed to camelCase; used by the css and data modules
  262. // Support: IE <=9 - 11, Edge 12 - 13
  263. // Microsoft forgot to hump their vendor prefix (#9572)
  264. camelCase: function( string ) {
  265. return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
  266. },
  267. each: function( obj, callback ) {
  268. var length, i = 0;
  269. if ( isArrayLike( obj ) ) {
  270. length = obj.length;
  271. for ( ; i < length; i++ ) {
  272. if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
  273. break;
  274. }
  275. }
  276. } else {
  277. for ( i in obj ) {
  278. if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
  279. break;
  280. }
  281. }
  282. }
  283. return obj;
  284. },
  285. // Support: Android <=4.0 only
  286. trim: function( text ) {
  287. return text == null ?
  288. "" :
  289. ( text + "" ).replace( rtrim, "" );
  290. },
  291. // results is for internal usage only
  292. makeArray: function( arr, results ) {
  293. var ret = results || [];
  294. if ( arr != null ) {
  295. if ( isArrayLike( Object( arr ) ) ) {
  296. jQuery.merge( ret,
  297. typeof arr === "string" ?
  298. [ arr ] : arr
  299. );
  300. } else {
  301. push.call( ret, arr );
  302. }
  303. }
  304. return ret;
  305. },
  306. inArray: function( elem, arr, i ) {
  307. return arr == null ? -1 : indexOf.call( arr, elem, i );
  308. },
  309. // Support: Android <=4.0 only, PhantomJS 1 only
  310. // push.apply(_, arraylike) throws on ancient WebKit
  311. merge: function( first, second ) {
  312. var len = +second.length,
  313. j = 0,
  314. i = first.length;
  315. for ( ; j < len; j++ ) {
  316. first[ i++ ] = second[ j ];
  317. }
  318. first.length = i;
  319. return first;
  320. },
  321. grep: function( elems, callback, invert ) {
  322. var callbackInverse,
  323. matches = [],
  324. i = 0,
  325. length = elems.length,
  326. callbackExpect = !invert;
  327. // Go through the array, only saving the items
  328. // that pass the validator function
  329. for ( ; i < length; i++ ) {
  330. callbackInverse = !callback( elems[ i ], i );
  331. if ( callbackInverse !== callbackExpect ) {
  332. matches.push( elems[ i ] );
  333. }
  334. }
  335. return matches;
  336. },
  337. // arg is for internal usage only
  338. map: function( elems, callback, arg ) {
  339. var length, value,
  340. i = 0,
  341. ret = [];
  342. // Go through the array, translating each of the items to their new values
  343. if ( isArrayLike( elems ) ) {
  344. length = elems.length;
  345. for ( ; i < length; i++ ) {
  346. value = callback( elems[ i ], i, arg );
  347. if ( value != null ) {
  348. ret.push( value );
  349. }
  350. }
  351. // Go through every key on the object,
  352. } else {
  353. for ( i in elems ) {
  354. value = callback( elems[ i ], i, arg );
  355. if ( value != null ) {
  356. ret.push( value );
  357. }
  358. }
  359. }
  360. // Flatten any nested arrays
  361. return concat.apply( [], ret );
  362. },
  363. // A global GUID counter for objects
  364. guid: 1,
  365. // Bind a function to a context, optionally partially applying any
  366. // arguments.
  367. proxy: function( fn, context ) {
  368. var tmp, args, proxy;
  369. if ( typeof context === "string" ) {
  370. tmp = fn[ context ];
  371. context = fn;
  372. fn = tmp;
  373. }
  374. // Quick check to determine if target is callable, in the spec
  375. // this throws a TypeError, but we will just return undefined.
  376. if ( !jQuery.isFunction( fn ) ) {
  377. return undefined;
  378. }
  379. // Simulated bind
  380. args = slice.call( arguments, 2 );
  381. proxy = function() {
  382. return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
  383. };
  384. // Set the guid of unique handler to the same of original handler, so it can be removed
  385. proxy.guid = fn.guid = fn.guid || jQuery.guid++;
  386. return proxy;
  387. },
  388. now: Date.now,
  389. // jQuery.support is not used in Core but other projects attach their
  390. // properties to it so it needs to exist.
  391. support: support
  392. } );
  393. if ( typeof Symbol === "function" ) {
  394. jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
  395. }
  396. // Populate the class2type map
  397. jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
  398. function( i, name ) {
  399. class2type[ "[object " + name + "]" ] = name.toLowerCase();
  400. } );
  401. function isArrayLike( obj ) {
  402. // Support: real iOS 8.2 only (not reproducible in simulator)
  403. // `in` check used to prevent JIT error (gh-2145)
  404. // hasOwn isn't used here due to false negatives
  405. // regarding Nodelist length in IE
  406. var length = !!obj && "length" in obj && obj.length,
  407. type = jQuery.type( obj );
  408. if ( type === "function" || jQuery.isWindow( obj ) ) {
  409. return false;
  410. }
  411. return type === "array" || length === 0 ||
  412. typeof length === "number" && length > 0 && ( length - 1 ) in obj;
  413. }
  414. var Sizzle =
  415. /*!
  416. * Sizzle CSS Selector Engine v2.3.3
  417. * https://sizzlejs.com/
  418. *
  419. * Copyright jQuery Foundation and other contributors
  420. * Released under the MIT license
  421. * http://jquery.org/license
  422. *
  423. * Date: 2016-08-08
  424. */
  425. (function( window ) {
  426. var i,
  427. support,
  428. Expr,
  429. getText,
  430. isXML,
  431. tokenize,
  432. compile,
  433. select,
  434. outermostContext,
  435. sortInput,
  436. hasDuplicate,
  437. // Local document vars
  438. setDocument,
  439. document,
  440. docElem,
  441. documentIsHTML,
  442. rbuggyQSA,
  443. rbuggyMatches,
  444. matches,
  445. contains,
  446. // Instance-specific data
  447. expando = "sizzle" + 1 * new Date(),
  448. preferredDoc = window.document,
  449. dirruns = 0,
  450. done = 0,
  451. classCache = createCache(),
  452. tokenCache = createCache(),
  453. compilerCache = createCache(),
  454. sortOrder = function( a, b ) {
  455. if ( a === b ) {
  456. hasDuplicate = true;
  457. }
  458. return 0;
  459. },
  460. // Instance methods
  461. hasOwn = ({}).hasOwnProperty,
  462. arr = [],
  463. pop = arr.pop,
  464. push_native = arr.push,
  465. push = arr.push,
  466. slice = arr.slice,
  467. // Use a stripped-down indexOf as it's faster than native
  468. // https://jsperf.com/thor-indexof-vs-for/5
  469. indexOf = function( list, elem ) {
  470. var i = 0,
  471. len = list.length;
  472. for ( ; i < len; i++ ) {
  473. if ( list[i] === elem ) {
  474. return i;
  475. }
  476. }
  477. return -1;
  478. },
  479. booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
  480. // Regular expressions
  481. // http://www.w3.org/TR/css3-selectors/#whitespace
  482. whitespace = "[\\x20\\t\\r\\n\\f]",
  483. // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
  484. identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
  485. // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
  486. attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
  487. // Operator (capture 2)
  488. "*([*^$|!~]?=)" + whitespace +
  489. // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
  490. "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
  491. "*\\]",
  492. pseudos = ":(" + identifier + ")(?:\\((" +
  493. // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
  494. // 1. quoted (capture 3; capture 4 or capture 5)
  495. "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
  496. // 2. simple (capture 6)
  497. "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
  498. // 3. anything else (capture 2)
  499. ".*" +
  500. ")\\)|)",
  501. // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
  502. rwhitespace = new RegExp( whitespace + "+", "g" ),
  503. rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
  504. rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
  505. rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
  506. rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
  507. rpseudo = new RegExp( pseudos ),
  508. ridentifier = new RegExp( "^" + identifier + "$" ),
  509. matchExpr = {
  510. "ID": new RegExp( "^#(" + identifier + ")" ),
  511. "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
  512. "TAG": new RegExp( "^(" + identifier + "|[*])" ),
  513. "ATTR": new RegExp( "^" + attributes ),
  514. "PSEUDO": new RegExp( "^" + pseudos ),
  515. "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
  516. "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
  517. "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
  518. "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
  519. // For use in libraries implementing .is()
  520. // We use this for POS matching in `select`
  521. "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
  522. whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
  523. },
  524. rinputs = /^(?:input|select|textarea|button)$/i,
  525. rheader = /^h\d$/i,
  526. rnative = /^[^{]+\{\s*\[native \w/,
  527. // Easily-parseable/retrievable ID or TAG or CLASS selectors
  528. rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
  529. rsibling = /[+~]/,
  530. // CSS escapes
  531. // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
  532. runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
  533. funescape = function( _, escaped, escapedWhitespace ) {
  534. var high = "0x" + escaped - 0x10000;
  535. // NaN means non-codepoint
  536. // Support: Firefox<24
  537. // Workaround erroneous numeric interpretation of +"0x"
  538. return high !== high || escapedWhitespace ?
  539. escaped :
  540. high < 0 ?
  541. // BMP codepoint
  542. String.fromCharCode( high + 0x10000 ) :
  543. // Supplemental Plane codepoint (surrogate pair)
  544. String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
  545. },
  546. // CSS string/identifier serialization
  547. // https://drafts.csswg.org/cssom/#common-serializing-idioms
  548. rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
  549. fcssescape = function( ch, asCodePoint ) {
  550. if ( asCodePoint ) {
  551. // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
  552. if ( ch === "\0" ) {
  553. return "\uFFFD";
  554. }
  555. // Control characters and (dependent upon position) numbers get escaped as code points
  556. return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
  557. }
  558. // Other potentially-special ASCII characters get backslash-escaped
  559. return "\\" + ch;
  560. },
  561. // Used for iframes
  562. // See setDocument()
  563. // Removing the function wrapper causes a "Permission Denied"
  564. // error in IE
  565. unloadHandler = function() {
  566. setDocument();
  567. },
  568. disabledAncestor = addCombinator(
  569. function( elem ) {
  570. return elem.disabled === true && ("form" in elem || "label" in elem);
  571. },
  572. { dir: "parentNode", next: "legend" }
  573. );
  574. // Optimize for push.apply( _, NodeList )
  575. try {
  576. push.apply(
  577. (arr = slice.call( preferredDoc.childNodes )),
  578. preferredDoc.childNodes
  579. );
  580. // Support: Android<4.0
  581. // Detect silently failing push.apply
  582. arr[ preferredDoc.childNodes.length ].nodeType;
  583. } catch ( e ) {
  584. push = { apply: arr.length ?
  585. // Leverage slice if possible
  586. function( target, els ) {
  587. push_native.apply( target, slice.call(els) );
  588. } :
  589. // Support: IE<9
  590. // Otherwise append directly
  591. function( target, els ) {
  592. var j = target.length,
  593. i = 0;
  594. // Can't trust NodeList.length
  595. while ( (target[j++] = els[i++]) ) {}
  596. target.length = j - 1;
  597. }
  598. };
  599. }
  600. function Sizzle( selector, context, results, seed ) {
  601. var m, i, elem, nid, match, groups, newSelector,
  602. newContext = context && context.ownerDocument,
  603. // nodeType defaults to 9, since context defaults to document
  604. nodeType = context ? context.nodeType : 9;
  605. results = results || [];
  606. // Return early from calls with invalid selector or context
  607. if ( typeof selector !== "string" || !selector ||
  608. nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
  609. return results;
  610. }
  611. // Try to shortcut find operations (as opposed to filters) in HTML documents
  612. if ( !seed ) {
  613. if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
  614. setDocument( context );
  615. }
  616. context = context || document;
  617. if ( documentIsHTML ) {
  618. // If the selector is sufficiently simple, try using a "get*By*" DOM method
  619. // (excepting DocumentFragment context, where the methods don't exist)
  620. if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
  621. // ID selector
  622. if ( (m = match[1]) ) {
  623. // Document context
  624. if ( nodeType === 9 ) {
  625. if ( (elem = context.getElementById( m )) ) {
  626. // Support: IE, Opera, Webkit
  627. // TODO: identify versions
  628. // getElementById can match elements by name instead of ID
  629. if ( elem.id === m ) {
  630. results.push( elem );
  631. return results;
  632. }
  633. } else {
  634. return results;
  635. }
  636. // Element context
  637. } else {
  638. // Support: IE, Opera, Webkit
  639. // TODO: identify versions
  640. // getElementById can match elements by name instead of ID
  641. if ( newContext && (elem = newContext.getElementById( m )) &&
  642. contains( context, elem ) &&
  643. elem.id === m ) {
  644. results.push( elem );
  645. return results;
  646. }
  647. }
  648. // Type selector
  649. } else if ( match[2] ) {
  650. push.apply( results, context.getElementsByTagName( selector ) );
  651. return results;
  652. // Class selector
  653. } else if ( (m = match[3]) && support.getElementsByClassName &&
  654. context.getElementsByClassName ) {
  655. push.apply( results, context.getElementsByClassName( m ) );
  656. return results;
  657. }
  658. }
  659. // Take advantage of querySelectorAll
  660. if ( support.qsa &&
  661. !compilerCache[ selector + " " ] &&
  662. (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
  663. if ( nodeType !== 1 ) {
  664. newContext = context;
  665. newSelector = selector;
  666. // qSA looks outside Element context, which is not what we want
  667. // Thanks to Andrew Dupont for this workaround technique
  668. // Support: IE <=8
  669. // Exclude object elements
  670. } else if ( context.nodeName.toLowerCase() !== "object" ) {
  671. // Capture the context ID, setting it first if necessary
  672. if ( (nid = context.getAttribute( "id" )) ) {
  673. nid = nid.replace( rcssescape, fcssescape );
  674. } else {
  675. context.setAttribute( "id", (nid = expando) );
  676. }
  677. // Prefix every selector in the list
  678. groups = tokenize( selector );
  679. i = groups.length;
  680. while ( i-- ) {
  681. groups[i] = "#" + nid + " " + toSelector( groups[i] );
  682. }
  683. newSelector = groups.join( "," );
  684. // Expand context for sibling selectors
  685. newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
  686. context;
  687. }
  688. if ( newSelector ) {
  689. try {
  690. push.apply( results,
  691. newContext.querySelectorAll( newSelector )
  692. );
  693. return results;
  694. } catch ( qsaError ) {
  695. } finally {
  696. if ( nid === expando ) {
  697. context.removeAttribute( "id" );
  698. }
  699. }
  700. }
  701. }
  702. }
  703. }
  704. // All others
  705. return select( selector.replace( rtrim, "$1" ), context, results, seed );
  706. }
  707. /**
  708. * Create key-value caches of limited size
  709. * @returns {function(string, object)} Returns the Object data after storing it on itself with
  710. * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
  711. * deleting the oldest entry
  712. */
  713. function createCache() {
  714. var keys = [];
  715. function cache( key, value ) {
  716. // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
  717. if ( keys.push( key + " " ) > Expr.cacheLength ) {
  718. // Only keep the most recent entries
  719. delete cache[ keys.shift() ];
  720. }
  721. return (cache[ key + " " ] = value);
  722. }
  723. return cache;
  724. }
  725. /**
  726. * Mark a function for special use by Sizzle
  727. * @param {Function} fn The function to mark
  728. */
  729. function markFunction( fn ) {
  730. fn[ expando ] = true;
  731. return fn;
  732. }
  733. /**
  734. * Support testing using an element
  735. * @param {Function} fn Passed the created element and returns a boolean result
  736. */
  737. function assert( fn ) {
  738. var el = document.createElement("fieldset");
  739. try {
  740. return !!fn( el );
  741. } catch (e) {
  742. return false;
  743. } finally {
  744. // Remove from its parent by default
  745. if ( el.parentNode ) {
  746. el.parentNode.removeChild( el );
  747. }
  748. // release memory in IE
  749. el = null;
  750. }
  751. }
  752. /**
  753. * Adds the same handler for all of the specified attrs
  754. * @param {String} attrs Pipe-separated list of attributes
  755. * @param {Function} handler The method that will be applied
  756. */
  757. function addHandle( attrs, handler ) {
  758. var arr = attrs.split("|"),
  759. i = arr.length;
  760. while ( i-- ) {
  761. Expr.attrHandle[ arr[i] ] = handler;
  762. }
  763. }
  764. /**
  765. * Checks document order of two siblings
  766. * @param {Element} a
  767. * @param {Element} b
  768. * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
  769. */
  770. function siblingCheck( a, b ) {
  771. var cur = b && a,
  772. diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
  773. a.sourceIndex - b.sourceIndex;
  774. // Use IE sourceIndex if available on both nodes
  775. if ( diff ) {
  776. return diff;
  777. }
  778. // Check if b follows a
  779. if ( cur ) {
  780. while ( (cur = cur.nextSibling) ) {
  781. if ( cur === b ) {
  782. return -1;
  783. }
  784. }
  785. }
  786. return a ? 1 : -1;
  787. }
  788. /**
  789. * Returns a function to use in pseudos for input types
  790. * @param {String} type
  791. */
  792. function createInputPseudo( type ) {
  793. return function( elem ) {
  794. var name = elem.nodeName.toLowerCase();
  795. return name === "input" && elem.type === type;
  796. };
  797. }
  798. /**
  799. * Returns a function to use in pseudos for buttons
  800. * @param {String} type
  801. */
  802. function createButtonPseudo( type ) {
  803. return function( elem ) {
  804. var name = elem.nodeName.toLowerCase();
  805. return (name === "input" || name === "button") && elem.type === type;
  806. };
  807. }
  808. /**
  809. * Returns a function to use in pseudos for :enabled/:disabled
  810. * @param {Boolean} disabled true for :disabled; false for :enabled
  811. */
  812. function createDisabledPseudo( disabled ) {
  813. // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
  814. return function( elem ) {
  815. // Only certain elements can match :enabled or :disabled
  816. // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
  817. // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
  818. if ( "form" in elem ) {
  819. // Check for inherited disabledness on relevant non-disabled elements:
  820. // * listed form-associated elements in a disabled fieldset
  821. // https://html.spec.whatwg.org/multipage/forms.html#category-listed
  822. // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
  823. // * option elements in a disabled optgroup
  824. // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
  825. // All such elements have a "form" property.
  826. if ( elem.parentNode && elem.disabled === false ) {
  827. // Option elements defer to a parent optgroup if present
  828. if ( "label" in elem ) {
  829. if ( "label" in elem.parentNode ) {
  830. return elem.parentNode.disabled === disabled;
  831. } else {
  832. return elem.disabled === disabled;
  833. }
  834. }
  835. // Support: IE 6 - 11
  836. // Use the isDisabled shortcut property to check for disabled fieldset ancestors
  837. return elem.isDisabled === disabled ||
  838. // Where there is no isDisabled, check manually
  839. /* jshint -W018 */
  840. elem.isDisabled !== !disabled &&
  841. disabledAncestor( elem ) === disabled;
  842. }
  843. return elem.disabled === disabled;
  844. // Try to winnow out elements that can't be disabled before trusting the disabled property.
  845. // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
  846. // even exist on them, let alone have a boolean value.
  847. } else if ( "label" in elem ) {
  848. return elem.disabled === disabled;
  849. }
  850. // Remaining elements are neither :enabled nor :disabled
  851. return false;
  852. };
  853. }
  854. /**
  855. * Returns a function to use in pseudos for positionals
  856. * @param {Function} fn
  857. */
  858. function createPositionalPseudo( fn ) {
  859. return markFunction(function( argument ) {
  860. argument = +argument;
  861. return markFunction(function( seed, matches ) {
  862. var j,
  863. matchIndexes = fn( [], seed.length, argument ),
  864. i = matchIndexes.length;
  865. // Match elements found at the specified indexes
  866. while ( i-- ) {
  867. if ( seed[ (j = matchIndexes[i]) ] ) {
  868. seed[j] = !(matches[j] = seed[j]);
  869. }
  870. }
  871. });
  872. });
  873. }
  874. /**
  875. * Checks a node for validity as a Sizzle context
  876. * @param {Element|Object=} context
  877. * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
  878. */
  879. function testContext( context ) {
  880. return context && typeof context.getElementsByTagName !== "undefined" && context;
  881. }
  882. // Expose support vars for convenience
  883. support = Sizzle.support = {};
  884. /**
  885. * Detects XML nodes
  886. * @param {Element|Object} elem An element or a document
  887. * @returns {Boolean} True iff elem is a non-HTML XML node
  888. */
  889. isXML = Sizzle.isXML = function( elem ) {
  890. // documentElement is verified for cases where it doesn't yet exist
  891. // (such as loading iframes in IE - #4833)
  892. var documentElement = elem && (elem.ownerDocument || elem).documentElement;
  893. return documentElement ? documentElement.nodeName !== "HTML" : false;
  894. };
  895. /**
  896. * Sets document-related variables once based on the current document
  897. * @param {Element|Object} [doc] An element or document object to use to set the document
  898. * @returns {Object} Returns the current document
  899. */
  900. setDocument = Sizzle.setDocument = function( node ) {
  901. var hasCompare, subWindow,
  902. doc = node ? node.ownerDocument || node : preferredDoc;
  903. // Return early if doc is invalid or already selected
  904. if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
  905. return document;
  906. }
  907. // Update global variables
  908. document = doc;
  909. docElem = document.documentElement;
  910. documentIsHTML = !isXML( document );
  911. // Support: IE 9-11, Edge
  912. // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
  913. if ( preferredDoc !== document &&
  914. (subWindow = document.defaultView) && subWindow.top !== subWindow ) {
  915. // Support: IE 11, Edge
  916. if ( subWindow.addEventListener ) {
  917. subWindow.addEventListener( "unload", unloadHandler, false );
  918. // Support: IE 9 - 10 only
  919. } else if ( subWindow.attachEvent ) {
  920. subWindow.attachEvent( "onunload", unloadHandler );
  921. }
  922. }
  923. /* Attributes
  924. ---------------------------------------------------------------------- */
  925. // Support: IE<8
  926. // Verify that getAttribute really returns attributes and not properties
  927. // (excepting IE8 booleans)
  928. support.attributes = assert(function( el ) {
  929. el.className = "i";
  930. return !el.getAttribute("className");
  931. });
  932. /* getElement(s)By*
  933. ---------------------------------------------------------------------- */
  934. // Check if getElementsByTagName("*") returns only elements
  935. support.getElementsByTagName = assert(function( el ) {
  936. el.appendChild( document.createComment("") );
  937. return !el.getElementsByTagName("*").length;
  938. });
  939. // Support: IE<9
  940. support.getElementsByClassName = rnative.test( document.getElementsByClassName );
  941. // Support: IE<10
  942. // Check if getElementById returns elements by name
  943. // The broken getElementById methods don't pick up programmatically-set names,
  944. // so use a roundabout getElementsByName test
  945. support.getById = assert(function( el ) {
  946. docElem.appendChild( el ).id = expando;
  947. return !document.getElementsByName || !document.getElementsByName( expando ).length;
  948. });
  949. // ID filter and find
  950. if ( support.getById ) {
  951. Expr.filter["ID"] = function( id ) {
  952. var attrId = id.replace( runescape, funescape );
  953. return function( elem ) {
  954. return elem.getAttribute("id") === attrId;
  955. };
  956. };
  957. Expr.find["ID"] = function( id, context ) {
  958. if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
  959. var elem = context.getElementById( id );
  960. return elem ? [ elem ] : [];
  961. }
  962. };
  963. } else {
  964. Expr.filter["ID"] = function( id ) {
  965. var attrId = id.replace( runescape, funescape );
  966. return function( elem ) {
  967. var node = typeof elem.getAttributeNode !== "undefined" &&
  968. elem.getAttributeNode("id");
  969. return node && node.value === attrId;
  970. };
  971. };
  972. // Support: IE 6 - 7 only
  973. // getElementById is not reliable as a find shortcut
  974. Expr.find["ID"] = function( id, context ) {
  975. if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
  976. var node, i, elems,
  977. elem = context.getElementById( id );
  978. if ( elem ) {
  979. // Verify the id attribute
  980. node = elem.getAttributeNode("id");
  981. if ( node && node.value === id ) {
  982. return [ elem ];
  983. }
  984. // Fall back on getElementsByName
  985. elems = context.getElementsByName( id );
  986. i = 0;
  987. while ( (elem = elems[i++]) ) {
  988. node = elem.getAttributeNode("id");
  989. if ( node && node.value === id ) {
  990. return [ elem ];
  991. }
  992. }
  993. }
  994. return [];
  995. }
  996. };
  997. }
  998. // Tag
  999. Expr.find["TAG"] = support.getElementsByTagName ?
  1000. function( tag, context ) {
  1001. if ( typeof context.getElementsByTagName !== "undefined" ) {
  1002. return context.getElementsByTagName( tag );
  1003. // DocumentFragment nodes don't have gEBTN
  1004. } else if ( support.qsa ) {
  1005. return context.querySelectorAll( tag );
  1006. }
  1007. } :
  1008. function( tag, context ) {
  1009. var elem,
  1010. tmp = [],
  1011. i = 0,
  1012. // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
  1013. results = context.getElementsByTagName( tag );
  1014. // Filter out possible comments
  1015. if ( tag === "*" ) {
  1016. while ( (elem = results[i++]) ) {
  1017. if ( elem.nodeType === 1 ) {
  1018. tmp.push( elem );
  1019. }
  1020. }
  1021. return tmp;
  1022. }
  1023. return results;
  1024. };
  1025. // Class
  1026. Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
  1027. if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
  1028. return context.getElementsByClassName( className );
  1029. }
  1030. };
  1031. /* QSA/matchesSelector
  1032. ---------------------------------------------------------------------- */
  1033. // QSA and matchesSelector support
  1034. // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
  1035. rbuggyMatches = [];
  1036. // qSa(:focus) reports false when true (Chrome 21)
  1037. // We allow this because of a bug in IE8/9 that throws an error
  1038. // whenever `document.activeElement` is accessed on an iframe
  1039. // So, we allow :focus to pass through QSA all the time to avoid the IE error
  1040. // See https://bugs.jquery.com/ticket/13378
  1041. rbuggyQSA = [];
  1042. if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
  1043. // Build QSA regex
  1044. // Regex strategy adopted from Diego Perini
  1045. assert(function( el ) {
  1046. // Select is set to empty string on purpose
  1047. // This is to test IE's treatment of not explicitly
  1048. // setting a boolean content attribute,
  1049. // since its presence should be enough
  1050. // https://bugs.jquery.com/ticket/12359
  1051. docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
  1052. "<select id='" + expando + "-\r\\' msallowcapture=''>" +
  1053. "<option selected=''></option></select>";
  1054. // Support: IE8, Opera 11-12.16
  1055. // Nothing should be selected when empty strings follow ^= or $= or *=
  1056. // The test attribute must be unknown in Opera but "safe" for WinRT
  1057. // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
  1058. if ( el.querySelectorAll("[msallowcapture^='']").length ) {
  1059. rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
  1060. }
  1061. // Support: IE8
  1062. // Boolean attributes and "value" are not treated correctly
  1063. if ( !el.querySelectorAll("[selected]").length ) {
  1064. rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
  1065. }
  1066. // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
  1067. if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
  1068. rbuggyQSA.push("~=");
  1069. }
  1070. // Webkit/Opera - :checked should return selected option elements
  1071. // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
  1072. // IE8 throws error here and will not see later tests
  1073. if ( !el.querySelectorAll(":checked").length ) {
  1074. rbuggyQSA.push(":checked");
  1075. }
  1076. // Support: Safari 8+, iOS 8+
  1077. // https://bugs.webkit.org/show_bug.cgi?id=136851
  1078. // In-page `selector#id sibling-combinator selector` fails
  1079. if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
  1080. rbuggyQSA.push(".#.+[+~]");
  1081. }
  1082. });
  1083. assert(function( el ) {
  1084. el.innerHTML = "<a href='' disabled='disabled'></a>" +
  1085. "<select disabled='disabled'><option/></select>";
  1086. // Support: Windows 8 Native Apps
  1087. // The type and name attributes are restricted during .innerHTML assignment
  1088. var input = document.createElement("input");
  1089. input.setAttribute( "type", "hidden" );
  1090. el.appendChild( input ).setAttribute( "name", "D" );
  1091. // Support: IE8
  1092. // Enforce case-sensitivity of name attribute
  1093. if ( el.querySelectorAll("[name=d]").length ) {
  1094. rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
  1095. }
  1096. // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
  1097. // IE8 throws error here and will not see later tests
  1098. if ( el.querySelectorAll(":enabled").length !== 2 ) {
  1099. rbuggyQSA.push( ":enabled", ":disabled" );
  1100. }
  1101. // Support: IE9-11+
  1102. // IE's :disabled selector does not pick up the children of disabled fieldsets
  1103. docElem.appendChild( el ).disabled = true;
  1104. if ( el.querySelectorAll(":disabled").length !== 2 ) {
  1105. rbuggyQSA.push( ":enabled", ":disabled" );
  1106. }
  1107. // Opera 10-11 does not throw on post-comma invalid pseudos
  1108. el.querySelectorAll("*,:x");
  1109. rbuggyQSA.push(",.*:");
  1110. });
  1111. }
  1112. if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
  1113. docElem.webkitMatchesSelector ||
  1114. docElem.mozMatchesSelector ||
  1115. docElem.oMatchesSelector ||
  1116. docElem.msMatchesSelector) )) ) {
  1117. assert(function( el ) {
  1118. // Check to see if it's possible to do matchesSelector
  1119. // on a disconnected node (IE 9)
  1120. support.disconnectedMatch = matches.call( el, "*" );
  1121. // This should fail with an exception
  1122. // Gecko does not error, returns false instead
  1123. matches.call( el, "[s!='']:x" );
  1124. rbuggyMatches.push( "!=", pseudos );
  1125. });
  1126. }
  1127. rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
  1128. rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
  1129. /* Contains
  1130. ---------------------------------------------------------------------- */
  1131. hasCompare = rnative.test( docElem.compareDocumentPosition );
  1132. // Element contains another
  1133. // Purposefully self-exclusive
  1134. // As in, an element does not contain itself
  1135. contains = hasCompare || rnative.test( docElem.contains ) ?
  1136. function( a, b ) {
  1137. var adown = a.nodeType === 9 ? a.documentElement : a,
  1138. bup = b && b.parentNode;
  1139. return a === bup || !!( bup && bup.nodeType === 1 && (
  1140. adown.contains ?
  1141. adown.contains( bup ) :
  1142. a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
  1143. ));
  1144. } :
  1145. function( a, b ) {
  1146. if ( b ) {
  1147. while ( (b = b.parentNode) ) {
  1148. if ( b === a ) {
  1149. return true;
  1150. }
  1151. }
  1152. }
  1153. return false;
  1154. };
  1155. /* Sorting
  1156. ---------------------------------------------------------------------- */
  1157. // Document order sorting
  1158. sortOrder = hasCompare ?
  1159. function( a, b ) {
  1160. // Flag for duplicate removal
  1161. if ( a === b ) {
  1162. hasDuplicate = true;
  1163. return 0;
  1164. }
  1165. // Sort on method existence if only one input has compareDocumentPosition
  1166. var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
  1167. if ( compare ) {
  1168. return compare;
  1169. }
  1170. // Calculate position if both inputs belong to the same document
  1171. compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
  1172. a.compareDocumentPosition( b ) :
  1173. // Otherwise we know they are disconnected
  1174. 1;
  1175. // Disconnected nodes
  1176. if ( compare & 1 ||
  1177. (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
  1178. // Choose the first element that is related to our preferred document
  1179. if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
  1180. return -1;
  1181. }
  1182. if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
  1183. return 1;
  1184. }
  1185. // Maintain original order
  1186. return sortInput ?
  1187. ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
  1188. 0;
  1189. }
  1190. return compare & 4 ? -1 : 1;
  1191. } :
  1192. function( a, b ) {
  1193. // Exit early if the nodes are identical
  1194. if ( a === b ) {
  1195. hasDuplicate = true;
  1196. return 0;
  1197. }
  1198. var cur,
  1199. i = 0,
  1200. aup = a.parentNode,
  1201. bup = b.parentNode,
  1202. ap = [ a ],
  1203. bp = [ b ];
  1204. // Parentless nodes are either documents or disconnected
  1205. if ( !aup || !bup ) {
  1206. return a === document ? -1 :
  1207. b === document ? 1 :
  1208. aup ? -1 :
  1209. bup ? 1 :
  1210. sortInput ?
  1211. ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
  1212. 0;
  1213. // If the nodes are siblings, we can do a quick check
  1214. } else if ( aup === bup ) {
  1215. return siblingCheck( a, b );
  1216. }
  1217. // Otherwise we need full lists of their ancestors for comparison
  1218. cur = a;
  1219. while ( (cur = cur.parentNode) ) {
  1220. ap.unshift( cur );
  1221. }
  1222. cur = b;
  1223. while ( (cur = cur.parentNode) ) {
  1224. bp.unshift( cur );
  1225. }
  1226. // Walk down the tree looking for a discrepancy
  1227. while ( ap[i] === bp[i] ) {
  1228. i++;
  1229. }
  1230. return i ?
  1231. // Do a sibling check if the nodes have a common ancestor
  1232. siblingCheck( ap[i], bp[i] ) :
  1233. // Otherwise nodes in our document sort first
  1234. ap[i] === preferredDoc ? -1 :
  1235. bp[i] === preferredDoc ? 1 :
  1236. 0;
  1237. };
  1238. return document;
  1239. };
  1240. Sizzle.matches = function( expr, elements ) {
  1241. return Sizzle( expr, null, null, elements );
  1242. };
  1243. Sizzle.matchesSelector = function( elem, expr ) {
  1244. // Set document vars if needed
  1245. if ( ( elem.ownerDocument || elem ) !== document ) {
  1246. setDocument( elem );
  1247. }
  1248. // Make sure that attribute selectors are quoted
  1249. expr = expr.replace( rattributeQuotes, "='$1']" );
  1250. if ( support.matchesSelector && documentIsHTML &&
  1251. !compilerCache[ expr + " " ] &&
  1252. ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
  1253. ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
  1254. try {
  1255. var ret = matches.call( elem, expr );
  1256. // IE 9's matchesSelector returns false on disconnected nodes
  1257. if ( ret || support.disconnectedMatch ||
  1258. // As well, disconnected nodes are said to be in a document
  1259. // fragment in IE 9
  1260. elem.document && elem.document.nodeType !== 11 ) {
  1261. return ret;
  1262. }
  1263. } catch (e) {}
  1264. }
  1265. return Sizzle( expr, document, null, [ elem ] ).length > 0;
  1266. };
  1267. Sizzle.contains = function( context, elem ) {
  1268. // Set document vars if needed
  1269. if ( ( context.ownerDocument || context ) !== document ) {
  1270. setDocument( context );
  1271. }
  1272. return contains( context, elem );
  1273. };
  1274. Sizzle.attr = function( elem, name ) {
  1275. // Set document vars if needed
  1276. if ( ( elem.ownerDocument || elem ) !== document ) {
  1277. setDocument( elem );
  1278. }
  1279. var fn = Expr.attrHandle[ name.toLowerCase() ],
  1280. // Don't get fooled by Object.prototype properties (jQuery #13807)
  1281. val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
  1282. fn( elem, name, !documentIsHTML ) :
  1283. undefined;
  1284. return val !== undefined ?
  1285. val :
  1286. support.attributes || !documentIsHTML ?
  1287. elem.getAttribute( name ) :
  1288. (val = elem.getAttributeNode(name)) && val.specified ?
  1289. val.value :
  1290. null;
  1291. };
  1292. Sizzle.escape = function( sel ) {
  1293. return (sel + "").replace( rcssescape, fcssescape );
  1294. };
  1295. Sizzle.error = function( msg ) {
  1296. throw new Error( "Syntax error, unrecognized expression: " + msg );
  1297. };
  1298. /**
  1299. * Document sorting and removing duplicates
  1300. * @param {ArrayLike} results
  1301. */
  1302. Sizzle.uniqueSort = function( results ) {
  1303. var elem,
  1304. duplicates = [],
  1305. j = 0,
  1306. i = 0;
  1307. // Unless we *know* we can detect duplicates, assume their presence
  1308. hasDuplicate = !support.detectDuplicates;
  1309. sortInput = !support.sortStable && results.slice( 0 );
  1310. results.sort( sortOrder );
  1311. if ( hasDuplicate ) {
  1312. while ( (elem = results[i++]) ) {
  1313. if ( elem === results[ i ] ) {
  1314. j = duplicates.push( i );
  1315. }
  1316. }
  1317. while ( j-- ) {
  1318. results.splice( duplicates[ j ], 1 );
  1319. }
  1320. }
  1321. // Clear input after sorting to release objects
  1322. // See https://github.com/jquery/sizzle/pull/225
  1323. sortInput = null;
  1324. return results;
  1325. };
  1326. /**
  1327. * Utility function for retrieving the text value of an array of DOM nodes
  1328. * @param {Array|Element} elem
  1329. */
  1330. getText = Sizzle.getText = function( elem ) {
  1331. var node,
  1332. ret = "",
  1333. i = 0,
  1334. nodeType = elem.nodeType;
  1335. if ( !nodeType ) {
  1336. // If no nodeType, this is expected to be an array
  1337. while ( (node = elem[i++]) ) {
  1338. // Do not traverse comment nodes
  1339. ret += getText( node );
  1340. }
  1341. } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
  1342. // Use textContent for elements
  1343. // innerText usage removed for consistency of new lines (jQuery #11153)
  1344. if ( typeof elem.textContent === "string" ) {
  1345. return elem.textContent;
  1346. } else {
  1347. // Traverse its children
  1348. for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
  1349. ret += getText( elem );
  1350. }
  1351. }
  1352. } else if ( nodeType === 3 || nodeType === 4 ) {
  1353. return elem.nodeValue;
  1354. }
  1355. // Do not include comment or processing instruction nodes
  1356. return ret;
  1357. };
  1358. Expr = Sizzle.selectors = {
  1359. // Can be adjusted by the user
  1360. cacheLength: 50,
  1361. createPseudo: markFunction,
  1362. match: matchExpr,
  1363. attrHandle: {},
  1364. find: {},
  1365. relative: {
  1366. ">": { dir: "parentNode", first: true },
  1367. " ": { dir: "parentNode" },
  1368. "+": { dir: "previousSibling", first: true },
  1369. "~": { dir: "previousSibling" }
  1370. },
  1371. preFilter: {
  1372. "ATTR": function( match ) {
  1373. match[1] = match[1].replace( runescape, funescape );
  1374. // Move the given value to match[3] whether quoted or unquoted
  1375. match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
  1376. if ( match[2] === "~=" ) {
  1377. match[3] = " " + match[3] + " ";
  1378. }
  1379. return match.slice( 0, 4 );
  1380. },
  1381. "CHILD": function( match ) {
  1382. /* matches from matchExpr["CHILD"]
  1383. 1 type (only|nth|...)
  1384. 2 what (child|of-type)
  1385. 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
  1386. 4 xn-component of xn+y argument ([+-]?\d*n|)
  1387. 5 sign of xn-component
  1388. 6 x of xn-component
  1389. 7 sign of y-component
  1390. 8 y of y-component
  1391. */
  1392. match[1] = match[1].toLowerCase();
  1393. if ( match[1].slice( 0, 3 ) === "nth" ) {
  1394. // nth-* requires argument
  1395. if ( !match[3] ) {
  1396. Sizzle.error( match[0] );
  1397. }
  1398. // numeric x and y parameters for Expr.filter.CHILD
  1399. // remember that false/true cast respectively to 0/1
  1400. match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
  1401. match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
  1402. // other types prohibit arguments
  1403. } else if ( match[3] ) {
  1404. Sizzle.error( match[0] );
  1405. }
  1406. return match;
  1407. },
  1408. "PSEUDO": function( match ) {
  1409. var excess,
  1410. unquoted = !match[6] && match[2];
  1411. if ( matchExpr["CHILD"].test( match[0] ) ) {
  1412. return null;
  1413. }
  1414. // Accept quoted arguments as-is
  1415. if ( match[3] ) {
  1416. match[2] = match[4] || match[5] || "";
  1417. // Strip excess characters from unquoted arguments
  1418. } else if ( unquoted && rpseudo.test( unquoted ) &&
  1419. // Get excess from tokenize (recursively)
  1420. (excess = tokenize( unquoted, true )) &&
  1421. // advance to the next closing parenthesis
  1422. (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
  1423. // excess is a negative index
  1424. match[0] = match[0].slice( 0, excess );
  1425. match[2] = unquoted.slice( 0, excess );
  1426. }
  1427. // Return only captures needed by the pseudo filter method (type and argument)
  1428. return match.slice( 0, 3 );
  1429. }
  1430. },
  1431. filter: {
  1432. "TAG": function( nodeNameSelector ) {
  1433. var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
  1434. return nodeNameSelector === "*" ?
  1435. function() { return true; } :
  1436. function( elem ) {
  1437. return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
  1438. };
  1439. },
  1440. "CLASS": function( className ) {
  1441. var pattern = classCache[ className + " " ];
  1442. return pattern ||
  1443. (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
  1444. classCache( className, function( elem ) {
  1445. return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
  1446. });
  1447. },
  1448. "ATTR": function( name, operator, check ) {
  1449. return function( elem ) {
  1450. var result = Sizzle.attr( elem, name );
  1451. if ( result == null ) {
  1452. return operator === "!=";
  1453. }
  1454. if ( !operator ) {
  1455. return true;
  1456. }
  1457. result += "";
  1458. return operator === "=" ? result === check :
  1459. operator === "!=" ? result !== check :
  1460. operator === "^=" ? check && result.indexOf( check ) === 0 :
  1461. operator === "*=" ? check && result.indexOf( check ) > -1 :
  1462. operator === "$=" ? check && result.slice( -check.length ) === check :
  1463. operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
  1464. operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
  1465. false;
  1466. };
  1467. },
  1468. "CHILD": function( type, what, argument, first, last ) {
  1469. var simple = type.slice( 0, 3 ) !== "nth",
  1470. forward = type.slice( -4 ) !== "last",
  1471. ofType = what === "of-type";
  1472. return first === 1 && last === 0 ?
  1473. // Shortcut for :nth-*(n)
  1474. function( elem ) {
  1475. return !!elem.parentNode;
  1476. } :
  1477. function( elem, context, xml ) {
  1478. var cache, uniqueCache, outerCache, node, nodeIndex, start,
  1479. dir = simple !== forward ? "nextSibling" : "previousSibling",
  1480. parent = elem.parentNode,
  1481. name = ofType && elem.nodeName.toLowerCase(),
  1482. useCache = !xml && !ofType,
  1483. diff = false;
  1484. if ( parent ) {
  1485. // :(first|last|only)-(child|of-type)
  1486. if ( simple ) {
  1487. while ( dir ) {
  1488. node = elem;
  1489. while ( (node = node[ dir ]) ) {
  1490. if ( ofType ?
  1491. node.nodeName.toLowerCase() === name :
  1492. node.nodeType === 1 ) {
  1493. return false;
  1494. }
  1495. }
  1496. // Reverse direction for :only-* (if we haven't yet done so)
  1497. start = dir = type === "only" && !start && "nextSibling";
  1498. }
  1499. return true;
  1500. }
  1501. start = [ forward ? parent.firstChild : parent.lastChild ];
  1502. // non-xml :nth-child(...) stores cache data on `parent`
  1503. if ( forward && useCache ) {
  1504. // Seek `elem` from a previously-cached index
  1505. // ...in a gzip-friendly way
  1506. node = parent;
  1507. outerCache = node[ expando ] || (node[ expando ] = {});
  1508. // Support: IE <9 only
  1509. // Defend against cloned attroperties (jQuery gh-1709)
  1510. uniqueCache = outerCache[ node.uniqueID ] ||
  1511. (outerCache[ node.uniqueID ] = {});
  1512. cache = uniqueCache[ type ] || [];
  1513. nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
  1514. diff = nodeIndex && cache[ 2 ];
  1515. node = nodeIndex && parent.childNodes[ nodeIndex ];
  1516. while ( (node = ++nodeIndex && node && node[ dir ] ||
  1517. // Fallback to seeking `elem` from the start
  1518. (diff = nodeIndex = 0) || start.pop()) ) {
  1519. // When found, cache indexes on `parent` and break
  1520. if ( node.nodeType === 1 && ++diff && node === elem ) {
  1521. uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
  1522. break;
  1523. }
  1524. }
  1525. } else {
  1526. // Use previously-cached element index if available
  1527. if ( useCache ) {
  1528. // ...in a gzip-friendly way
  1529. node = elem;
  1530. outerCache = node[ expando ] || (node[ expando ] = {});
  1531. // Support: IE <9 only
  1532. // Defend against cloned attroperties (jQuery gh-1709)
  1533. uniqueCache = outerCache[ node.uniqueID ] ||
  1534. (outerCache[ node.uniqueID ] = {});
  1535. cache = uniqueCache[ type ] || [];
  1536. nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
  1537. diff = nodeIndex;
  1538. }
  1539. // xml :nth-child(...)
  1540. // or :nth-last-child(...) or :nth(-last)?-of-type(...)
  1541. if ( diff === false ) {
  1542. // Use the same loop as above to seek `elem` from the start
  1543. while ( (node = ++nodeIndex && node && node[ dir ] ||
  1544. (diff = nodeIndex = 0) || start.pop()) ) {
  1545. if ( ( ofType ?
  1546. node.nodeName.toLowerCase() === name :
  1547. node.nodeType === 1 ) &&
  1548. ++diff ) {
  1549. // Cache the index of each encountered element
  1550. if ( useCache ) {
  1551. outerCache = node[ expando ] || (node[ expando ] = {});
  1552. // Support: IE <9 only
  1553. // Defend against cloned attroperties (jQuery gh-1709)
  1554. uniqueCache = outerCache[ node.uniqueID ] ||
  1555. (outerCache[ node.uniqueID ] = {});
  1556. uniqueCache[ type ] = [ dirruns, diff ];
  1557. }
  1558. if ( node === elem ) {
  1559. break;
  1560. }
  1561. }
  1562. }
  1563. }
  1564. }
  1565. // Incorporate the offset, then check against cycle size
  1566. diff -= last;
  1567. return diff === first || ( diff % first === 0 && diff / first >= 0 );
  1568. }
  1569. };
  1570. },
  1571. "PSEUDO": function( pseudo, argument ) {
  1572. // pseudo-class names are case-insensitive
  1573. // http://www.w3.org/TR/selectors/#pseudo-classes
  1574. // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
  1575. // Remember that setFilters inherits from pseudos
  1576. var args,
  1577. fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
  1578. Sizzle.error( "unsupported pseudo: " + pseudo );
  1579. // The user may use createPseudo to indicate that
  1580. // arguments are needed to create the filter function
  1581. // just as Sizzle does
  1582. if ( fn[ expando ] ) {
  1583. return fn( argument );
  1584. }
  1585. // But maintain support for old signatures
  1586. if ( fn.length > 1 ) {
  1587. args = [ pseudo, pseudo, "", argument ];
  1588. return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
  1589. markFunction(function( seed, matches ) {
  1590. var idx,
  1591. matched = fn( seed, argument ),
  1592. i = matched.length;
  1593. while ( i-- ) {
  1594. idx = indexOf( seed, matched[i] );
  1595. seed[ idx ] = !( matches[ idx ] = matched[i] );
  1596. }
  1597. }) :
  1598. function( elem ) {
  1599. return fn( elem, 0, args );
  1600. };
  1601. }
  1602. return fn;
  1603. }
  1604. },
  1605. pseudos: {
  1606. // Potentially complex pseudos
  1607. "not": markFunction(function( selector ) {
  1608. // Trim the selector passed to compile
  1609. // to avoid treating leading and trailing
  1610. // spaces as combinators
  1611. var input = [],
  1612. results = [],
  1613. matcher = compile( selector.replace( rtrim, "$1" ) );
  1614. return matcher[ expando ] ?
  1615. markFunction(function( seed, matches, context, xml ) {
  1616. var elem,
  1617. unmatched = matcher( seed, null, xml, [] ),
  1618. i = seed.length;
  1619. // Match elements unmatched by `matcher`
  1620. while ( i-- ) {
  1621. if ( (elem = unmatched[i]) ) {
  1622. seed[i] = !(matches[i] = elem);
  1623. }
  1624. }
  1625. }) :
  1626. function( elem, context, xml ) {
  1627. input[0] = elem;
  1628. matcher( input, null, xml, results );
  1629. // Don't keep the element (issue #299)
  1630. input[0] = null;
  1631. return !results.pop();
  1632. };
  1633. }),
  1634. "has": markFunction(function( selector ) {
  1635. return function( elem ) {
  1636. return Sizzle( selector, elem ).length > 0;
  1637. };
  1638. }),
  1639. "contains": markFunction(function( text ) {
  1640. text = text.replace( runescape, funescape );
  1641. return function( elem ) {
  1642. return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
  1643. };
  1644. }),
  1645. // "Whether an element is represented by a :lang() selector
  1646. // is based solely on the element's language value
  1647. // being equal to the identifier C,
  1648. // or beginning with the identifier C immediately followed by "-".
  1649. // The matching of C against the element's language value is performed case-insensitively.
  1650. // The identifier C does not have to be a valid language name."
  1651. // http://www.w3.org/TR/selectors/#lang-pseudo
  1652. "lang": markFunction( function( lang ) {
  1653. // lang value must be a valid identifier
  1654. if ( !ridentifier.test(lang || "") ) {
  1655. Sizzle.error( "unsupported lang: " + lang );
  1656. }
  1657. lang = lang.replace( runescape, funescape ).toLowerCase();
  1658. return function( elem ) {
  1659. var elemLang;
  1660. do {
  1661. if ( (elemLang = documentIsHTML ?
  1662. elem.lang :
  1663. elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
  1664. elemLang = elemLang.toLowerCase();
  1665. return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
  1666. }
  1667. } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
  1668. return false;
  1669. };
  1670. }),
  1671. // Miscellaneous
  1672. "target": function( elem ) {
  1673. var hash = window.location && window.location.hash;
  1674. return hash && hash.slice( 1 ) === elem.id;
  1675. },
  1676. "root": function( elem ) {
  1677. return elem === docElem;
  1678. },
  1679. "focus": function( elem ) {
  1680. return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
  1681. },
  1682. // Boolean properties
  1683. "enabled": createDisabledPseudo( false ),
  1684. "disabled": createDisabledPseudo( true ),
  1685. "checked": function( elem ) {
  1686. // In CSS3, :checked should return both checked and selected elements
  1687. // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
  1688. var nodeName = elem.nodeName.toLowerCase();
  1689. return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
  1690. },
  1691. "selected": function( elem ) {
  1692. // Accessing this property makes selected-by-default
  1693. // options in Safari work properly
  1694. if ( elem.parentNode ) {
  1695. elem.parentNode.selectedIndex;
  1696. }
  1697. return elem.selected === true;
  1698. },
  1699. // Contents
  1700. "empty": function( elem ) {
  1701. // http://www.w3.org/TR/selectors/#empty-pseudo
  1702. // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
  1703. // but not by others (comment: 8; processing instruction: 7; etc.)
  1704. // nodeType < 6 works because attributes (2) do not appear as children
  1705. for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
  1706. if ( elem.nodeType < 6 ) {
  1707. return false;
  1708. }
  1709. }
  1710. return true;
  1711. },
  1712. "parent": function( elem ) {
  1713. return !Expr.pseudos["empty"]( elem );
  1714. },
  1715. // Element/input types
  1716. "header": function( elem ) {
  1717. return rheader.test( elem.nodeName );
  1718. },
  1719. "input": function( elem ) {
  1720. return rinputs.test( elem.nodeName );
  1721. },
  1722. "button": function( elem ) {
  1723. var name = elem.nodeName.toLowerCase();
  1724. return name === "input" && elem.type === "button" || name === "button";
  1725. },
  1726. "text": function( elem ) {
  1727. var attr;
  1728. return elem.nodeName.toLowerCase() === "input" &&
  1729. elem.type === "text" &&
  1730. // Support: IE<8
  1731. // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
  1732. ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
  1733. },
  1734. // Position-in-collection
  1735. "first": createPositionalPseudo(function() {
  1736. return [ 0 ];
  1737. }),
  1738. "last": createPositionalPseudo(function( matchIndexes, length ) {
  1739. return [ length - 1 ];
  1740. }),
  1741. "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
  1742. return [ argument < 0 ? argument + length : argument ];
  1743. }),
  1744. "even": createPositionalPseudo(function( matchIndexes, length ) {
  1745. var i = 0;
  1746. for ( ; i < length; i += 2 ) {
  1747. matchIndexes.push( i );
  1748. }
  1749. return matchIndexes;
  1750. }),
  1751. "odd": createPositionalPseudo(function( matchIndexes, length ) {
  1752. var i = 1;
  1753. for ( ; i < length; i += 2 ) {
  1754. matchIndexes.push( i );
  1755. }
  1756. return matchIndexes;
  1757. }),
  1758. "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
  1759. var i = argument < 0 ? argument + length : argument;
  1760. for ( ; --i >= 0; ) {
  1761. matchIndexes.push( i );
  1762. }
  1763. return matchIndexes;
  1764. }),
  1765. "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
  1766. var i = argument < 0 ? argument + length : argument;
  1767. for ( ; ++i < length; ) {
  1768. matchIndexes.push( i );
  1769. }
  1770. return matchIndexes;
  1771. })
  1772. }
  1773. };
  1774. Expr.pseudos["nth"] = Expr.pseudos["eq"];
  1775. // Add button/input type pseudos
  1776. for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
  1777. Expr.pseudos[ i ] = createInputPseudo( i );
  1778. }
  1779. for ( i in { submit: true, reset: true } ) {
  1780. Expr.pseudos[ i ] = createButtonPseudo( i );
  1781. }
  1782. // Easy API for creating new setFilters
  1783. function setFilters() {}
  1784. setFilters.prototype = Expr.filters = Expr.pseudos;
  1785. Expr.setFilters = new setFilters();
  1786. tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
  1787. var matched, match, tokens, type,
  1788. soFar, groups, preFilters,
  1789. cached = tokenCache[ selector + " " ];
  1790. if ( cached ) {
  1791. return parseOnly ? 0 : cached.slice( 0 );
  1792. }
  1793. soFar = selector;
  1794. groups = [];
  1795. preFilters = Expr.preFilter;
  1796. while ( soFar ) {
  1797. // Comma and first run
  1798. if ( !matched || (match = rcomma.exec( soFar )) ) {
  1799. if ( match ) {
  1800. // Don't consume trailing commas as valid
  1801. soFar = soFar.slice( match[0].length ) || soFar;
  1802. }
  1803. groups.push( (tokens = []) );
  1804. }
  1805. matched = false;
  1806. // Combinators
  1807. if ( (match = rcombinators.exec( soFar )) ) {
  1808. matched = match.shift();
  1809. tokens.push({
  1810. value: matched,
  1811. // Cast descendant combinators to space
  1812. type: match[0].replace( rtrim, " " )
  1813. });
  1814. soFar = soFar.slice( matched.length );
  1815. }
  1816. // Filters
  1817. for ( type in Expr.filter ) {
  1818. if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
  1819. (match = preFilters[ type ]( match ))) ) {
  1820. matched = match.shift();
  1821. tokens.push({
  1822. value: matched,
  1823. type: type,
  1824. matches: match
  1825. });
  1826. soFar = soFar.slice( matched.length );
  1827. }
  1828. }
  1829. if ( !matched ) {
  1830. break;
  1831. }
  1832. }
  1833. // Return the length of the invalid excess
  1834. // if we're just parsing
  1835. // Otherwise, throw an error or return tokens
  1836. return parseOnly ?
  1837. soFar.length :
  1838. soFar ?
  1839. Sizzle.error( selector ) :
  1840. // Cache the tokens
  1841. tokenCache( selector, groups ).slice( 0 );
  1842. };
  1843. function toSelector( tokens ) {
  1844. var i = 0,
  1845. len = tokens.length,
  1846. selector = "";
  1847. for ( ; i < len; i++ ) {
  1848. selector += tokens[i].value;
  1849. }
  1850. return selector;
  1851. }
  1852. function addCombinator( matcher, combinator, base ) {
  1853. var dir = combinator.dir,
  1854. skip = combinator.next,
  1855. key = skip || dir,
  1856. checkNonElements = base && key === "parentNode",
  1857. doneName = done++;
  1858. return combinator.first ?
  1859. // Check against closest ancestor/preceding element
  1860. function( elem, context, xml ) {
  1861. while ( (elem = elem[ dir ]) ) {
  1862. if ( elem.nodeType === 1 || checkNonElements ) {
  1863. return matcher( elem, context, xml );
  1864. }
  1865. }
  1866. return false;
  1867. } :
  1868. // Check against all ancestor/preceding elements
  1869. function( elem, context, xml ) {
  1870. var oldCache, uniqueCache, outerCache,
  1871. newCache = [ dirruns, doneName ];
  1872. // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
  1873. if ( xml ) {
  1874. while ( (elem = elem[ dir ]) ) {
  1875. if ( elem.nodeType === 1 || checkNonElements ) {
  1876. if ( matcher( elem, context, xml ) ) {
  1877. return true;
  1878. }
  1879. }
  1880. }
  1881. } else {
  1882. while ( (elem = elem[ dir ]) ) {
  1883. if ( elem.nodeType === 1 || checkNonElements ) {
  1884. outerCache = elem[ expando ] || (elem[ expando ] = {});
  1885. // Support: IE <9 only
  1886. // Defend against cloned attroperties (jQuery gh-1709)
  1887. uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
  1888. if ( skip && skip === elem.nodeName.toLowerCase() ) {
  1889. elem = elem[ dir ] || elem;
  1890. } else if ( (oldCache = uniqueCache[ key ]) &&
  1891. oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
  1892. // Assign to newCache so results back-propagate to previous elements
  1893. return (newCache[ 2 ] = oldCache[ 2 ]);
  1894. } else {
  1895. // Reuse newcache so results back-propagate to previous elements
  1896. uniqueCache[ key ] = newCache;
  1897. // A match means we're done; a fail means we have to keep checking
  1898. if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
  1899. return true;
  1900. }
  1901. }
  1902. }
  1903. }
  1904. }
  1905. return false;
  1906. };
  1907. }
  1908. function elementMatcher( matchers ) {
  1909. return matchers.length > 1 ?
  1910. function( elem, context, xml ) {
  1911. var i = matchers.length;
  1912. while ( i-- ) {
  1913. if ( !matchers[i]( elem, context, xml ) ) {
  1914. return false;
  1915. }
  1916. }
  1917. return true;
  1918. } :
  1919. matchers[0];
  1920. }
  1921. function multipleContexts( selector, contexts, results ) {
  1922. var i = 0,
  1923. len = contexts.length;
  1924. for ( ; i < len; i++ ) {
  1925. Sizzle( selector, contexts[i], results );
  1926. }
  1927. return results;
  1928. }
  1929. function condense( unmatched, map, filter, context, xml ) {
  1930. var elem,
  1931. newUnmatched = [],
  1932. i = 0,
  1933. len = unmatched.length,
  1934. mapped = map != null;
  1935. for ( ; i < len; i++ ) {
  1936. if ( (elem = unmatched[i]) ) {
  1937. if ( !filter || filter( elem, context, xml ) ) {
  1938. newUnmatched.push( elem );
  1939. if ( mapped ) {
  1940. map.push( i );
  1941. }
  1942. }
  1943. }
  1944. }
  1945. return newUnmatched;
  1946. }
  1947. function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
  1948. if ( postFilter && !postFilter[ expando ] ) {
  1949. postFilter = setMatcher( postFilter );
  1950. }
  1951. if ( postFinder && !postFinder[ expando ] ) {
  1952. postFinder = setMatcher( postFinder, postSelector );
  1953. }
  1954. return markFunction(function( seed, results, context, xml ) {
  1955. var temp, i, elem,
  1956. preMap = [],
  1957. postMap = [],
  1958. preexisting = results.length,
  1959. // Get initial elements from seed or context
  1960. elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
  1961. // Prefilter to get matcher input, preserving a map for seed-results synchronization
  1962. matcherIn = preFilter && ( seed || !selector ) ?
  1963. condense( elems, preMap, preFilter, context, xml ) :
  1964. elems,
  1965. matcherOut = matcher ?
  1966. // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
  1967. postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
  1968. // ...intermediate processing is necessary
  1969. [] :
  1970. // ...otherwise use results directly
  1971. results :
  1972. matcherIn;
  1973. // Find primary matches
  1974. if ( matcher ) {
  1975. matcher( matcherIn, matcherOut, context, xml );
  1976. }
  1977. // Apply postFilter
  1978. if ( postFilter ) {
  1979. temp = condense( matcherOut, postMap );
  1980. postFilter( temp, [], context, xml );
  1981. // Un-match failing elements by moving them back to matcherIn
  1982. i = temp.length;
  1983. while ( i-- ) {
  1984. if ( (elem = temp[i]) ) {
  1985. matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
  1986. }
  1987. }
  1988. }
  1989. if ( seed ) {
  1990. if ( postFinder || preFilter ) {
  1991. if ( postFinder ) {
  1992. // Get the final matcherOut by condensing this intermediate into postFinder contexts
  1993. temp = [];
  1994. i = matcherOut.length;
  1995. while ( i-- ) {
  1996. if ( (elem = matcherOut[i]) ) {
  1997. // Restore matcherIn since elem is not yet a final match
  1998. temp.push( (matcherIn[i] = elem) );
  1999. }
  2000. }
  2001. postFinder( null, (matcherOut = []), temp, xml );
  2002. }
  2003. // Move matched elements from seed to results to keep them synchronized
  2004. i = matcherOut.length;
  2005. while ( i-- ) {
  2006. if ( (elem = matcherOut[i]) &&
  2007. (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
  2008. seed[temp] = !(results[temp] = elem);
  2009. }
  2010. }
  2011. }
  2012. // Add elements to results, through postFinder if defined
  2013. } else {
  2014. matcherOut = condense(
  2015. matcherOut === results ?
  2016. matcherOut.splice( preexisting, matcherOut.length ) :
  2017. matcherOut
  2018. );
  2019. if ( postFinder ) {
  2020. postFinder( null, results, matcherOut, xml );
  2021. } else {
  2022. push.apply( results, matcherOut );
  2023. }
  2024. }
  2025. });
  2026. }
  2027. function matcherFromTokens( tokens ) {
  2028. var checkContext, matcher, j,
  2029. len = tokens.length,
  2030. leadingRelative = Expr.relative[ tokens[0].type ],
  2031. implicitRelative = leadingRelative || Expr.relative[" "],
  2032. i = leadingRelative ? 1 : 0,
  2033. // The foundational matcher ensures that elements are reachable from top-level context(s)
  2034. matchContext = addCombinator( function( elem ) {
  2035. return elem === checkContext;
  2036. }, implicitRelative, true ),
  2037. matchAnyContext = addCombinator( function( elem ) {
  2038. return indexOf( checkContext, elem ) > -1;
  2039. }, implicitRelative, true ),
  2040. matchers = [ function( elem, context, xml ) {
  2041. var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
  2042. (checkContext = context).nodeType ?
  2043. matchContext( elem, context, xml ) :
  2044. matchAnyContext( elem, context, xml ) );
  2045. // Avoid hanging onto element (issue #299)
  2046. checkContext = null;
  2047. return ret;
  2048. } ];
  2049. for ( ; i < len; i++ ) {
  2050. if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
  2051. matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
  2052. } else {
  2053. matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
  2054. // Return special upon seeing a positional matcher
  2055. if ( matcher[ expando ] ) {
  2056. // Find the next relative operator (if any) for proper handling
  2057. j = ++i;
  2058. for ( ; j < len; j++ ) {
  2059. if ( Expr.relative[ tokens[j].type ] ) {
  2060. break;
  2061. }
  2062. }
  2063. return setMatcher(
  2064. i > 1 && elementMatcher( matchers ),
  2065. i > 1 && toSelector(
  2066. // If the preceding token was a descendant combinator, insert an implicit any-element `*`
  2067. tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
  2068. ).replace( rtrim, "$1" ),
  2069. matcher,
  2070. i < j && matcherFromTokens( tokens.slice( i, j ) ),
  2071. j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
  2072. j < len && toSelector( tokens )
  2073. );
  2074. }
  2075. matchers.push( matcher );
  2076. }
  2077. }
  2078. return elementMatcher( matchers );
  2079. }
  2080. function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
  2081. var bySet = setMatchers.length > 0,
  2082. byElement = elementMatchers.length > 0,
  2083. superMatcher = function( seed, context, xml, results, outermost ) {
  2084. var elem, j, matcher,
  2085. matchedCount = 0,
  2086. i = "0",
  2087. unmatched = seed && [],
  2088. setMatched = [],
  2089. contextBackup = outermostContext,
  2090. // We must always have either seed elements or outermost context
  2091. elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
  2092. // Use integer dirruns iff this is the outermost matcher
  2093. dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
  2094. len = elems.length;
  2095. if ( outermost ) {
  2096. outermostContext = context === document || context || outermost;
  2097. }
  2098. // Add elements passing elementMatchers directly to results
  2099. // Support: IE<9, Safari
  2100. // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
  2101. for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
  2102. if ( byElement && elem ) {
  2103. j = 0;
  2104. if ( !context && elem.ownerDocument !== document ) {
  2105. setDocument( elem );
  2106. xml = !documentIsHTML;
  2107. }
  2108. while ( (matcher = elementMatchers[j++]) ) {
  2109. if ( matcher( elem, context || document, xml) ) {
  2110. results.push( elem );
  2111. break;
  2112. }
  2113. }
  2114. if ( outermost ) {
  2115. dirruns = dirrunsUnique;
  2116. }
  2117. }
  2118. // Track unmatched elements for set filters
  2119. if ( bySet ) {
  2120. // They will have gone through all possible matchers
  2121. if ( (elem = !matcher && elem) ) {
  2122. matchedCount--;
  2123. }
  2124. // Lengthen the array for every element, matched or not
  2125. if ( seed ) {
  2126. unmatched.push( elem );
  2127. }
  2128. }
  2129. }
  2130. // `i` is now the count of elements visited above, and adding it to `matchedCount`
  2131. // makes the latter nonnegative.
  2132. matchedCount += i;
  2133. // Apply set filters to unmatched elements
  2134. // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
  2135. // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
  2136. // no element matchers and no seed.
  2137. // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
  2138. // case, which will result in a "00" `matchedCount` that differs from `i` but is also
  2139. // numerically zero.
  2140. if ( bySet && i !== matchedCount ) {
  2141. j = 0;
  2142. while ( (matcher = setMatchers[j++]) ) {
  2143. matcher( unmatched, setMatched, context, xml );
  2144. }
  2145. if ( seed ) {
  2146. // Reintegrate element matches to eliminate the need for sorting
  2147. if ( matchedCount > 0 ) {
  2148. while ( i-- ) {
  2149. if ( !(unmatched[i] || setMatched[i]) ) {
  2150. setMatched[i] = pop.call( results );
  2151. }
  2152. }
  2153. }
  2154. // Discard index placeholder values to get only actual matches
  2155. setMatched = condense( setMatched );
  2156. }
  2157. // Add matches to results
  2158. push.apply( results, setMatched );
  2159. // Seedless set matches succeeding multiple successful matchers stipulate sorting
  2160. if ( outermost && !seed && setMatched.length > 0 &&
  2161. ( matchedCount + setMatchers.length ) > 1 ) {
  2162. Sizzle.uniqueSort( results );
  2163. }
  2164. }
  2165. // Override manipulation of globals by nested matchers
  2166. if ( outermost ) {
  2167. dirruns = dirrunsUnique;
  2168. outermostContext = contextBackup;
  2169. }
  2170. return unmatched;
  2171. };
  2172. return bySet ?
  2173. markFunction( superMatcher ) :
  2174. superMatcher;
  2175. }
  2176. compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
  2177. var i,
  2178. setMatchers = [],
  2179. elementMatchers = [],
  2180. cached = compilerCache[ selector + " " ];
  2181. if ( !cached ) {
  2182. // Generate a function of recursive functions that can be used to check each element
  2183. if ( !match ) {
  2184. match = tokenize( selector );
  2185. }
  2186. i = match.length;
  2187. while ( i-- ) {
  2188. cached = matcherFromTokens( match[i] );
  2189. if ( cached[ expando ] ) {
  2190. setMatchers.push( cached );
  2191. } else {
  2192. elementMatchers.push( cached );
  2193. }
  2194. }
  2195. // Cache the compiled function
  2196. cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
  2197. // Save selector and tokenization
  2198. cached.selector = selector;
  2199. }
  2200. return cached;
  2201. };
  2202. /**
  2203. * A low-level selection function that works with Sizzle's compiled
  2204. * selector functions
  2205. * @param {String|Function} selector A selector or a pre-compiled
  2206. * selector function built with Sizzle.compile
  2207. * @param {Element} context
  2208. * @param {Array} [results]
  2209. * @param {Array} [seed] A set of elements to match against
  2210. */
  2211. select = Sizzle.select = function( selector, context, results, seed ) {
  2212. var i, tokens, token, type, find,
  2213. compiled = typeof selector === "function" && selector,
  2214. match = !seed && tokenize( (selector = compiled.selector || selector) );
  2215. results = results || [];
  2216. // Try to minimize operations if there is only one selector in the list and no seed
  2217. // (the latter of which guarantees us context)
  2218. if ( match.length === 1 ) {
  2219. // Reduce context if the leading compound selector is an ID
  2220. tokens = match[0] = match[0].slice( 0 );
  2221. if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
  2222. context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
  2223. context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
  2224. if ( !context ) {
  2225. return results;
  2226. // Precompiled matchers will still verify ancestry, so step up a level
  2227. } else if ( compiled ) {
  2228. context = context.parentNode;
  2229. }
  2230. selector = selector.slice( tokens.shift().value.length );
  2231. }
  2232. // Fetch a seed set for right-to-left matching
  2233. i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
  2234. while ( i-- ) {
  2235. token = tokens[i];
  2236. // Abort if we hit a combinator
  2237. if ( Expr.relative[ (type = token.type) ] ) {
  2238. break;
  2239. }
  2240. if ( (find = Expr.find[ type ]) ) {
  2241. // Search, expanding context for leading sibling combinators
  2242. if ( (seed = find(
  2243. token.matches[0].replace( runescape, funescape ),
  2244. rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
  2245. )) ) {
  2246. // If seed is empty or no tokens remain, we can return early
  2247. tokens.splice( i, 1 );
  2248. selector = seed.length && toSelector( tokens );
  2249. if ( !selector ) {
  2250. push.apply( results, seed );
  2251. return results;
  2252. }
  2253. break;
  2254. }
  2255. }
  2256. }
  2257. }
  2258. // Compile and execute a filtering function if one is not provided
  2259. // Provide `match` to avoid retokenization if we modified the selector above
  2260. ( compiled || compile( selector, match ) )(
  2261. seed,
  2262. context,
  2263. !documentIsHTML,
  2264. results,
  2265. !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
  2266. );
  2267. return results;
  2268. };
  2269. // One-time assignments
  2270. // Sort stability
  2271. support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
  2272. // Support: Chrome 14-35+
  2273. // Always assume duplicates if they aren't passed to the comparison function
  2274. support.detectDuplicates = !!hasDuplicate;
  2275. // Initialize against the default document
  2276. setDocument();
  2277. // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
  2278. // Detached nodes confoundingly follow *each other*
  2279. support.sortDetached = assert(function( el ) {
  2280. // Should return 1, but returns 4 (following)
  2281. return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
  2282. });
  2283. // Support: IE<8
  2284. // Prevent attribute/property "interpolation"
  2285. // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
  2286. if ( !assert(function( el ) {
  2287. el.innerHTML = "<a href='#'></a>";
  2288. return el.firstChild.getAttribute("href") === "#" ;
  2289. }) ) {
  2290. addHandle( "type|href|height|width", function( elem, name, isXML ) {
  2291. if ( !isXML ) {
  2292. return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
  2293. }
  2294. });
  2295. }
  2296. // Support: IE<9
  2297. // Use defaultValue in place of getAttribute("value")
  2298. if ( !support.attributes || !assert(function( el ) {
  2299. el.innerHTML = "<input/>";
  2300. el.firstChild.setAttribute( "value", "" );
  2301. return el.firstChild.getAttribute( "value" ) === "";
  2302. }) ) {
  2303. addHandle( "value", function( elem, name, isXML ) {
  2304. if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
  2305. return elem.defaultValue;
  2306. }
  2307. });
  2308. }
  2309. // Support: IE<9
  2310. // Use getAttributeNode to fetch booleans when getAttribute lies
  2311. if ( !assert(function( el ) {
  2312. return el.getAttribute("disabled") == null;
  2313. }) ) {
  2314. addHandle( booleans, function( elem, name, isXML ) {
  2315. var val;
  2316. if ( !isXML ) {
  2317. return elem[ name ] === true ? name.toLowerCase() :
  2318. (val = elem.getAttributeNode( name )) && val.specified ?
  2319. val.value :
  2320. null;
  2321. }
  2322. });
  2323. }
  2324. return Sizzle;
  2325. })( window );
  2326. jQuery.find = Sizzle;
  2327. jQuery.expr = Sizzle.selectors;
  2328. // Deprecated
  2329. jQuery.expr[ ":" ] = jQuery.expr.pseudos;
  2330. jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
  2331. jQuery.text = Sizzle.getText;
  2332. jQuery.isXMLDoc = Sizzle.isXML;
  2333. jQuery.contains = Sizzle.contains;
  2334. jQuery.escapeSelector = Sizzle.escape;
  2335. var dir = function( elem, dir, until ) {
  2336. var matched = [],
  2337. truncate = until !== undefined;
  2338. while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
  2339. if ( elem.nodeType === 1 ) {
  2340. if ( truncate && jQuery( elem ).is( until ) ) {
  2341. break;
  2342. }
  2343. matched.push( elem );
  2344. }
  2345. }
  2346. return matched;
  2347. };
  2348. var siblings = function( n, elem ) {
  2349. var matched = [];
  2350. for ( ; n; n = n.nextSibling ) {
  2351. if ( n.nodeType === 1 && n !== elem ) {
  2352. matched.push( n );
  2353. }
  2354. }
  2355. return matched;
  2356. };
  2357. var rneedsContext = jQuery.expr.match.needsContext;
  2358. function nodeName( elem, name ) {
  2359. return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
  2360. };
  2361. var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
  2362. var risSimple = /^.[^:#\[\.,]*$/;
  2363. // Implement the identical functionality for filter and not
  2364. function winnow( elements, qualifier, not ) {
  2365. if ( jQuery.isFunction( qualifier ) ) {
  2366. return jQuery.grep( elements, function( elem, i ) {
  2367. return !!qualifier.call( elem, i, elem ) !== not;
  2368. } );
  2369. }
  2370. // Single element
  2371. if ( qualifier.nodeType ) {
  2372. return jQuery.grep( elements, function( elem ) {
  2373. return ( elem === qualifier ) !== not;
  2374. } );
  2375. }
  2376. // Arraylike of elements (jQuery, arguments, Array)
  2377. if ( typeof qualifier !== "string" ) {
  2378. return jQuery.grep( elements, function( elem ) {
  2379. return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
  2380. } );
  2381. }
  2382. // Simple selector that can be filtered directly, removing non-Elements
  2383. if ( risSimple.test( qualifier ) ) {
  2384. return jQuery.filter( qualifier, elements, not );
  2385. }
  2386. // Complex selector, compare the two sets, removing non-Elements
  2387. qualifier = jQuery.filter( qualifier, elements );
  2388. return jQuery.grep( elements, function( elem ) {
  2389. return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;
  2390. } );
  2391. }
  2392. jQuery.filter = function( expr, elems, not ) {
  2393. var elem = elems[ 0 ];
  2394. if ( not ) {
  2395. expr = ":not(" + expr + ")";
  2396. }
  2397. if ( elems.length === 1 && elem.nodeType === 1 ) {
  2398. return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
  2399. }
  2400. return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
  2401. return elem.nodeType === 1;
  2402. } ) );
  2403. };
  2404. jQuery.fn.extend( {
  2405. find: function( selector ) {
  2406. var i, ret,
  2407. len = this.length,
  2408. self = this;
  2409. if ( typeof selector !== "string" ) {
  2410. return this.pushStack( jQuery( selector ).filter( function() {
  2411. for ( i = 0; i < len; i++ ) {
  2412. if ( jQuery.contains( self[ i ], this ) ) {
  2413. return true;
  2414. }
  2415. }
  2416. } ) );
  2417. }
  2418. ret = this.pushStack( [] );
  2419. for ( i = 0; i < len; i++ ) {
  2420. jQuery.find( selector, self[ i ], ret );
  2421. }
  2422. return len > 1 ? jQuery.uniqueSort( ret ) : ret;
  2423. },
  2424. filter: function( selector ) {
  2425. return this.pushStack( winnow( this, selector || [], false ) );
  2426. },
  2427. not: function( selector ) {
  2428. return this.pushStack( winnow( this, selector || [], true ) );
  2429. },
  2430. is: function( selector ) {
  2431. return !!winnow(
  2432. this,
  2433. // If this is a positional/relative selector, check membership in the returned set
  2434. // so $("p:first").is("p:last") won't return true for a doc with two "p".
  2435. typeof selector === "string" && rneedsContext.test( selector ) ?
  2436. jQuery( selector ) :
  2437. selector || [],
  2438. false
  2439. ).length;
  2440. }
  2441. } );
  2442. // Initialize a jQuery object
  2443. // A central reference to the root jQuery(document)
  2444. var rootjQuery,
  2445. // A simple way to check for HTML strings
  2446. // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
  2447. // Strict HTML recognition (#11290: must start with <)
  2448. // Shortcut simple #id case for speed
  2449. rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
  2450. init = jQuery.fn.init = function( selector, context, root ) {
  2451. var match, elem;
  2452. // HANDLE: $(""), $(null), $(undefined), $(false)
  2453. if ( !selector ) {
  2454. return this;
  2455. }
  2456. // Method init() accepts an alternate rootjQuery
  2457. // so migrate can support jQuery.sub (gh-2101)
  2458. root = root || rootjQuery;
  2459. // Handle HTML strings
  2460. if ( typeof selector === "string" ) {
  2461. if ( selector[ 0 ] === "<" &&
  2462. selector[ selector.length - 1 ] === ">" &&
  2463. selector.length >= 3 ) {
  2464. // Assume that strings that start and end with <> are HTML and skip the regex check
  2465. match = [ null, selector, null ];
  2466. } else {
  2467. match = rquickExpr.exec( selector );
  2468. }
  2469. // Match html or make sure no context is specified for #id
  2470. if ( match && ( match[ 1 ] || !context ) ) {
  2471. // HANDLE: $(html) -> $(array)
  2472. if ( match[ 1 ] ) {
  2473. context = context instanceof jQuery ? context[ 0 ] : context;
  2474. // Option to run scripts is true for back-compat
  2475. // Intentionally let the error be thrown if parseHTML is not present
  2476. jQuery.merge( this, jQuery.parseHTML(
  2477. match[ 1 ],
  2478. context && context.nodeType ? context.ownerDocument || context : document,
  2479. true
  2480. ) );
  2481. // HANDLE: $(html, props)
  2482. if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
  2483. for ( match in context ) {
  2484. // Properties of context are called as methods if possible
  2485. if ( jQuery.isFunction( this[ match ] ) ) {
  2486. this[ match ]( context[ match ] );
  2487. // ...and otherwise set as attributes
  2488. } else {
  2489. this.attr( match, context[ match ] );
  2490. }
  2491. }
  2492. }
  2493. return this;
  2494. // HANDLE: $(#id)
  2495. } else {
  2496. elem = document.getElementById( match[ 2 ] );
  2497. if ( elem ) {
  2498. // Inject the element directly into the jQuery object
  2499. this[ 0 ] = elem;
  2500. this.length = 1;
  2501. }
  2502. return this;
  2503. }
  2504. // HANDLE: $(expr, $(...))
  2505. } else if ( !context || context.jquery ) {
  2506. return ( context || root ).find( selector );
  2507. // HANDLE: $(expr, context)
  2508. // (which is just equivalent to: $(context).find(expr)
  2509. } else {
  2510. return this.constructor( context ).find( selector );
  2511. }
  2512. // HANDLE: $(DOMElement)
  2513. } else if ( selector.nodeType ) {
  2514. this[ 0 ] = selector;
  2515. this.length = 1;
  2516. return this;
  2517. // HANDLE: $(function)
  2518. // Shortcut for document ready
  2519. } else if ( jQuery.isFunction( selector ) ) {
  2520. return root.ready !== undefined ?
  2521. root.ready( selector ) :
  2522. // Execute immediately if ready is not present
  2523. selector( jQuery );
  2524. }
  2525. return jQuery.makeArray( selector, this );
  2526. };
  2527. // Give the init function the jQuery prototype for later instantiation
  2528. init.prototype = jQuery.fn;
  2529. // Initialize central reference
  2530. rootjQuery = jQuery( document );
  2531. var rparentsprev = /^(?:parents|prev(?:Until|All))/,
  2532. // Methods guaranteed to produce a unique set when starting from a unique set
  2533. guaranteedUnique = {
  2534. children: true,
  2535. contents: true,
  2536. next: true,
  2537. prev: true
  2538. };
  2539. jQuery.fn.extend( {
  2540. has: function( target ) {
  2541. var targets = jQuery( target, this ),
  2542. l = targets.length;
  2543. return this.filter( function() {
  2544. var i = 0;
  2545. for ( ; i < l; i++ ) {
  2546. if ( jQuery.contains( this, targets[ i ] ) ) {
  2547. return true;
  2548. }
  2549. }
  2550. } );
  2551. },
  2552. closest: function( selectors, context ) {
  2553. var cur,
  2554. i = 0,
  2555. l = this.length,
  2556. matched = [],
  2557. targets = typeof selectors !== "string" && jQuery( selectors );
  2558. // Positional selectors never match, since there's no _selection_ context
  2559. if ( !rneedsContext.test( selectors ) ) {
  2560. for ( ; i < l; i++ ) {
  2561. for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
  2562. // Always skip document fragments
  2563. if ( cur.nodeType < 11 && ( targets ?
  2564. targets.index( cur ) > -1 :
  2565. // Don't pass non-elements to Sizzle
  2566. cur.nodeType === 1 &&
  2567. jQuery.find.matchesSelector( cur, selectors ) ) ) {
  2568. matched.push( cur );
  2569. break;
  2570. }
  2571. }
  2572. }
  2573. }
  2574. return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
  2575. },
  2576. // Determine the position of an element within the set
  2577. index: function( elem ) {
  2578. // No argument, return index in parent
  2579. if ( !elem ) {
  2580. return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
  2581. }
  2582. // Index in selector
  2583. if ( typeof elem === "string" ) {
  2584. return indexOf.call( jQuery( elem ), this[ 0 ] );
  2585. }
  2586. // Locate the position of the desired element
  2587. return indexOf.call( this,
  2588. // If it receives a jQuery object, the first element is used
  2589. elem.jquery ? elem[ 0 ] : elem
  2590. );
  2591. },
  2592. add: function( selector, context ) {
  2593. return this.pushStack(
  2594. jQuery.uniqueSort(
  2595. jQuery.merge( this.get(), jQuery( selector, context ) )
  2596. )
  2597. );
  2598. },
  2599. addBack: function( selector ) {
  2600. return this.add( selector == null ?
  2601. this.prevObject : this.prevObject.filter( selector )
  2602. );
  2603. }
  2604. } );
  2605. function sibling( cur, dir ) {
  2606. while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
  2607. return cur;
  2608. }
  2609. jQuery.each( {
  2610. parent: function( elem ) {
  2611. var parent = elem.parentNode;
  2612. return parent && parent.nodeType !== 11 ? parent : null;
  2613. },
  2614. parents: function( elem ) {
  2615. return dir( elem, "parentNode" );
  2616. },
  2617. parentsUntil: function( elem, i, until ) {
  2618. return dir( elem, "parentNode", until );
  2619. },
  2620. next: function( elem ) {
  2621. return sibling( elem, "nextSibling" );
  2622. },
  2623. prev: function( elem ) {
  2624. return sibling( elem, "previousSibling" );
  2625. },
  2626. nextAll: function( elem ) {
  2627. return dir( elem, "nextSibling" );
  2628. },
  2629. prevAll: function( elem ) {
  2630. return dir( elem, "previousSibling" );
  2631. },
  2632. nextUntil: function( elem, i, until ) {
  2633. return dir( elem, "nextSibling", until );
  2634. },
  2635. prevUntil: function( elem, i, until ) {
  2636. return dir( elem, "previousSibling", until );
  2637. },
  2638. siblings: function( elem ) {
  2639. return siblings( ( elem.parentNode || {} ).firstChild, elem );
  2640. },
  2641. children: function( elem ) {
  2642. return siblings( elem.firstChild );
  2643. },
  2644. contents: function( elem ) {
  2645. if ( nodeName( elem, "iframe" ) ) {
  2646. return elem.contentDocument;
  2647. }
  2648. // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
  2649. // Treat the template element as a regular one in browsers that
  2650. // don't support it.
  2651. if ( nodeName( elem, "template" ) ) {
  2652. elem = elem.content || elem;
  2653. }
  2654. return jQuery.merge( [], elem.childNodes );
  2655. }
  2656. }, function( name, fn ) {
  2657. jQuery.fn[ name ] = function( until, selector ) {
  2658. var matched = jQuery.map( this, fn, until );
  2659. if ( name.slice( -5 ) !== "Until" ) {
  2660. selector = until;
  2661. }
  2662. if ( selector && typeof selector === "string" ) {
  2663. matched = jQuery.filter( selector, matched );
  2664. }
  2665. if ( this.length > 1 ) {
  2666. // Remove duplicates
  2667. if ( !guaranteedUnique[ name ] ) {
  2668. jQuery.uniqueSort( matched );
  2669. }
  2670. // Reverse order for parents* and prev-derivatives
  2671. if ( rparentsprev.test( name ) ) {
  2672. matched.reverse();
  2673. }
  2674. }
  2675. return this.pushStack( matched );
  2676. };
  2677. } );
  2678. var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
  2679. // Convert String-formatted options into Object-formatted ones
  2680. function createOptions( options ) {
  2681. var object = {};
  2682. jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
  2683. object[ flag ] = true;
  2684. } );
  2685. return object;
  2686. }
  2687. /*
  2688. * Create a callback list using the following parameters:
  2689. *
  2690. * options: an optional list of space-separated options that will change how
  2691. * the callback list behaves or a more traditional option object
  2692. *
  2693. * By default a callback list will act like an event callback list and can be
  2694. * "fired" multiple times.
  2695. *
  2696. * Possible options:
  2697. *
  2698. * once: will ensure the callback list can only be fired once (like a Deferred)
  2699. *
  2700. * memory: will keep track of previous values and will call any callback added
  2701. * after the list has been fired right away with the latest "memorized"
  2702. * values (like a Deferred)
  2703. *
  2704. * unique: will ensure a callback can only be added once (no duplicate in the list)
  2705. *
  2706. * stopOnFalse: interrupt callings when a callback returns false
  2707. *
  2708. */
  2709. jQuery.Callbacks = function( options ) {
  2710. // Convert options from String-formatted to Object-formatted if needed
  2711. // (we check in cache first)
  2712. options = typeof options === "string" ?
  2713. createOptions( options ) :
  2714. jQuery.extend( {}, options );
  2715. var // Flag to know if list is currently firing
  2716. firing,
  2717. // Last fire value for non-forgettable lists
  2718. memory,
  2719. // Flag to know if list was already fired
  2720. fired,
  2721. // Flag to prevent firing
  2722. locked,
  2723. // Actual callback list
  2724. list = [],
  2725. // Queue of execution data for repeatable lists
  2726. queue = [],
  2727. // Index of currently firing callback (modified by add/remove as needed)
  2728. firingIndex = -1,
  2729. // Fire callbacks
  2730. fire = function() {
  2731. // Enforce single-firing
  2732. locked = locked || options.once;
  2733. // Execute callbacks for all pending executions,
  2734. // respecting firingIndex overrides and runtime changes
  2735. fired = firing = true;
  2736. for ( ; queue.length; firingIndex = -1 ) {
  2737. memory = queue.shift();
  2738. while ( ++firingIndex < list.length ) {
  2739. // Run callback and check for early termination
  2740. if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
  2741. options.stopOnFalse ) {
  2742. // Jump to end and forget the data so .add doesn't re-fire
  2743. firingIndex = list.length;
  2744. memory = false;
  2745. }
  2746. }
  2747. }
  2748. // Forget the data if we're done with it
  2749. if ( !options.memory ) {
  2750. memory = false;
  2751. }
  2752. firing = false;
  2753. // Clean up if we're done firing for good
  2754. if ( locked ) {
  2755. // Keep an empty list if we have data for future add calls
  2756. if ( memory ) {
  2757. list = [];
  2758. // Otherwise, this object is spent
  2759. } else {
  2760. list = "";
  2761. }
  2762. }
  2763. },
  2764. // Actual Callbacks object
  2765. self = {
  2766. // Add a callback or a collection of callbacks to the list
  2767. add: function() {
  2768. if ( list ) {
  2769. // If we have memory from a past run, we should fire after adding
  2770. if ( memory && !firing ) {
  2771. firingIndex = list.length - 1;
  2772. queue.push( memory );
  2773. }
  2774. ( function add( args ) {
  2775. jQuery.each( args, function( _, arg ) {
  2776. if ( jQuery.isFunction( arg ) ) {
  2777. if ( !options.unique || !self.has( arg ) ) {
  2778. list.push( arg );
  2779. }
  2780. } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
  2781. // Inspect recursively
  2782. add( arg );
  2783. }
  2784. } );
  2785. } )( arguments );
  2786. if ( memory && !firing ) {
  2787. fire();
  2788. }
  2789. }
  2790. return this;
  2791. },
  2792. // Remove a callback from the list
  2793. remove: function() {
  2794. jQuery.each( arguments, function( _, arg ) {
  2795. var index;
  2796. while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
  2797. list.splice( index, 1 );
  2798. // Handle firing indexes
  2799. if ( index <= firingIndex ) {
  2800. firingIndex--;
  2801. }
  2802. }
  2803. } );
  2804. return this;
  2805. },
  2806. // Check if a given callback is in the list.
  2807. // If no argument is given, return whether or not list has callbacks attached.
  2808. has: function( fn ) {
  2809. return fn ?
  2810. jQuery.inArray( fn, list ) > -1 :
  2811. list.length > 0;
  2812. },
  2813. // Remove all callbacks from the list
  2814. empty: function() {
  2815. if ( list ) {
  2816. list = [];
  2817. }
  2818. return this;
  2819. },
  2820. // Disable .fire and .add
  2821. // Abort any current/pending executions
  2822. // Clear all callbacks and values
  2823. disable: function() {
  2824. locked = queue = [];
  2825. list = memory = "";
  2826. return this;
  2827. },
  2828. disabled: function() {
  2829. return !list;
  2830. },
  2831. // Disable .fire
  2832. // Also disable .add unless we have memory (since it would have no effect)
  2833. // Abort any pending executions
  2834. lock: function() {
  2835. locked = queue = [];
  2836. if ( !memory && !firing ) {
  2837. list = memory = "";
  2838. }
  2839. return this;
  2840. },
  2841. locked: function() {
  2842. return !!locked;
  2843. },
  2844. // Call all callbacks with the given context and arguments
  2845. fireWith: function( context, args ) {
  2846. if ( !locked ) {
  2847. args = args || [];
  2848. args = [ context, args.slice ? args.slice() : args ];
  2849. queue.push( args );
  2850. if ( !firing ) {
  2851. fire();
  2852. }
  2853. }
  2854. return this;
  2855. },
  2856. // Call all the callbacks with the given arguments
  2857. fire: function() {
  2858. self.fireWith( this, arguments );
  2859. return this;
  2860. },
  2861. // To know if the callbacks have already been called at least once
  2862. fired: function() {
  2863. return !!fired;
  2864. }
  2865. };
  2866. return self;
  2867. };
  2868. function Identity( v ) {
  2869. return v;
  2870. }
  2871. function Thrower( ex ) {
  2872. throw ex;
  2873. }
  2874. function adoptValue( value, resolve, reject, noValue ) {
  2875. var method;
  2876. try {
  2877. // Check for promise aspect first to privilege synchronous behavior
  2878. if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {
  2879. method.call( value ).done( resolve ).fail( reject );
  2880. // Other thenables
  2881. } else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {
  2882. method.call( value, resolve, reject );
  2883. // Other non-thenables
  2884. } else {
  2885. // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
  2886. // * false: [ value ].slice( 0 ) => resolve( value )
  2887. // * true: [ value ].slice( 1 ) => resolve()
  2888. resolve.apply( undefined, [ value ].slice( noValue ) );
  2889. }
  2890. // For Promises/A+, convert exceptions into rejections
  2891. // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
  2892. // Deferred#then to conditionally suppress rejection.
  2893. } catch ( value ) {
  2894. // Support: Android 4.0 only
  2895. // Strict mode functions invoked without .call/.apply get global-object context
  2896. reject.apply( undefined, [ value ] );
  2897. }
  2898. }
  2899. jQuery.extend( {
  2900. Deferred: function( func ) {
  2901. var tuples = [
  2902. // action, add listener, callbacks,
  2903. // ... .then handlers, argument index, [final state]
  2904. [ "notify", "progress", jQuery.Callbacks( "memory" ),
  2905. jQuery.Callbacks( "memory" ), 2 ],
  2906. [ "resolve", "done", jQuery.Callbacks( "once memory" ),
  2907. jQuery.Callbacks( "once memory" ), 0, "resolved" ],
  2908. [ "reject", "fail", jQuery.Callbacks( "once memory" ),
  2909. jQuery.Callbacks( "once memory" ), 1, "rejected" ]
  2910. ],
  2911. state = "pending",
  2912. promise = {
  2913. state: function() {
  2914. return state;
  2915. },
  2916. always: function() {
  2917. deferred.done( arguments ).fail( arguments );
  2918. return this;
  2919. },
  2920. "catch": function( fn ) {
  2921. return promise.then( null, fn );
  2922. },
  2923. // Keep pipe for back-compat
  2924. pipe: function( /* fnDone, fnFail, fnProgress */ ) {
  2925. var fns = arguments;
  2926. return jQuery.Deferred( function( newDefer ) {
  2927. jQuery.each( tuples, function( i, tuple ) {
  2928. // Map tuples (progress, done, fail) to arguments (done, fail, progress)
  2929. var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
  2930. // deferred.progress(function() { bind to newDefer or newDefer.notify })
  2931. // deferred.done(function() { bind to newDefer or newDefer.resolve })
  2932. // deferred.fail(function() { bind to newDefer or newDefer.reject })
  2933. deferred[ tuple[ 1 ] ]( function() {
  2934. var returned = fn && fn.apply( this, arguments );
  2935. if ( returned && jQuery.isFunction( returned.promise ) ) {
  2936. returned.promise()
  2937. .progress( newDefer.notify )
  2938. .done( newDefer.resolve )
  2939. .fail( newDefer.reject );
  2940. } else {
  2941. newDefer[ tuple[ 0 ] + "With" ](
  2942. this,
  2943. fn ? [ returned ] : arguments
  2944. );
  2945. }
  2946. } );
  2947. } );
  2948. fns = null;
  2949. } ).promise();
  2950. },
  2951. then: function( onFulfilled, onRejected, onProgress ) {
  2952. var maxDepth = 0;
  2953. function resolve( depth, deferred, handler, special ) {
  2954. return function() {
  2955. var that = this,
  2956. args = arguments,
  2957. mightThrow = function() {
  2958. var returned, then;
  2959. // Support: Promises/A+ section 2.3.3.3.3
  2960. // https://promisesaplus.com/#point-59
  2961. // Ignore double-resolution attempts
  2962. if ( depth < maxDepth ) {
  2963. return;
  2964. }
  2965. returned = handler.apply( that, args );
  2966. // Support: Promises/A+ section 2.3.1
  2967. // https://promisesaplus.com/#point-48
  2968. if ( returned === deferred.promise() ) {
  2969. throw new TypeError( "Thenable self-resolution" );
  2970. }
  2971. // Support: Promises/A+ sections 2.3.3.1, 3.5
  2972. // https://promisesaplus.com/#point-54
  2973. // https://promisesaplus.com/#point-75
  2974. // Retrieve `then` only once
  2975. then = returned &&
  2976. // Support: Promises/A+ section 2.3.4
  2977. // https://promisesaplus.com/#point-64
  2978. // Only check objects and functions for thenability
  2979. ( typeof returned === "object" ||
  2980. typeof returned === "function" ) &&
  2981. returned.then;
  2982. // Handle a returned thenable
  2983. if ( jQuery.isFunction( then ) ) {
  2984. // Special processors (notify) just wait for resolution
  2985. if ( special ) {
  2986. then.call(
  2987. returned,
  2988. resolve( maxDepth, deferred, Identity, special ),
  2989. resolve( maxDepth, deferred, Thrower, special )
  2990. );
  2991. // Normal processors (resolve) also hook into progress
  2992. } else {
  2993. // ...and disregard older resolution values
  2994. maxDepth++;
  2995. then.call(
  2996. returned,
  2997. resolve( maxDepth, deferred, Identity, special ),
  2998. resolve( maxDepth, deferred, Thrower, special ),
  2999. resolve( maxDepth, deferred, Identity,
  3000. deferred.notifyWith )
  3001. );
  3002. }
  3003. // Handle all other returned values
  3004. } else {
  3005. // Only substitute handlers pass on context
  3006. // and multiple values (non-spec behavior)
  3007. if ( handler !== Identity ) {
  3008. that = undefined;
  3009. args = [ returned ];
  3010. }
  3011. // Process the value(s)
  3012. // Default process is resolve
  3013. ( special || deferred.resolveWith )( that, args );
  3014. }
  3015. },
  3016. // Only normal processors (resolve) catch and reject exceptions
  3017. process = special ?
  3018. mightThrow :
  3019. function() {
  3020. try {
  3021. mightThrow();
  3022. } catch ( e ) {
  3023. if ( jQuery.Deferred.exceptionHook ) {
  3024. jQuery.Deferred.exceptionHook( e,
  3025. process.stackTrace );
  3026. }
  3027. // Support: Promises/A+ section 2.3.3.3.4.1
  3028. // https://promisesaplus.com/#point-61
  3029. // Ignore post-resolution exceptions
  3030. if ( depth + 1 >= maxDepth ) {
  3031. // Only substitute handlers pass on context
  3032. // and multiple values (non-spec behavior)
  3033. if ( handler !== Thrower ) {
  3034. that = undefined;
  3035. args = [ e ];
  3036. }
  3037. deferred.rejectWith( that, args );
  3038. }
  3039. }
  3040. };
  3041. // Support: Promises/A+ section 2.3.3.3.1
  3042. // https://promisesaplus.com/#point-57
  3043. // Re-resolve promises immediately to dodge false rejection from
  3044. // subsequent errors
  3045. if ( depth ) {
  3046. process();
  3047. } else {
  3048. // Call an optional hook to record the stack, in case of exception
  3049. // since it's otherwise lost when execution goes async
  3050. if ( jQuery.Deferred.getStackHook ) {
  3051. process.stackTrace = jQuery.Deferred.getStackHook();
  3052. }
  3053. window.setTimeout( process );
  3054. }
  3055. };
  3056. }
  3057. return jQuery.Deferred( function( newDefer ) {
  3058. // progress_handlers.add( ... )
  3059. tuples[ 0 ][ 3 ].add(
  3060. resolve(
  3061. 0,
  3062. newDefer,
  3063. jQuery.isFunction( onProgress ) ?
  3064. onProgress :
  3065. Identity,
  3066. newDefer.notifyWith
  3067. )
  3068. );
  3069. // fulfilled_handlers.add( ... )
  3070. tuples[ 1 ][ 3 ].add(
  3071. resolve(
  3072. 0,
  3073. newDefer,
  3074. jQuery.isFunction( onFulfilled ) ?
  3075. onFulfilled :
  3076. Identity
  3077. )
  3078. );
  3079. // rejected_handlers.add( ... )
  3080. tuples[ 2 ][ 3 ].add(
  3081. resolve(
  3082. 0,
  3083. newDefer,
  3084. jQuery.isFunction( onRejected ) ?
  3085. onRejected :
  3086. Thrower
  3087. )
  3088. );
  3089. } ).promise();
  3090. },
  3091. // Get a promise for this deferred
  3092. // If obj is provided, the promise aspect is added to the object
  3093. promise: function( obj ) {
  3094. return obj != null ? jQuery.extend( obj, promise ) : promise;
  3095. }
  3096. },
  3097. deferred = {};
  3098. // Add list-specific methods
  3099. jQuery.each( tuples, function( i, tuple ) {
  3100. var list = tuple[ 2 ],
  3101. stateString = tuple[ 5 ];
  3102. // promise.progress = list.add
  3103. // promise.done = list.add
  3104. // promise.fail = list.add
  3105. promise[ tuple[ 1 ] ] = list.add;
  3106. // Handle state
  3107. if ( stateString ) {
  3108. list.add(
  3109. function() {
  3110. // state = "resolved" (i.e., fulfilled)
  3111. // state = "rejected"
  3112. state = stateString;
  3113. },
  3114. // rejected_callbacks.disable
  3115. // fulfilled_callbacks.disable
  3116. tuples[ 3 - i ][ 2 ].disable,
  3117. // progress_callbacks.lock
  3118. tuples[ 0 ][ 2 ].lock
  3119. );
  3120. }
  3121. // progress_handlers.fire
  3122. // fulfilled_handlers.fire
  3123. // rejected_handlers.fire
  3124. list.add( tuple[ 3 ].fire );
  3125. // deferred.notify = function() { deferred.notifyWith(...) }
  3126. // deferred.resolve = function() { deferred.resolveWith(...) }
  3127. // deferred.reject = function() { deferred.rejectWith(...) }
  3128. deferred[ tuple[ 0 ] ] = function() {
  3129. deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
  3130. return this;
  3131. };
  3132. // deferred.notifyWith = list.fireWith
  3133. // deferred.resolveWith = list.fireWith
  3134. // deferred.rejectWith = list.fireWith
  3135. deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
  3136. } );
  3137. // Make the deferred a promise
  3138. promise.promise( deferred );
  3139. // Call given func if any
  3140. if ( func ) {
  3141. func.call( deferred, deferred );
  3142. }
  3143. // All done!
  3144. return deferred;
  3145. },
  3146. // Deferred helper
  3147. when: function( singleValue ) {
  3148. var
  3149. // count of uncompleted subordinates
  3150. remaining = arguments.length,
  3151. // count of unprocessed arguments
  3152. i = remaining,
  3153. // subordinate fulfillment data
  3154. resolveContexts = Array( i ),
  3155. resolveValues = slice.call( arguments ),
  3156. // the master Deferred
  3157. master = jQuery.Deferred(),
  3158. // subordinate callback factory
  3159. updateFunc = function( i ) {
  3160. return function( value ) {
  3161. resolveContexts[ i ] = this;
  3162. resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
  3163. if ( !( --remaining ) ) {
  3164. master.resolveWith( resolveContexts, resolveValues );
  3165. }
  3166. };
  3167. };
  3168. // Single- and empty arguments are adopted like Promise.resolve
  3169. if ( remaining <= 1 ) {
  3170. adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
  3171. !remaining );
  3172. // Use .then() to unwrap secondary thenables (cf. gh-3000)
  3173. if ( master.state() === "pending" ||
  3174. jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
  3175. return master.then();
  3176. }
  3177. }
  3178. // Multiple arguments are aggregated like Promise.all array elements
  3179. while ( i-- ) {
  3180. adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
  3181. }
  3182. return master.promise();
  3183. }
  3184. } );
  3185. // These usually indicate a programmer mistake during development,
  3186. // warn about them ASAP rather than swallowing them by default.
  3187. var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
  3188. jQuery.Deferred.exceptionHook = function( error, stack ) {
  3189. // Support: IE 8 - 9 only
  3190. // Console exists when dev tools are open, which can happen at any time
  3191. if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
  3192. window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
  3193. }
  3194. };
  3195. jQuery.readyException = function( error ) {
  3196. window.setTimeout( function() {
  3197. throw error;
  3198. } );
  3199. };
  3200. // The deferred used on DOM ready
  3201. var readyList = jQuery.Deferred();
  3202. jQuery.fn.ready = function( fn ) {
  3203. readyList
  3204. .then( fn )
  3205. // Wrap jQuery.readyException in a function so that the lookup
  3206. // happens at the time of error handling instead of callback
  3207. // registration.
  3208. .catch( function( error ) {
  3209. jQuery.readyException( error );
  3210. } );
  3211. return this;
  3212. };
  3213. jQuery.extend( {
  3214. // Is the DOM ready to be used? Set to true once it occurs.
  3215. isReady: false,
  3216. // A counter to track how many items to wait for before
  3217. // the ready event fires. See #6781
  3218. readyWait: 1,
  3219. // Handle when the DOM is ready
  3220. ready: function( wait ) {
  3221. // Abort if there are pending holds or we're already ready
  3222. if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
  3223. return;
  3224. }
  3225. // Remember that the DOM is ready
  3226. jQuery.isReady = true;
  3227. // If a normal DOM Ready event fired, decrement, and wait if need be
  3228. if ( wait !== true && --jQuery.readyWait > 0 ) {
  3229. return;
  3230. }
  3231. // If there are functions bound, to execute
  3232. readyList.resolveWith( document, [ jQuery ] );
  3233. }
  3234. } );
  3235. jQuery.ready.then = readyList.then;
  3236. // The ready event handler and self cleanup method
  3237. function completed() {
  3238. document.removeEventListener( "DOMContentLoaded", completed );
  3239. window.removeEventListener( "load", completed );
  3240. jQuery.ready();
  3241. }
  3242. // Catch cases where $(document).ready() is called
  3243. // after the browser event has already occurred.
  3244. // Support: IE <=9 - 10 only
  3245. // Older IE sometimes signals "interactive" too soon
  3246. if ( document.readyState === "complete" ||
  3247. ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
  3248. // Handle it asynchronously to allow scripts the opportunity to delay ready
  3249. window.setTimeout( jQuery.ready );
  3250. } else {
  3251. // Use the handy event callback
  3252. document.addEventListener( "DOMContentLoaded", completed );
  3253. // A fallback to window.onload, that will always work
  3254. window.addEventListener( "load", completed );
  3255. }
  3256. // Multifunctional method to get and set values of a collection
  3257. // The value/s can optionally be executed if it's a function
  3258. var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
  3259. var i = 0,
  3260. len = elems.length,
  3261. bulk = key == null;
  3262. // Sets many values
  3263. if ( jQuery.type( key ) === "object" ) {
  3264. chainable = true;
  3265. for ( i in key ) {
  3266. access( elems, fn, i, key[ i ], true, emptyGet, raw );
  3267. }
  3268. // Sets one value
  3269. } else if ( value !== undefined ) {
  3270. chainable = true;
  3271. if ( !jQuery.isFunction( value ) ) {
  3272. raw = true;
  3273. }
  3274. if ( bulk ) {
  3275. // Bulk operations run against the entire set
  3276. if ( raw ) {
  3277. fn.call( elems, value );
  3278. fn = null;
  3279. // ...except when executing function values
  3280. } else {
  3281. bulk = fn;
  3282. fn = function( elem, key, value ) {
  3283. return bulk.call( jQuery( elem ), value );
  3284. };
  3285. }
  3286. }
  3287. if ( fn ) {
  3288. for ( ; i < len; i++ ) {
  3289. fn(
  3290. elems[ i ], key, raw ?
  3291. value :
  3292. value.call( elems[ i ], i, fn( elems[ i ], key ) )
  3293. );
  3294. }
  3295. }
  3296. }
  3297. if ( chainable ) {
  3298. return elems;
  3299. }
  3300. // Gets
  3301. if ( bulk ) {
  3302. return fn.call( elems );
  3303. }
  3304. return len ? fn( elems[ 0 ], key ) : emptyGet;
  3305. };
  3306. var acceptData = function( owner ) {
  3307. // Accepts only:
  3308. // - Node
  3309. // - Node.ELEMENT_NODE
  3310. // - Node.DOCUMENT_NODE
  3311. // - Object
  3312. // - Any
  3313. return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
  3314. };
  3315. function Data() {
  3316. this.expando = jQuery.expando + Data.uid++;
  3317. }
  3318. Data.uid = 1;
  3319. Data.prototype = {
  3320. cache: function( owner ) {
  3321. // Check if the owner object already has a cache
  3322. var value = owner[ this.expando ];
  3323. // If not, create one
  3324. if ( !value ) {
  3325. value = {};
  3326. // We can accept data for non-element nodes in modern browsers,
  3327. // but we should not, see #8335.
  3328. // Always return an empty object.
  3329. if ( acceptData( owner ) ) {
  3330. // If it is a node unlikely to be stringify-ed or looped over
  3331. // use plain assignment
  3332. if ( owner.nodeType ) {
  3333. owner[ this.expando ] = value;
  3334. // Otherwise secure it in a non-enumerable property
  3335. // configurable must be true to allow the property to be
  3336. // deleted when data is removed
  3337. } else {
  3338. Object.defineProperty( owner, this.expando, {
  3339. value: value,
  3340. configurable: true
  3341. } );
  3342. }
  3343. }
  3344. }
  3345. return value;
  3346. },
  3347. set: function( owner, data, value ) {
  3348. var prop,
  3349. cache = this.cache( owner );
  3350. // Handle: [ owner, key, value ] args
  3351. // Always use camelCase key (gh-2257)
  3352. if ( typeof data === "string" ) {
  3353. cache[ jQuery.camelCase( data ) ] = value;
  3354. // Handle: [ owner, { properties } ] args
  3355. } else {
  3356. // Copy the properties one-by-one to the cache object
  3357. for ( prop in data ) {
  3358. cache[ jQuery.camelCase( prop ) ] = data[ prop ];
  3359. }
  3360. }
  3361. return cache;
  3362. },
  3363. get: function( owner, key ) {
  3364. return key === undefined ?
  3365. this.cache( owner ) :
  3366. // Always use camelCase key (gh-2257)
  3367. owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];
  3368. },
  3369. access: function( owner, key, value ) {
  3370. // In cases where either:
  3371. //
  3372. // 1. No key was specified
  3373. // 2. A string key was specified, but no value provided
  3374. //
  3375. // Take the "read" path and allow the get method to determine
  3376. // which value to return, respectively either:
  3377. //
  3378. // 1. The entire cache object
  3379. // 2. The data stored at the key
  3380. //
  3381. if ( key === undefined ||
  3382. ( ( key && typeof key === "string" ) && value === undefined ) ) {
  3383. return this.get( owner, key );
  3384. }
  3385. // When the key is not a string, or both a key and value
  3386. // are specified, set or extend (existing objects) with either:
  3387. //
  3388. // 1. An object of properties
  3389. // 2. A key and value
  3390. //
  3391. this.set( owner, key, value );
  3392. // Since the "set" path can have two possible entry points
  3393. // return the expected data based on which path was taken[*]
  3394. return value !== undefined ? value : key;
  3395. },
  3396. remove: function( owner, key ) {
  3397. var i,
  3398. cache = owner[ this.expando ];
  3399. if ( cache === undefined ) {
  3400. return;
  3401. }
  3402. if ( key !== undefined ) {
  3403. // Support array or space separated string of keys
  3404. if ( Array.isArray( key ) ) {
  3405. // If key is an array of keys...
  3406. // We always set camelCase keys, so remove that.
  3407. key = key.map( jQuery.camelCase );
  3408. } else {
  3409. key = jQuery.camelCase( key );
  3410. // If a key with the spaces exists, use it.
  3411. // Otherwise, create an array by matching non-whitespace
  3412. key = key in cache ?
  3413. [ key ] :
  3414. ( key.match( rnothtmlwhite ) || [] );
  3415. }
  3416. i = key.length;
  3417. while ( i-- ) {
  3418. delete cache[ key[ i ] ];
  3419. }
  3420. }
  3421. // Remove the expando if there's no more data
  3422. if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
  3423. // Support: Chrome <=35 - 45
  3424. // Webkit & Blink performance suffers when deleting properties
  3425. // from DOM nodes, so set to undefined instead
  3426. // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
  3427. if ( owner.nodeType ) {
  3428. owner[ this.expando ] = undefined;
  3429. } else {
  3430. delete owner[ this.expando ];
  3431. }
  3432. }
  3433. },
  3434. hasData: function( owner ) {
  3435. var cache = owner[ this.expando ];
  3436. return cache !== undefined && !jQuery.isEmptyObject( cache );
  3437. }
  3438. };
  3439. var dataPriv = new Data();
  3440. var dataUser = new Data();
  3441. // Implementation Summary
  3442. //
  3443. // 1. Enforce API surface and semantic compatibility with 1.9.x branch
  3444. // 2. Improve the module's maintainability by reducing the storage
  3445. // paths to a single mechanism.
  3446. // 3. Use the same single mechanism to support "private" and "user" data.
  3447. // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
  3448. // 5. Avoid exposing implementation details on user objects (eg. expando properties)
  3449. // 6. Provide a clear path for implementation upgrade to WeakMap in 2014
  3450. var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
  3451. rmultiDash = /[A-Z]/g;
  3452. function getData( data ) {
  3453. if ( data === "true" ) {
  3454. return true;
  3455. }
  3456. if ( data === "false" ) {
  3457. return false;
  3458. }
  3459. if ( data === "null" ) {
  3460. return null;
  3461. }
  3462. // Only convert to a number if it doesn't change the string
  3463. if ( data === +data + "" ) {
  3464. return +data;
  3465. }
  3466. if ( rbrace.test( data ) ) {
  3467. return JSON.parse( data );
  3468. }
  3469. return data;
  3470. }
  3471. function dataAttr( elem, key, data ) {
  3472. var name;
  3473. // If nothing was found internally, try to fetch any
  3474. // data from the HTML5 data-* attribute
  3475. if ( data === undefined && elem.nodeType === 1 ) {
  3476. name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
  3477. data = elem.getAttribute( name );
  3478. if ( typeof data === "string" ) {
  3479. try {
  3480. data = getData( data );
  3481. } catch ( e ) {}
  3482. // Make sure we set the data so it isn't changed later
  3483. dataUser.set( elem, key, data );
  3484. } else {
  3485. data = undefined;
  3486. }
  3487. }
  3488. return data;
  3489. }
  3490. jQuery.extend( {
  3491. hasData: function( elem ) {
  3492. return dataUser.hasData( elem ) || dataPriv.hasData( elem );
  3493. },
  3494. data: function( elem, name, data ) {
  3495. return dataUser.access( elem, name, data );
  3496. },
  3497. removeData: function( elem, name ) {
  3498. dataUser.remove( elem, name );
  3499. },
  3500. // TODO: Now that all calls to _data and _removeData have been replaced
  3501. // with direct calls to dataPriv methods, these can be deprecated.
  3502. _data: function( elem, name, data ) {
  3503. return dataPriv.access( elem, name, data );
  3504. },
  3505. _removeData: function( elem, name ) {
  3506. dataPriv.remove( elem, name );
  3507. }
  3508. } );
  3509. jQuery.fn.extend( {
  3510. data: function( key, value ) {
  3511. var i, name, data,
  3512. elem = this[ 0 ],
  3513. attrs = elem && elem.attributes;
  3514. // Gets all values
  3515. if ( key === undefined ) {
  3516. if ( this.length ) {
  3517. data = dataUser.get( elem );
  3518. if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
  3519. i = attrs.length;
  3520. while ( i-- ) {
  3521. // Support: IE 11 only
  3522. // The attrs elements can be null (#14894)
  3523. if ( attrs[ i ] ) {
  3524. name = attrs[ i ].name;
  3525. if ( name.indexOf( "data-" ) === 0 ) {
  3526. name = jQuery.camelCase( name.slice( 5 ) );
  3527. dataAttr( elem, name, data[ name ] );
  3528. }
  3529. }
  3530. }
  3531. dataPriv.set( elem, "hasDataAttrs", true );
  3532. }
  3533. }
  3534. return data;
  3535. }
  3536. // Sets multiple values
  3537. if ( typeof key === "object" ) {
  3538. return this.each( function() {
  3539. dataUser.set( this, key );
  3540. } );
  3541. }
  3542. return access( this, function( value ) {
  3543. var data;
  3544. // The calling jQuery object (element matches) is not empty
  3545. // (and therefore has an element appears at this[ 0 ]) and the
  3546. // `value` parameter was not undefined. An empty jQuery object
  3547. // will result in `undefined` for elem = this[ 0 ] which will
  3548. // throw an exception if an attempt to read a data cache is made.
  3549. if ( elem && value === undefined ) {
  3550. // Attempt to get data from the cache
  3551. // The key will always be camelCased in Data
  3552. data = dataUser.get( elem, key );
  3553. if ( data !== undefined ) {
  3554. return data;
  3555. }
  3556. // Attempt to "discover" the data in
  3557. // HTML5 custom data-* attrs
  3558. data = dataAttr( elem, key );
  3559. if ( data !== undefined ) {
  3560. return data;
  3561. }
  3562. // We tried really hard, but the data doesn't exist.
  3563. return;
  3564. }
  3565. // Set the data...
  3566. this.each( function() {
  3567. // We always store the camelCased key
  3568. dataUser.set( this, key, value );
  3569. } );
  3570. }, null, value, arguments.length > 1, null, true );
  3571. },
  3572. removeData: function( key ) {
  3573. return this.each( function() {
  3574. dataUser.remove( this, key );
  3575. } );
  3576. }
  3577. } );
  3578. jQuery.extend( {
  3579. queue: function( elem, type, data ) {
  3580. var queue;
  3581. if ( elem ) {
  3582. type = ( type || "fx" ) + "queue";
  3583. queue = dataPriv.get( elem, type );
  3584. // Speed up dequeue by getting out quickly if this is just a lookup
  3585. if ( data ) {
  3586. if ( !queue || Array.isArray( data ) ) {
  3587. queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
  3588. } else {
  3589. queue.push( data );
  3590. }
  3591. }
  3592. return queue || [];
  3593. }
  3594. },
  3595. dequeue: function( elem, type ) {
  3596. type = type || "fx";
  3597. var queue = jQuery.queue( elem, type ),
  3598. startLength = queue.length,
  3599. fn = queue.shift(),
  3600. hooks = jQuery._queueHooks( elem, type ),
  3601. next = function() {
  3602. jQuery.dequeue( elem, type );
  3603. };
  3604. // If the fx queue is dequeued, always remove the progress sentinel
  3605. if ( fn === "inprogress" ) {
  3606. fn = queue.shift();
  3607. startLength--;
  3608. }
  3609. if ( fn ) {
  3610. // Add a progress sentinel to prevent the fx queue from being
  3611. // automatically dequeued
  3612. if ( type === "fx" ) {
  3613. queue.unshift( "inprogress" );
  3614. }
  3615. // Clear up the last queue stop function
  3616. delete hooks.stop;
  3617. fn.call( elem, next, hooks );
  3618. }
  3619. if ( !startLength && hooks ) {
  3620. hooks.empty.fire();
  3621. }
  3622. },
  3623. // Not public - generate a queueHooks object, or return the current one
  3624. _queueHooks: function( elem, type ) {
  3625. var key = type + "queueHooks";
  3626. return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
  3627. empty: jQuery.Callbacks( "once memory" ).add( function() {
  3628. dataPriv.remove( elem, [ type + "queue", key ] );
  3629. } )
  3630. } );
  3631. }
  3632. } );
  3633. jQuery.fn.extend( {
  3634. queue: function( type, data ) {
  3635. var setter = 2;
  3636. if ( typeof type !== "string" ) {
  3637. data = type;
  3638. type = "fx";
  3639. setter--;
  3640. }
  3641. if ( arguments.length < setter ) {
  3642. return jQuery.queue( this[ 0 ], type );
  3643. }
  3644. return data === undefined ?
  3645. this :
  3646. this.each( function() {
  3647. var queue = jQuery.queue( this, type, data );
  3648. // Ensure a hooks for this queue
  3649. jQuery._queueHooks( this, type );
  3650. if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
  3651. jQuery.dequeue( this, type );
  3652. }
  3653. } );
  3654. },
  3655. dequeue: function( type ) {
  3656. return this.each( function() {
  3657. jQuery.dequeue( this, type );
  3658. } );
  3659. },
  3660. clearQueue: function( type ) {
  3661. return this.queue( type || "fx", [] );
  3662. },
  3663. // Get a promise resolved when queues of a certain type
  3664. // are emptied (fx is the type by default)
  3665. promise: function( type, obj ) {
  3666. var tmp,
  3667. count = 1,
  3668. defer = jQuery.Deferred(),
  3669. elements = this,
  3670. i = this.length,
  3671. resolve = function() {
  3672. if ( !( --count ) ) {
  3673. defer.resolveWith( elements, [ elements ] );
  3674. }
  3675. };
  3676. if ( typeof type !== "string" ) {
  3677. obj = type;
  3678. type = undefined;
  3679. }
  3680. type = type || "fx";
  3681. while ( i-- ) {
  3682. tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
  3683. if ( tmp && tmp.empty ) {
  3684. count++;
  3685. tmp.empty.add( resolve );
  3686. }
  3687. }
  3688. resolve();
  3689. return defer.promise( obj );
  3690. }
  3691. } );
  3692. var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
  3693. var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
  3694. var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
  3695. var isHiddenWithinTree = function( elem, el ) {
  3696. // isHiddenWithinTree might be called from jQuery#filter function;
  3697. // in that case, element will be second argument
  3698. elem = el || elem;
  3699. // Inline style trumps all
  3700. return elem.style.display === "none" ||
  3701. elem.style.display === "" &&
  3702. // Otherwise, check computed style
  3703. // Support: Firefox <=43 - 45
  3704. // Disconnected elements can have computed display: none, so first confirm that elem is
  3705. // in the document.
  3706. jQuery.contains( elem.ownerDocument, elem ) &&
  3707. jQuery.css( elem, "display" ) === "none";
  3708. };
  3709. var swap = function( elem, options, callback, args ) {
  3710. var ret, name,
  3711. old = {};
  3712. // Remember the old values, and insert the new ones
  3713. for ( name in options ) {
  3714. old[ name ] = elem.style[ name ];
  3715. elem.style[ name ] = options[ name ];
  3716. }
  3717. ret = callback.apply( elem, args || [] );
  3718. // Revert the old values
  3719. for ( name in options ) {
  3720. elem.style[ name ] = old[ name ];
  3721. }
  3722. return ret;
  3723. };
  3724. function adjustCSS( elem, prop, valueParts, tween ) {
  3725. var adjusted,
  3726. scale = 1,
  3727. maxIterations = 20,
  3728. currentValue = tween ?
  3729. function() {
  3730. return tween.cur();
  3731. } :
  3732. function() {
  3733. return jQuery.css( elem, prop, "" );
  3734. },
  3735. initial = currentValue(),
  3736. unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
  3737. // Starting value computation is required for potential unit mismatches
  3738. initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
  3739. rcssNum.exec( jQuery.css( elem, prop ) );
  3740. if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
  3741. // Trust units reported by jQuery.css
  3742. unit = unit || initialInUnit[ 3 ];
  3743. // Make sure we update the tween properties later on
  3744. valueParts = valueParts || [];
  3745. // Iteratively approximate from a nonzero starting point
  3746. initialInUnit = +initial || 1;
  3747. do {
  3748. // If previous iteration zeroed out, double until we get *something*.
  3749. // Use string for doubling so we don't accidentally see scale as unchanged below
  3750. scale = scale || ".5";
  3751. // Adjust and apply
  3752. initialInUnit = initialInUnit / scale;
  3753. jQuery.style( elem, prop, initialInUnit + unit );
  3754. // Update scale, tolerating zero or NaN from tween.cur()
  3755. // Break the loop if scale is unchanged or perfect, or if we've just had enough.
  3756. } while (
  3757. scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
  3758. );
  3759. }
  3760. if ( valueParts ) {
  3761. initialInUnit = +initialInUnit || +initial || 0;
  3762. // Apply relative offset (+=/-=) if specified
  3763. adjusted = valueParts[ 1 ] ?
  3764. initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
  3765. +valueParts[ 2 ];
  3766. if ( tween ) {
  3767. tween.unit = unit;
  3768. tween.start = initialInUnit;
  3769. tween.end = adjusted;
  3770. }
  3771. }
  3772. return adjusted;
  3773. }
  3774. var defaultDisplayMap = {};
  3775. function getDefaultDisplay( elem ) {
  3776. var temp,
  3777. doc = elem.ownerDocument,
  3778. nodeName = elem.nodeName,
  3779. display = defaultDisplayMap[ nodeName ];
  3780. if ( display ) {
  3781. return display;
  3782. }
  3783. temp = doc.body.appendChild( doc.createElement( nodeName ) );
  3784. display = jQuery.css( temp, "display" );
  3785. temp.parentNode.removeChild( temp );
  3786. if ( display === "none" ) {
  3787. display = "block";
  3788. }
  3789. defaultDisplayMap[ nodeName ] = display;
  3790. return display;
  3791. }
  3792. function showHide( elements, show ) {
  3793. var display, elem,
  3794. values = [],
  3795. index = 0,
  3796. length = elements.length;
  3797. // Determine new display value for elements that need to change
  3798. for ( ; index < length; index++ ) {
  3799. elem = elements[ index ];
  3800. if ( !elem.style ) {
  3801. continue;
  3802. }
  3803. display = elem.style.display;
  3804. if ( show ) {
  3805. // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
  3806. // check is required in this first loop unless we have a nonempty display value (either
  3807. // inline or about-to-be-restored)
  3808. if ( display === "none" ) {
  3809. values[ index ] = dataPriv.get( elem, "display" ) || null;
  3810. if ( !values[ index ] ) {
  3811. elem.style.display = "";
  3812. }
  3813. }
  3814. if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
  3815. values[ index ] = getDefaultDisplay( elem );
  3816. }
  3817. } else {
  3818. if ( display !== "none" ) {
  3819. values[ index ] = "none";
  3820. // Remember what we're overwriting
  3821. dataPriv.set( elem, "display", display );
  3822. }
  3823. }
  3824. }
  3825. // Set the display of the elements in a second loop to avoid constant reflow
  3826. for ( index = 0; index < length; index++ ) {
  3827. if ( values[ index ] != null ) {
  3828. elements[ index ].style.display = values[ index ];
  3829. }
  3830. }
  3831. return elements;
  3832. }
  3833. jQuery.fn.extend( {
  3834. show: function() {
  3835. return showHide( this, true );
  3836. },
  3837. hide: function() {
  3838. return showHide( this );
  3839. },
  3840. toggle: function( state ) {
  3841. if ( typeof state === "boolean" ) {
  3842. return state ? this.show() : this.hide();
  3843. }
  3844. return this.each( function() {
  3845. if ( isHiddenWithinTree( this ) ) {
  3846. jQuery( this ).show();
  3847. } else {
  3848. jQuery( this ).hide();
  3849. }
  3850. } );
  3851. }
  3852. } );
  3853. var rcheckableType = ( /^(?:checkbox|radio)$/i );
  3854. var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
  3855. var rscriptType = ( /^$|\/(?:java|ecma)script/i );
  3856. // We have to close these tags to support XHTML (#13200)
  3857. var wrapMap = {
  3858. // Support: IE <=9 only
  3859. option: [ 1, "<select multiple='multiple'>", "</select>" ],
  3860. // XHTML parsers do not magically insert elements in the
  3861. // same way that tag soup parsers do. So we cannot shorten
  3862. // this by omitting <tbody> or other required elements.
  3863. thead: [ 1, "<table>", "</table>" ],
  3864. col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
  3865. tr: [ 2, "<table><tbody>", "</tbody></table>" ],
  3866. td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
  3867. _default: [ 0, "", "" ]
  3868. };
  3869. // Support: IE <=9 only
  3870. wrapMap.optgroup = wrapMap.option;
  3871. wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
  3872. wrapMap.th = wrapMap.td;
  3873. function getAll( context, tag ) {
  3874. // Support: IE <=9 - 11 only
  3875. // Use typeof to avoid zero-argument method invocation on host objects (#15151)
  3876. var ret;
  3877. if ( typeof context.getElementsByTagName !== "undefined" ) {
  3878. ret = context.getElementsByTagName( tag || "*" );
  3879. } else if ( typeof context.querySelectorAll !== "undefined" ) {
  3880. ret = context.querySelectorAll( tag || "*" );
  3881. } else {
  3882. ret = [];
  3883. }
  3884. if ( tag === undefined || tag && nodeName( context, tag ) ) {
  3885. return jQuery.merge( [ context ], ret );
  3886. }
  3887. return ret;
  3888. }
  3889. // Mark scripts as having already been evaluated
  3890. function setGlobalEval( elems, refElements ) {
  3891. var i = 0,
  3892. l = elems.length;
  3893. for ( ; i < l; i++ ) {
  3894. dataPriv.set(
  3895. elems[ i ],
  3896. "globalEval",
  3897. !refElements || dataPriv.get( refElements[ i ], "globalEval" )
  3898. );
  3899. }
  3900. }
  3901. var rhtml = /<|&#?\w+;/;
  3902. function buildFragment( elems, context, scripts, selection, ignored ) {
  3903. var elem, tmp, tag, wrap, contains, j,
  3904. fragment = context.createDocumentFragment(),
  3905. nodes = [],
  3906. i = 0,
  3907. l = elems.length;
  3908. for ( ; i < l; i++ ) {
  3909. elem = elems[ i ];
  3910. if ( elem || elem === 0 ) {
  3911. // Add nodes directly
  3912. if ( jQuery.type( elem ) === "object" ) {
  3913. // Support: Android <=4.0 only, PhantomJS 1 only
  3914. // push.apply(_, arraylike) throws on ancient WebKit
  3915. jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
  3916. // Convert non-html into a text node
  3917. } else if ( !rhtml.test( elem ) ) {
  3918. nodes.push( context.createTextNode( elem ) );
  3919. // Convert html into DOM nodes
  3920. } else {
  3921. tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
  3922. // Deserialize a standard representation
  3923. tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
  3924. wrap = wrapMap[ tag ] || wrapMap._default;
  3925. tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
  3926. // Descend through wrappers to the right content
  3927. j = wrap[ 0 ];
  3928. while ( j-- ) {
  3929. tmp = tmp.lastChild;
  3930. }
  3931. // Support: Android <=4.0 only, PhantomJS 1 only
  3932. // push.apply(_, arraylike) throws on ancient WebKit
  3933. jQuery.merge( nodes, tmp.childNodes );
  3934. // Remember the top-level container
  3935. tmp = fragment.firstChild;
  3936. // Ensure the created nodes are orphaned (#12392)
  3937. tmp.textContent = "";
  3938. }
  3939. }
  3940. }
  3941. // Remove wrapper from fragment
  3942. fragment.textContent = "";
  3943. i = 0;
  3944. while ( ( elem = nodes[ i++ ] ) ) {
  3945. // Skip elements already in the context collection (trac-4087)
  3946. if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
  3947. if ( ignored ) {
  3948. ignored.push( elem );
  3949. }
  3950. continue;
  3951. }
  3952. contains = jQuery.contains( elem.ownerDocument, elem );
  3953. // Append to fragment
  3954. tmp = getAll( fragment.appendChild( elem ), "script" );
  3955. // Preserve script evaluation history
  3956. if ( contains ) {
  3957. setGlobalEval( tmp );
  3958. }
  3959. // Capture executables
  3960. if ( scripts ) {
  3961. j = 0;
  3962. while ( ( elem = tmp[ j++ ] ) ) {
  3963. if ( rscriptType.test( elem.type || "" ) ) {
  3964. scripts.push( elem );
  3965. }
  3966. }
  3967. }
  3968. }
  3969. return fragment;
  3970. }
  3971. ( function() {
  3972. var fragment = document.createDocumentFragment(),
  3973. div = fragment.appendChild( document.createElement( "div" ) ),
  3974. input = document.createElement( "input" );
  3975. // Support: Android 4.0 - 4.3 only
  3976. // Check state lost if the name is set (#11217)
  3977. // Support: Windows Web Apps (WWA)
  3978. // `name` and `type` must use .setAttribute for WWA (#14901)
  3979. input.setAttribute( "type", "radio" );
  3980. input.setAttribute( "checked", "checked" );
  3981. input.setAttribute( "name", "t" );
  3982. div.appendChild( input );
  3983. // Support: Android <=4.1 only
  3984. // Older WebKit doesn't clone checked state correctly in fragments
  3985. support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
  3986. // Support: IE <=11 only
  3987. // Make sure textarea (and checkbox) defaultValue is properly cloned
  3988. div.innerHTML = "<textarea>x</textarea>";
  3989. support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
  3990. } )();
  3991. var documentElement = document.documentElement;
  3992. var
  3993. rkeyEvent = /^key/,
  3994. rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
  3995. rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
  3996. function returnTrue() {
  3997. return true;
  3998. }
  3999. function returnFalse() {
  4000. return false;
  4001. }
  4002. // Support: IE <=9 only
  4003. // See #13393 for more info
  4004. function safeActiveElement() {
  4005. try {
  4006. return document.activeElement;
  4007. } catch ( err ) { }
  4008. }
  4009. function on( elem, types, selector, data, fn, one ) {
  4010. var origFn, type;
  4011. // Types can be a map of types/handlers
  4012. if ( typeof types === "object" ) {
  4013. // ( types-Object, selector, data )
  4014. if ( typeof selector !== "string" ) {
  4015. // ( types-Object, data )
  4016. data = data || selector;
  4017. selector = undefined;
  4018. }
  4019. for ( type in types ) {
  4020. on( elem, type, selector, data, types[ type ], one );
  4021. }
  4022. return elem;
  4023. }
  4024. if ( data == null && fn == null ) {
  4025. // ( types, fn )
  4026. fn = selector;
  4027. data = selector = undefined;
  4028. } else if ( fn == null ) {
  4029. if ( typeof selector === "string" ) {
  4030. // ( types, selector, fn )
  4031. fn = data;
  4032. data = undefined;
  4033. } else {
  4034. // ( types, data, fn )
  4035. fn = data;
  4036. data = selector;
  4037. selector = undefined;
  4038. }
  4039. }
  4040. if ( fn === false ) {
  4041. fn = returnFalse;
  4042. } else if ( !fn ) {
  4043. return elem;
  4044. }
  4045. if ( one === 1 ) {
  4046. origFn = fn;
  4047. fn = function( event ) {
  4048. // Can use an empty set, since event contains the info
  4049. jQuery().off( event );
  4050. return origFn.apply( this, arguments );
  4051. };
  4052. // Use same guid so caller can remove using origFn
  4053. fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
  4054. }
  4055. return elem.each( function() {
  4056. jQuery.event.add( this, types, fn, data, selector );
  4057. } );
  4058. }
  4059. /*
  4060. * Helper functions for managing events -- not part of the public interface.
  4061. * Props to Dean Edwards' addEvent library for many of the ideas.
  4062. */
  4063. jQuery.event = {
  4064. global: {},
  4065. add: function( elem, types, handler, data, selector ) {
  4066. var handleObjIn, eventHandle, tmp,
  4067. events, t, handleObj,
  4068. special, handlers, type, namespaces, origType,
  4069. elemData = dataPriv.get( elem );
  4070. // Don't attach events to noData or text/comment nodes (but allow plain objects)
  4071. if ( !elemData ) {
  4072. return;
  4073. }
  4074. // Caller can pass in an object of custom data in lieu of the handler
  4075. if ( handler.handler ) {
  4076. handleObjIn = handler;
  4077. handler = handleObjIn.handler;
  4078. selector = handleObjIn.selector;
  4079. }
  4080. // Ensure that invalid selectors throw exceptions at attach time
  4081. // Evaluate against documentElement in case elem is a non-element node (e.g., document)
  4082. if ( selector ) {
  4083. jQuery.find.matchesSelector( documentElement, selector );
  4084. }
  4085. // Make sure that the handler has a unique ID, used to find/remove it later
  4086. if ( !handler.guid ) {
  4087. handler.guid = jQuery.guid++;
  4088. }
  4089. // Init the element's event structure and main handler, if this is the first
  4090. if ( !( events = elemData.events ) ) {
  4091. events = elemData.events = {};
  4092. }
  4093. if ( !( eventHandle = elemData.handle ) ) {
  4094. eventHandle = elemData.handle = function( e ) {
  4095. // Discard the second event of a jQuery.event.trigger() and
  4096. // when an event is called after a page has unloaded
  4097. return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
  4098. jQuery.event.dispatch.apply( elem, arguments ) : undefined;
  4099. };
  4100. }
  4101. // Handle multiple events separated by a space
  4102. types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
  4103. t = types.length;
  4104. while ( t-- ) {
  4105. tmp = rtypenamespace.exec( types[ t ] ) || [];
  4106. type = origType = tmp[ 1 ];
  4107. namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
  4108. // There *must* be a type, no attaching namespace-only handlers
  4109. if ( !type ) {
  4110. continue;
  4111. }
  4112. // If event changes its type, use the special event handlers for the changed type
  4113. special = jQuery.event.special[ type ] || {};
  4114. // If selector defined, determine special event api type, otherwise given type
  4115. type = ( selector ? special.delegateType : special.bindType ) || type;
  4116. // Update special based on newly reset type
  4117. special = jQuery.event.special[ type ] || {};
  4118. // handleObj is passed to all event handlers
  4119. handleObj = jQuery.extend( {
  4120. type: type,
  4121. origType: origType,
  4122. data: data,
  4123. handler: handler,
  4124. guid: handler.guid,
  4125. selector: selector,
  4126. needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
  4127. namespace: namespaces.join( "." )
  4128. }, handleObjIn );
  4129. // Init the event handler queue if we're the first
  4130. if ( !( handlers = events[ type ] ) ) {
  4131. handlers = events[ type ] = [];
  4132. handlers.delegateCount = 0;
  4133. // Only use addEventListener if the special events handler returns false
  4134. if ( !special.setup ||
  4135. special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
  4136. if ( elem.addEventListener ) {
  4137. elem.addEventListener( type, eventHandle );
  4138. }
  4139. }
  4140. }
  4141. if ( special.add ) {
  4142. special.add.call( elem, handleObj );
  4143. if ( !handleObj.handler.guid ) {
  4144. handleObj.handler.guid = handler.guid;
  4145. }
  4146. }
  4147. // Add to the element's handler list, delegates in front
  4148. if ( selector ) {
  4149. handlers.splice( handlers.delegateCount++, 0, handleObj );
  4150. } else {
  4151. handlers.push( handleObj );
  4152. }
  4153. // Keep track of which events have ever been used, for event optimization
  4154. jQuery.event.global[ type ] = true;
  4155. }
  4156. },
  4157. // Detach an event or set of events from an element
  4158. remove: function( elem, types, handler, selector, mappedTypes ) {
  4159. var j, origCount, tmp,
  4160. events, t, handleObj,
  4161. special, handlers, type, namespaces, origType,
  4162. elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
  4163. if ( !elemData || !( events = elemData.events ) ) {
  4164. return;
  4165. }
  4166. // Once for each type.namespace in types; type may be omitted
  4167. types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
  4168. t = types.length;
  4169. while ( t-- ) {
  4170. tmp = rtypenamespace.exec( types[ t ] ) || [];
  4171. type = origType = tmp[ 1 ];
  4172. namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
  4173. // Unbind all events (on this namespace, if provided) for the element
  4174. if ( !type ) {
  4175. for ( type in events ) {
  4176. jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
  4177. }
  4178. continue;
  4179. }
  4180. special = jQuery.event.special[ type ] || {};
  4181. type = ( selector ? special.delegateType : special.bindType ) || type;
  4182. handlers = events[ type ] || [];
  4183. tmp = tmp[ 2 ] &&
  4184. new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
  4185. // Remove matching events
  4186. origCount = j = handlers.length;
  4187. while ( j-- ) {
  4188. handleObj = handlers[ j ];
  4189. if ( ( mappedTypes || origType === handleObj.origType ) &&
  4190. ( !handler || handler.guid === handleObj.guid ) &&
  4191. ( !tmp || tmp.test( handleObj.namespace ) ) &&
  4192. ( !selector || selector === handleObj.selector ||
  4193. selector === "**" && handleObj.selector ) ) {
  4194. handlers.splice( j, 1 );
  4195. if ( handleObj.selector ) {
  4196. handlers.delegateCount--;
  4197. }
  4198. if ( special.remove ) {
  4199. special.remove.call( elem, handleObj );
  4200. }
  4201. }
  4202. }
  4203. // Remove generic event handler if we removed something and no more handlers exist
  4204. // (avoids potential for endless recursion during removal of special event handlers)
  4205. if ( origCount && !handlers.length ) {
  4206. if ( !special.teardown ||
  4207. special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
  4208. jQuery.removeEvent( elem, type, elemData.handle );
  4209. }
  4210. delete events[ type ];
  4211. }
  4212. }
  4213. // Remove data and the expando if it's no longer used
  4214. if ( jQuery.isEmptyObject( events ) ) {
  4215. dataPriv.remove( elem, "handle events" );
  4216. }
  4217. },
  4218. dispatch: function( nativeEvent ) {
  4219. // Make a writable jQuery.Event from the native event object
  4220. var event = jQuery.event.fix( nativeEvent );
  4221. var i, j, ret, matched, handleObj, handlerQueue,
  4222. args = new Array( arguments.length ),
  4223. handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
  4224. special = jQuery.event.special[ event.type ] || {};
  4225. // Use the fix-ed jQuery.Event rather than the (read-only) native event
  4226. args[ 0 ] = event;
  4227. for ( i = 1; i < arguments.length; i++ ) {
  4228. args[ i ] = arguments[ i ];
  4229. }
  4230. event.delegateTarget = this;
  4231. // Call the preDispatch hook for the mapped type, and let it bail if desired
  4232. if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
  4233. return;
  4234. }
  4235. // Determine handlers
  4236. handlerQueue = jQuery.event.handlers.call( this, event, handlers );
  4237. // Run delegates first; they may want to stop propagation beneath us
  4238. i = 0;
  4239. while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
  4240. event.currentTarget = matched.elem;
  4241. j = 0;
  4242. while ( ( handleObj = matched.handlers[ j++ ] ) &&
  4243. !event.isImmediatePropagationStopped() ) {
  4244. // Triggered event must either 1) have no namespace, or 2) have namespace(s)
  4245. // a subset or equal to those in the bound event (both can have no namespace).
  4246. if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
  4247. event.handleObj = handleObj;
  4248. event.data = handleObj.data;
  4249. ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
  4250. handleObj.handler ).apply( matched.elem, args );
  4251. if ( ret !== undefined ) {
  4252. if ( ( event.result = ret ) === false ) {
  4253. event.preventDefault();
  4254. event.stopPropagation();
  4255. }
  4256. }
  4257. }
  4258. }
  4259. }
  4260. // Call the postDispatch hook for the mapped type
  4261. if ( special.postDispatch ) {
  4262. special.postDispatch.call( this, event );
  4263. }
  4264. return event.result;
  4265. },
  4266. handlers: function( event, handlers ) {
  4267. var i, handleObj, sel, matchedHandlers, matchedSelectors,
  4268. handlerQueue = [],
  4269. delegateCount = handlers.delegateCount,
  4270. cur = event.target;
  4271. // Find delegate handlers
  4272. if ( delegateCount &&
  4273. // Support: IE <=9
  4274. // Black-hole SVG <use> instance trees (trac-13180)
  4275. cur.nodeType &&
  4276. // Support: Firefox <=42
  4277. // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
  4278. // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
  4279. // Support: IE 11 only
  4280. // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
  4281. !( event.type === "click" && event.button >= 1 ) ) {
  4282. for ( ; cur !== this; cur = cur.parentNode || this ) {
  4283. // Don't check non-elements (#13208)
  4284. // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
  4285. if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
  4286. matchedHandlers = [];
  4287. matchedSelectors = {};
  4288. for ( i = 0; i < delegateCount; i++ ) {
  4289. handleObj = handlers[ i ];
  4290. // Don't conflict with Object.prototype properties (#13203)
  4291. sel = handleObj.selector + " ";
  4292. if ( matchedSelectors[ sel ] === undefined ) {
  4293. matchedSelectors[ sel ] = handleObj.needsContext ?
  4294. jQuery( sel, this ).index( cur ) > -1 :
  4295. jQuery.find( sel, this, null, [ cur ] ).length;
  4296. }
  4297. if ( matchedSelectors[ sel ] ) {
  4298. matchedHandlers.push( handleObj );
  4299. }
  4300. }
  4301. if ( matchedHandlers.length ) {
  4302. handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
  4303. }
  4304. }
  4305. }
  4306. }
  4307. // Add the remaining (directly-bound) handlers
  4308. cur = this;
  4309. if ( delegateCount < handlers.length ) {
  4310. handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
  4311. }
  4312. return handlerQueue;
  4313. },
  4314. addProp: function( name, hook ) {
  4315. Object.defineProperty( jQuery.Event.prototype, name, {
  4316. enumerable: true,
  4317. configurable: true,
  4318. get: jQuery.isFunction( hook ) ?
  4319. function() {
  4320. if ( this.originalEvent ) {
  4321. return hook( this.originalEvent );
  4322. }
  4323. } :
  4324. function() {
  4325. if ( this.originalEvent ) {
  4326. return this.originalEvent[ name ];
  4327. }
  4328. },
  4329. set: function( value ) {
  4330. Object.defineProperty( this, name, {
  4331. enumerable: true,
  4332. configurable: true,
  4333. writable: true,
  4334. value: value
  4335. } );
  4336. }
  4337. } );
  4338. },
  4339. fix: function( originalEvent ) {
  4340. return originalEvent[ jQuery.expando ] ?
  4341. originalEvent :
  4342. new jQuery.Event( originalEvent );
  4343. },
  4344. special: {
  4345. load: {
  4346. // Prevent triggered image.load events from bubbling to window.load
  4347. noBubble: true
  4348. },
  4349. focus: {
  4350. // Fire native event if possible so blur/focus sequence is correct
  4351. trigger: function() {
  4352. if ( this !== safeActiveElement() && this.focus ) {
  4353. this.focus();
  4354. return false;
  4355. }
  4356. },
  4357. delegateType: "focusin"
  4358. },
  4359. blur: {
  4360. trigger: function() {
  4361. if ( this === safeActiveElement() && this.blur ) {
  4362. this.blur();
  4363. return false;
  4364. }
  4365. },
  4366. delegateType: "focusout"
  4367. },
  4368. click: {
  4369. // For checkbox, fire native event so checked state will be right
  4370. trigger: function() {
  4371. if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
  4372. this.click();
  4373. return false;
  4374. }
  4375. },
  4376. // For cross-browser consistency, don't fire native .click() on links
  4377. _default: function( event ) {
  4378. return nodeName( event.target, "a" );
  4379. }
  4380. },
  4381. beforeunload: {
  4382. postDispatch: function( event ) {
  4383. // Support: Firefox 20+
  4384. // Firefox doesn't alert if the returnValue field is not set.
  4385. if ( event.result !== undefined && event.originalEvent ) {
  4386. event.originalEvent.returnValue = event.result;
  4387. }
  4388. }
  4389. }
  4390. }
  4391. };
  4392. jQuery.removeEvent = function( elem, type, handle ) {
  4393. // This "if" is needed for plain objects
  4394. if ( elem.removeEventListener ) {
  4395. elem.removeEventListener( type, handle );
  4396. }
  4397. };
  4398. jQuery.Event = function( src, props ) {
  4399. // Allow instantiation without the 'new' keyword
  4400. if ( !( this instanceof jQuery.Event ) ) {
  4401. return new jQuery.Event( src, props );
  4402. }
  4403. // Event object
  4404. if ( src && src.type ) {
  4405. this.originalEvent = src;
  4406. this.type = src.type;
  4407. // Events bubbling up the document may have been marked as prevented
  4408. // by a handler lower down the tree; reflect the correct value.
  4409. this.isDefaultPrevented = src.defaultPrevented ||
  4410. src.defaultPrevented === undefined &&
  4411. // Support: Android <=2.3 only
  4412. src.returnValue === false ?
  4413. returnTrue :
  4414. returnFalse;
  4415. // Create target properties
  4416. // Support: Safari <=6 - 7 only
  4417. // Target should not be a text node (#504, #13143)
  4418. this.target = ( src.target && src.target.nodeType === 3 ) ?
  4419. src.target.parentNode :
  4420. src.target;
  4421. this.currentTarget = src.currentTarget;
  4422. this.relatedTarget = src.relatedTarget;
  4423. // Event type
  4424. } else {
  4425. this.type = src;
  4426. }
  4427. // Put explicitly provided properties onto the event object
  4428. if ( props ) {
  4429. jQuery.extend( this, props );
  4430. }
  4431. // Create a timestamp if incoming event doesn't have one
  4432. this.timeStamp = src && src.timeStamp || jQuery.now();
  4433. // Mark it as fixed
  4434. this[ jQuery.expando ] = true;
  4435. };
  4436. // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
  4437. // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
  4438. jQuery.Event.prototype = {
  4439. constructor: jQuery.Event,
  4440. isDefaultPrevented: returnFalse,
  4441. isPropagationStopped: returnFalse,
  4442. isImmediatePropagationStopped: returnFalse,
  4443. isSimulated: false,
  4444. preventDefault: function() {
  4445. var e = this.originalEvent;
  4446. this.isDefaultPrevented = returnTrue;
  4447. if ( e && !this.isSimulated ) {
  4448. e.preventDefault();
  4449. }
  4450. },
  4451. stopPropagation: function() {
  4452. var e = this.originalEvent;
  4453. this.isPropagationStopped = returnTrue;
  4454. if ( e && !this.isSimulated ) {
  4455. e.stopPropagation();
  4456. }
  4457. },
  4458. stopImmediatePropagation: function() {
  4459. var e = this.originalEvent;
  4460. this.isImmediatePropagationStopped = returnTrue;
  4461. if ( e && !this.isSimulated ) {
  4462. e.stopImmediatePropagation();
  4463. }
  4464. this.stopPropagation();
  4465. }
  4466. };
  4467. // Includes all common event props including KeyEvent and MouseEvent specific props
  4468. jQuery.each( {
  4469. altKey: true,
  4470. bubbles: true,
  4471. cancelable: true,
  4472. changedTouches: true,
  4473. ctrlKey: true,
  4474. detail: true,
  4475. eventPhase: true,
  4476. metaKey: true,
  4477. pageX: true,
  4478. pageY: true,
  4479. shiftKey: true,
  4480. view: true,
  4481. "char": true,
  4482. charCode: true,
  4483. key: true,
  4484. keyCode: true,
  4485. button: true,
  4486. buttons: true,
  4487. clientX: true,
  4488. clientY: true,
  4489. offsetX: true,
  4490. offsetY: true,
  4491. pointerId: true,
  4492. pointerType: true,
  4493. screenX: true,
  4494. screenY: true,
  4495. targetTouches: true,
  4496. toElement: true,
  4497. touches: true,
  4498. which: function( event ) {
  4499. var button = event.button;
  4500. // Add which for key events
  4501. if ( event.which == null && rkeyEvent.test( event.type ) ) {
  4502. return event.charCode != null ? event.charCode : event.keyCode;
  4503. }
  4504. // Add which for click: 1 === left; 2 === middle; 3 === right
  4505. if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
  4506. if ( button & 1 ) {
  4507. return 1;
  4508. }
  4509. if ( button & 2 ) {
  4510. return 3;
  4511. }
  4512. if ( button & 4 ) {
  4513. return 2;
  4514. }
  4515. return 0;
  4516. }
  4517. return event.which;
  4518. }
  4519. }, jQuery.event.addProp );
  4520. // Create mouseenter/leave events using mouseover/out and event-time checks
  4521. // so that event delegation works in jQuery.
  4522. // Do the same for pointerenter/pointerleave and pointerover/pointerout
  4523. //
  4524. // Support: Safari 7 only
  4525. // Safari sends mouseenter too often; see:
  4526. // https://bugs.chromium.org/p/chromium/issues/detail?id=470258
  4527. // for the description of the bug (it existed in older Chrome versions as well).
  4528. jQuery.each( {
  4529. mouseenter: "mouseover",
  4530. mouseleave: "mouseout",
  4531. pointerenter: "pointerover",
  4532. pointerleave: "pointerout"
  4533. }, function( orig, fix ) {
  4534. jQuery.event.special[ orig ] = {
  4535. delegateType: fix,
  4536. bindType: fix,
  4537. handle: function( event ) {
  4538. var ret,
  4539. target = this,
  4540. related = event.relatedTarget,
  4541. handleObj = event.handleObj;
  4542. // For mouseenter/leave call the handler if related is outside the target.
  4543. // NB: No relatedTarget if the mouse left/entered the browser window
  4544. if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
  4545. event.type = handleObj.origType;
  4546. ret = handleObj.handler.apply( this, arguments );
  4547. event.type = fix;
  4548. }
  4549. return ret;
  4550. }
  4551. };
  4552. } );
  4553. jQuery.fn.extend( {
  4554. on: function( types, selector, data, fn ) {
  4555. return on( this, types, selector, data, fn );
  4556. },
  4557. one: function( types, selector, data, fn ) {
  4558. return on( this, types, selector, data, fn, 1 );
  4559. },
  4560. off: function( types, selector, fn ) {
  4561. var handleObj, type;
  4562. if ( types && types.preventDefault && types.handleObj ) {
  4563. // ( event ) dispatched jQuery.Event
  4564. handleObj = types.handleObj;
  4565. jQuery( types.delegateTarget ).off(
  4566. handleObj.namespace ?
  4567. handleObj.origType + "." + handleObj.namespace :
  4568. handleObj.origType,
  4569. handleObj.selector,
  4570. handleObj.handler
  4571. );
  4572. return this;
  4573. }
  4574. if ( typeof types === "object" ) {
  4575. // ( types-object [, selector] )
  4576. for ( type in types ) {
  4577. this.off( type, selector, types[ type ] );
  4578. }
  4579. return this;
  4580. }
  4581. if ( selector === false || typeof selector === "function" ) {
  4582. // ( types [, fn] )
  4583. fn = selector;
  4584. selector = undefined;
  4585. }
  4586. if ( fn === false ) {
  4587. fn = returnFalse;
  4588. }
  4589. return this.each( function() {
  4590. jQuery.event.remove( this, types, fn, selector );
  4591. } );
  4592. }
  4593. } );
  4594. var
  4595. /* eslint-disable max-len */
  4596. // See https://github.com/eslint/eslint/issues/3229
  4597. rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
  4598. /* eslint-enable */
  4599. // Support: IE <=10 - 11, Edge 12 - 13
  4600. // In IE/Edge using regex groups here causes severe slowdowns.
  4601. // See https://connect.microsoft.com/IE/feedback/details/1736512/
  4602. rnoInnerhtml = /<script|<style|<link/i,
  4603. // checked="checked" or checked
  4604. rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
  4605. rscriptTypeMasked = /^true\/(.*)/,
  4606. rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
  4607. // Prefer a tbody over its parent table for containing new rows
  4608. function manipulationTarget( elem, content ) {
  4609. if ( nodeName( elem, "table" ) &&
  4610. nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
  4611. return jQuery( ">tbody", elem )[ 0 ] || elem;
  4612. }
  4613. return elem;
  4614. }
  4615. // Replace/restore the type attribute of script elements for safe DOM manipulation
  4616. function disableScript( elem ) {
  4617. elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
  4618. return elem;
  4619. }
  4620. function restoreScript( elem ) {
  4621. var match = rscriptTypeMasked.exec( elem.type );
  4622. if ( match ) {
  4623. elem.type = match[ 1 ];
  4624. } else {
  4625. elem.removeAttribute( "type" );
  4626. }
  4627. return elem;
  4628. }
  4629. function cloneCopyEvent( src, dest ) {
  4630. var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
  4631. if ( dest.nodeType !== 1 ) {
  4632. return;
  4633. }
  4634. // 1. Copy private data: events, handlers, etc.
  4635. if ( dataPriv.hasData( src ) ) {
  4636. pdataOld = dataPriv.access( src );
  4637. pdataCur = dataPriv.set( dest, pdataOld );
  4638. events = pdataOld.events;
  4639. if ( events ) {
  4640. delete pdataCur.handle;
  4641. pdataCur.events = {};
  4642. for ( type in events ) {
  4643. for ( i = 0, l = events[ type ].length; i < l; i++ ) {
  4644. jQuery.event.add( dest, type, events[ type ][ i ] );
  4645. }
  4646. }
  4647. }
  4648. }
  4649. // 2. Copy user data
  4650. if ( dataUser.hasData( src ) ) {
  4651. udataOld = dataUser.access( src );
  4652. udataCur = jQuery.extend( {}, udataOld );
  4653. dataUser.set( dest, udataCur );
  4654. }
  4655. }
  4656. // Fix IE bugs, see support tests
  4657. function fixInput( src, dest ) {
  4658. var nodeName = dest.nodeName.toLowerCase();
  4659. // Fails to persist the checked state of a cloned checkbox or radio button.
  4660. if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
  4661. dest.checked = src.checked;
  4662. // Fails to return the selected option to the default selected state when cloning options
  4663. } else if ( nodeName === "input" || nodeName === "textarea" ) {
  4664. dest.defaultValue = src.defaultValue;
  4665. }
  4666. }
  4667. function domManip( collection, args, callback, ignored ) {
  4668. // Flatten any nested arrays
  4669. args = concat.apply( [], args );
  4670. var fragment, first, scripts, hasScripts, node, doc,
  4671. i = 0,
  4672. l = collection.length,
  4673. iNoClone = l - 1,
  4674. value = args[ 0 ],
  4675. isFunction = jQuery.isFunction( value );
  4676. // We can't cloneNode fragments that contain checked, in WebKit
  4677. if ( isFunction ||
  4678. ( l > 1 && typeof value === "string" &&
  4679. !support.checkClone && rchecked.test( value ) ) ) {
  4680. return collection.each( function( index ) {
  4681. var self = collection.eq( index );
  4682. if ( isFunction ) {
  4683. args[ 0 ] = value.call( this, index, self.html() );
  4684. }
  4685. domManip( self, args, callback, ignored );
  4686. } );
  4687. }
  4688. if ( l ) {
  4689. fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
  4690. first = fragment.firstChild;
  4691. if ( fragment.childNodes.length === 1 ) {
  4692. fragment = first;
  4693. }
  4694. // Require either new content or an interest in ignored elements to invoke the callback
  4695. if ( first || ignored ) {
  4696. scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
  4697. hasScripts = scripts.length;
  4698. // Use the original fragment for the last item
  4699. // instead of the first because it can end up
  4700. // being emptied incorrectly in certain situations (#8070).
  4701. for ( ; i < l; i++ ) {
  4702. node = fragment;
  4703. if ( i !== iNoClone ) {
  4704. node = jQuery.clone( node, true, true );
  4705. // Keep references to cloned scripts for later restoration
  4706. if ( hasScripts ) {
  4707. // Support: Android <=4.0 only, PhantomJS 1 only
  4708. // push.apply(_, arraylike) throws on ancient WebKit
  4709. jQuery.merge( scripts, getAll( node, "script" ) );
  4710. }
  4711. }
  4712. callback.call( collection[ i ], node, i );
  4713. }
  4714. if ( hasScripts ) {
  4715. doc = scripts[ scripts.length - 1 ].ownerDocument;
  4716. // Reenable scripts
  4717. jQuery.map( scripts, restoreScript );
  4718. // Evaluate executable scripts on first document insertion
  4719. for ( i = 0; i < hasScripts; i++ ) {
  4720. node = scripts[ i ];
  4721. if ( rscriptType.test( node.type || "" ) &&
  4722. !dataPriv.access( node, "globalEval" ) &&
  4723. jQuery.contains( doc, node ) ) {
  4724. if ( node.src ) {
  4725. // Optional AJAX dependency, but won't run scripts if not present
  4726. if ( jQuery._evalUrl ) {
  4727. jQuery._evalUrl( node.src );
  4728. }
  4729. } else {
  4730. DOMEval( node.textContent.replace( rcleanScript, "" ), doc );
  4731. }
  4732. }
  4733. }
  4734. }
  4735. }
  4736. }
  4737. return collection;
  4738. }
  4739. function remove( elem, selector, keepData ) {
  4740. var node,
  4741. nodes = selector ? jQuery.filter( selector, elem ) : elem,
  4742. i = 0;
  4743. for ( ; ( node = nodes[ i ] ) != null; i++ ) {
  4744. if ( !keepData && node.nodeType === 1 ) {
  4745. jQuery.cleanData( getAll( node ) );
  4746. }
  4747. if ( node.parentNode ) {
  4748. if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
  4749. setGlobalEval( getAll( node, "script" ) );
  4750. }
  4751. node.parentNode.removeChild( node );
  4752. }
  4753. }
  4754. return elem;
  4755. }
  4756. jQuery.extend( {
  4757. htmlPrefilter: function( html ) {
  4758. return html.replace( rxhtmlTag, "<$1></$2>" );
  4759. },
  4760. clone: function( elem, dataAndEvents, deepDataAndEvents ) {
  4761. var i, l, srcElements, destElements,
  4762. clone = elem.cloneNode( true ),
  4763. inPage = jQuery.contains( elem.ownerDocument, elem );
  4764. // Fix IE cloning issues
  4765. if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
  4766. !jQuery.isXMLDoc( elem ) ) {
  4767. // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
  4768. destElements = getAll( clone );
  4769. srcElements = getAll( elem );
  4770. for ( i = 0, l = srcElements.length; i < l; i++ ) {
  4771. fixInput( srcElements[ i ], destElements[ i ] );
  4772. }
  4773. }
  4774. // Copy the events from the original to the clone
  4775. if ( dataAndEvents ) {
  4776. if ( deepDataAndEvents ) {
  4777. srcElements = srcElements || getAll( elem );
  4778. destElements = destElements || getAll( clone );
  4779. for ( i = 0, l = srcElements.length; i < l; i++ ) {
  4780. cloneCopyEvent( srcElements[ i ], destElements[ i ] );
  4781. }
  4782. } else {
  4783. cloneCopyEvent( elem, clone );
  4784. }
  4785. }
  4786. // Preserve script evaluation history
  4787. destElements = getAll( clone, "script" );
  4788. if ( destElements.length > 0 ) {
  4789. setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
  4790. }
  4791. // Return the cloned set
  4792. return clone;
  4793. },
  4794. cleanData: function( elems ) {
  4795. var data, elem, type,
  4796. special = jQuery.event.special,
  4797. i = 0;
  4798. for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
  4799. if ( acceptData( elem ) ) {
  4800. if ( ( data = elem[ dataPriv.expando ] ) ) {
  4801. if ( data.events ) {
  4802. for ( type in data.events ) {
  4803. if ( special[ type ] ) {
  4804. jQuery.event.remove( elem, type );
  4805. // This is a shortcut to avoid jQuery.event.remove's overhead
  4806. } else {
  4807. jQuery.removeEvent( elem, type, data.handle );
  4808. }
  4809. }
  4810. }
  4811. // Support: Chrome <=35 - 45+
  4812. // Assign undefined instead of using delete, see Data#remove
  4813. elem[ dataPriv.expando ] = undefined;
  4814. }
  4815. if ( elem[ dataUser.expando ] ) {
  4816. // Support: Chrome <=35 - 45+
  4817. // Assign undefined instead of using delete, see Data#remove
  4818. elem[ dataUser.expando ] = undefined;
  4819. }
  4820. }
  4821. }
  4822. }
  4823. } );
  4824. jQuery.fn.extend( {
  4825. detach: function( selector ) {
  4826. return remove( this, selector, true );
  4827. },
  4828. remove: function( selector ) {
  4829. return remove( this, selector );
  4830. },
  4831. text: function( value ) {
  4832. return access( this, function( value ) {
  4833. return value === undefined ?
  4834. jQuery.text( this ) :
  4835. this.empty().each( function() {
  4836. if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  4837. this.textContent = value;
  4838. }
  4839. } );
  4840. }, null, value, arguments.length );
  4841. },
  4842. append: function() {
  4843. return domManip( this, arguments, function( elem ) {
  4844. if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  4845. var target = manipulationTarget( this, elem );
  4846. target.appendChild( elem );
  4847. }
  4848. } );
  4849. },
  4850. prepend: function() {
  4851. return domManip( this, arguments, function( elem ) {
  4852. if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  4853. var target = manipulationTarget( this, elem );
  4854. target.insertBefore( elem, target.firstChild );
  4855. }
  4856. } );
  4857. },
  4858. before: function() {
  4859. return domManip( this, arguments, function( elem ) {
  4860. if ( this.parentNode ) {
  4861. this.parentNode.insertBefore( elem, this );
  4862. }
  4863. } );
  4864. },
  4865. after: function() {
  4866. return domManip( this, arguments, function( elem ) {
  4867. if ( this.parentNode ) {
  4868. this.parentNode.insertBefore( elem, this.nextSibling );
  4869. }
  4870. } );
  4871. },
  4872. empty: function() {
  4873. var elem,
  4874. i = 0;
  4875. for ( ; ( elem = this[ i ] ) != null; i++ ) {
  4876. if ( elem.nodeType === 1 ) {
  4877. // Prevent memory leaks
  4878. jQuery.cleanData( getAll( elem, false ) );
  4879. // Remove any remaining nodes
  4880. elem.textContent = "";
  4881. }
  4882. }
  4883. return this;
  4884. },
  4885. clone: function( dataAndEvents, deepDataAndEvents ) {
  4886. dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
  4887. deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
  4888. return this.map( function() {
  4889. return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
  4890. } );
  4891. },
  4892. html: function( value ) {
  4893. return access( this, function( value ) {
  4894. var elem = this[ 0 ] || {},
  4895. i = 0,
  4896. l = this.length;
  4897. if ( value === undefined && elem.nodeType === 1 ) {
  4898. return elem.innerHTML;
  4899. }
  4900. // See if we can take a shortcut and just use innerHTML
  4901. if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
  4902. !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
  4903. value = jQuery.htmlPrefilter( value );
  4904. try {
  4905. for ( ; i < l; i++ ) {
  4906. elem = this[ i ] || {};
  4907. // Remove element nodes and prevent memory leaks
  4908. if ( elem.nodeType === 1 ) {
  4909. jQuery.cleanData( getAll( elem, false ) );
  4910. elem.innerHTML = value;
  4911. }
  4912. }
  4913. elem = 0;
  4914. // If using innerHTML throws an exception, use the fallback method
  4915. } catch ( e ) {}
  4916. }
  4917. if ( elem ) {
  4918. this.empty().append( value );
  4919. }
  4920. }, null, value, arguments.length );
  4921. },
  4922. replaceWith: function() {
  4923. var ignored = [];
  4924. // Make the changes, replacing each non-ignored context element with the new content
  4925. return domManip( this, arguments, function( elem ) {
  4926. var parent = this.parentNode;
  4927. if ( jQuery.inArray( this, ignored ) < 0 ) {
  4928. jQuery.cleanData( getAll( this ) );
  4929. if ( parent ) {
  4930. parent.replaceChild( elem, this );
  4931. }
  4932. }
  4933. // Force callback invocation
  4934. }, ignored );
  4935. }
  4936. } );
  4937. jQuery.each( {
  4938. appendTo: "append",
  4939. prependTo: "prepend",
  4940. insertBefore: "before",
  4941. insertAfter: "after",
  4942. replaceAll: "replaceWith"
  4943. }, function( name, original ) {
  4944. jQuery.fn[ name ] = function( selector ) {
  4945. var elems,
  4946. ret = [],
  4947. insert = jQuery( selector ),
  4948. last = insert.length - 1,
  4949. i = 0;
  4950. for ( ; i <= last; i++ ) {
  4951. elems = i === last ? this : this.clone( true );
  4952. jQuery( insert[ i ] )[ original ]( elems );
  4953. // Support: Android <=4.0 only, PhantomJS 1 only
  4954. // .get() because push.apply(_, arraylike) throws on ancient WebKit
  4955. push.apply( ret, elems.get() );
  4956. }
  4957. return this.pushStack( ret );
  4958. };
  4959. } );
  4960. var rmargin = ( /^margin/ );
  4961. var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
  4962. var getStyles = function( elem ) {
  4963. // Support: IE <=11 only, Firefox <=30 (#15098, #14150)
  4964. // IE throws on elements created in popups
  4965. // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
  4966. var view = elem.ownerDocument.defaultView;
  4967. if ( !view || !view.opener ) {
  4968. view = window;
  4969. }
  4970. return view.getComputedStyle( elem );
  4971. };
  4972. ( function() {
  4973. // Executing both pixelPosition & boxSizingReliable tests require only one layout
  4974. // so they're executed at the same time to save the second computation.
  4975. function computeStyleTests() {
  4976. // This is a singleton, we need to execute it only once
  4977. if ( !div ) {
  4978. return;
  4979. }
  4980. div.style.cssText =
  4981. "box-sizing:border-box;" +
  4982. "position:relative;display:block;" +
  4983. "margin:auto;border:1px;padding:1px;" +
  4984. "top:1%;width:50%";
  4985. div.innerHTML = "";
  4986. documentElement.appendChild( container );
  4987. var divStyle = window.getComputedStyle( div );
  4988. pixelPositionVal = divStyle.top !== "1%";
  4989. // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
  4990. reliableMarginLeftVal = divStyle.marginLeft === "2px";
  4991. boxSizingReliableVal = divStyle.width === "4px";
  4992. // Support: Android 4.0 - 4.3 only
  4993. // Some styles come back with percentage values, even though they shouldn't
  4994. div.style.marginRight = "50%";
  4995. pixelMarginRightVal = divStyle.marginRight === "4px";
  4996. documentElement.removeChild( container );
  4997. // Nullify the div so it wouldn't be stored in the memory and
  4998. // it will also be a sign that checks already performed
  4999. div = null;
  5000. }
  5001. var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
  5002. container = document.createElement( "div" ),
  5003. div = document.createElement( "div" );
  5004. // Finish early in limited (non-browser) environments
  5005. if ( !div.style ) {
  5006. return;
  5007. }
  5008. // Support: IE <=9 - 11 only
  5009. // Style of cloned element affects source element cloned (#8908)
  5010. div.style.backgroundClip = "content-box";
  5011. div.cloneNode( true ).style.backgroundClip = "";
  5012. support.clearCloneStyle = div.style.backgroundClip === "content-box";
  5013. container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
  5014. "padding:0;margin-top:1px;position:absolute";
  5015. container.appendChild( div );
  5016. jQuery.extend( support, {
  5017. pixelPosition: function() {
  5018. computeStyleTests();
  5019. return pixelPositionVal;
  5020. },
  5021. boxSizingReliable: function() {
  5022. computeStyleTests();
  5023. return boxSizingReliableVal;
  5024. },
  5025. pixelMarginRight: function() {
  5026. computeStyleTests();
  5027. return pixelMarginRightVal;
  5028. },
  5029. reliableMarginLeft: function() {
  5030. computeStyleTests();
  5031. return reliableMarginLeftVal;
  5032. }
  5033. } );
  5034. } )();
  5035. function curCSS( elem, name, computed ) {
  5036. var width, minWidth, maxWidth, ret,
  5037. // Support: Firefox 51+
  5038. // Retrieving style before computed somehow
  5039. // fixes an issue with getting wrong values
  5040. // on detached elements
  5041. style = elem.style;
  5042. computed = computed || getStyles( elem );
  5043. // getPropertyValue is needed for:
  5044. // .css('filter') (IE 9 only, #12537)
  5045. // .css('--customProperty) (#3144)
  5046. if ( computed ) {
  5047. ret = computed.getPropertyValue( name ) || computed[ name ];
  5048. if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
  5049. ret = jQuery.style( elem, name );
  5050. }
  5051. // A tribute to the "awesome hack by Dean Edwards"
  5052. // Android Browser returns percentage for some values,
  5053. // but width seems to be reliably pixels.
  5054. // This is against the CSSOM draft spec:
  5055. // https://drafts.csswg.org/cssom/#resolved-values
  5056. if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
  5057. // Remember the original values
  5058. width = style.width;
  5059. minWidth = style.minWidth;
  5060. maxWidth = style.maxWidth;
  5061. // Put in the new values to get a computed value out
  5062. style.minWidth = style.maxWidth = style.width = ret;
  5063. ret = computed.width;
  5064. // Revert the changed values
  5065. style.width = width;
  5066. style.minWidth = minWidth;
  5067. style.maxWidth = maxWidth;
  5068. }
  5069. }
  5070. return ret !== undefined ?
  5071. // Support: IE <=9 - 11 only
  5072. // IE returns zIndex value as an integer.
  5073. ret + "" :
  5074. ret;
  5075. }
  5076. function addGetHookIf( conditionFn, hookFn ) {
  5077. // Define the hook, we'll check on the first run if it's really needed.
  5078. return {
  5079. get: function() {
  5080. if ( conditionFn() ) {
  5081. // Hook not needed (or it's not possible to use it due
  5082. // to missing dependency), remove it.
  5083. delete this.get;
  5084. return;
  5085. }
  5086. // Hook needed; redefine it so that the support test is not executed again.
  5087. return ( this.get = hookFn ).apply( this, arguments );
  5088. }
  5089. };
  5090. }
  5091. var
  5092. // Swappable if display is none or starts with table
  5093. // except "table", "table-cell", or "table-caption"
  5094. // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
  5095. rdisplayswap = /^(none|table(?!-c[ea]).+)/,
  5096. rcustomProp = /^--/,
  5097. cssShow = { position: "absolute", visibility: "hidden", display: "block" },
  5098. cssNormalTransform = {
  5099. letterSpacing: "0",
  5100. fontWeight: "400"
  5101. },
  5102. cssPrefixes = [ "Webkit", "Moz", "ms" ],
  5103. emptyStyle = document.createElement( "div" ).style;
  5104. // Return a css property mapped to a potentially vendor prefixed property
  5105. function vendorPropName( name ) {
  5106. // Shortcut for names that are not vendor prefixed
  5107. if ( name in emptyStyle ) {
  5108. return name;
  5109. }
  5110. // Check for vendor prefixed names
  5111. var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
  5112. i = cssPrefixes.length;
  5113. while ( i-- ) {
  5114. name = cssPrefixes[ i ] + capName;
  5115. if ( name in emptyStyle ) {
  5116. return name;
  5117. }
  5118. }
  5119. }
  5120. // Return a property mapped along what jQuery.cssProps suggests or to
  5121. // a vendor prefixed property.
  5122. function finalPropName( name ) {
  5123. var ret = jQuery.cssProps[ name ];
  5124. if ( !ret ) {
  5125. ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
  5126. }
  5127. return ret;
  5128. }
  5129. function setPositiveNumber( elem, value, subtract ) {
  5130. // Any relative (+/-) values have already been
  5131. // normalized at this point
  5132. var matches = rcssNum.exec( value );
  5133. return matches ?
  5134. // Guard against undefined "subtract", e.g., when used as in cssHooks
  5135. Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
  5136. value;
  5137. }
  5138. function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
  5139. var i,
  5140. val = 0;
  5141. // If we already have the right measurement, avoid augmentation
  5142. if ( extra === ( isBorderBox ? "border" : "content" ) ) {
  5143. i = 4;
  5144. // Otherwise initialize for horizontal or vertical properties
  5145. } else {
  5146. i = name === "width" ? 1 : 0;
  5147. }
  5148. for ( ; i < 4; i += 2 ) {
  5149. // Both box models exclude margin, so add it if we want it
  5150. if ( extra === "margin" ) {
  5151. val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
  5152. }
  5153. if ( isBorderBox ) {
  5154. // border-box includes padding, so remove it if we want content
  5155. if ( extra === "content" ) {
  5156. val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
  5157. }
  5158. // At this point, extra isn't border nor margin, so remove border
  5159. if ( extra !== "margin" ) {
  5160. val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  5161. }
  5162. } else {
  5163. // At this point, extra isn't content, so add padding
  5164. val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
  5165. // At this point, extra isn't content nor padding, so add border
  5166. if ( extra !== "padding" ) {
  5167. val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  5168. }
  5169. }
  5170. }
  5171. return val;
  5172. }
  5173. function getWidthOrHeight( elem, name, extra ) {
  5174. // Start with computed style
  5175. var valueIsBorderBox,
  5176. styles = getStyles( elem ),
  5177. val = curCSS( elem, name, styles ),
  5178. isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
  5179. // Computed unit is not pixels. Stop here and return.
  5180. if ( rnumnonpx.test( val ) ) {
  5181. return val;
  5182. }
  5183. // Check for style in case a browser which returns unreliable values
  5184. // for getComputedStyle silently falls back to the reliable elem.style
  5185. valueIsBorderBox = isBorderBox &&
  5186. ( support.boxSizingReliable() || val === elem.style[ name ] );
  5187. // Fall back to offsetWidth/Height when value is "auto"
  5188. // This happens for inline elements with no explicit setting (gh-3571)
  5189. if ( val === "auto" ) {
  5190. val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ];
  5191. }
  5192. // Normalize "", auto, and prepare for extra
  5193. val = parseFloat( val ) || 0;
  5194. // Use the active box-sizing model to add/subtract irrelevant styles
  5195. return ( val +
  5196. augmentWidthOrHeight(
  5197. elem,
  5198. name,
  5199. extra || ( isBorderBox ? "border" : "content" ),
  5200. valueIsBorderBox,
  5201. styles
  5202. )
  5203. ) + "px";
  5204. }
  5205. jQuery.extend( {
  5206. // Add in style property hooks for overriding the default
  5207. // behavior of getting and setting a style property
  5208. cssHooks: {
  5209. opacity: {
  5210. get: function( elem, computed ) {
  5211. if ( computed ) {
  5212. // We should always get a number back from opacity
  5213. var ret = curCSS( elem, "opacity" );
  5214. return ret === "" ? "1" : ret;
  5215. }
  5216. }
  5217. }
  5218. },
  5219. // Don't automatically add "px" to these possibly-unitless properties
  5220. cssNumber: {
  5221. "animationIterationCount": true,
  5222. "columnCount": true,
  5223. "fillOpacity": true,
  5224. "flexGrow": true,
  5225. "flexShrink": true,
  5226. "fontWeight": true,
  5227. "lineHeight": true,
  5228. "opacity": true,
  5229. "order": true,
  5230. "orphans": true,
  5231. "widows": true,
  5232. "zIndex": true,
  5233. "zoom": true
  5234. },
  5235. // Add in properties whose names you wish to fix before
  5236. // setting or getting the value
  5237. cssProps: {
  5238. "float": "cssFloat"
  5239. },
  5240. // Get and set the style property on a DOM Node
  5241. style: function( elem, name, value, extra ) {
  5242. // Don't set styles on text and comment nodes
  5243. if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
  5244. return;
  5245. }
  5246. // Make sure that we're working with the right name
  5247. var ret, type, hooks,
  5248. origName = jQuery.camelCase( name ),
  5249. isCustomProp = rcustomProp.test( name ),
  5250. style = elem.style;
  5251. // Make sure that we're working with the right name. We don't
  5252. // want to query the value if it is a CSS custom property
  5253. // since they are user-defined.
  5254. if ( !isCustomProp ) {
  5255. name = finalPropName( origName );
  5256. }
  5257. // Gets hook for the prefixed version, then unprefixed version
  5258. hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  5259. // Check if we're setting a value
  5260. if ( value !== undefined ) {
  5261. type = typeof value;
  5262. // Convert "+=" or "-=" to relative numbers (#7345)
  5263. if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
  5264. value = adjustCSS( elem, name, ret );
  5265. // Fixes bug #9237
  5266. type = "number";
  5267. }
  5268. // Make sure that null and NaN values aren't set (#7116)
  5269. if ( value == null || value !== value ) {
  5270. return;
  5271. }
  5272. // If a number was passed in, add the unit (except for certain CSS properties)
  5273. if ( type === "number" ) {
  5274. value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
  5275. }
  5276. // background-* props affect original clone's values
  5277. if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
  5278. style[ name ] = "inherit";
  5279. }
  5280. // If a hook was provided, use that value, otherwise just set the specified value
  5281. if ( !hooks || !( "set" in hooks ) ||
  5282. ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
  5283. if ( isCustomProp ) {
  5284. style.setProperty( name, value );
  5285. } else {
  5286. style[ name ] = value;
  5287. }
  5288. }
  5289. } else {
  5290. // If a hook was provided get the non-computed value from there
  5291. if ( hooks && "get" in hooks &&
  5292. ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
  5293. return ret;
  5294. }
  5295. // Otherwise just get the value from the style object
  5296. return style[ name ];
  5297. }
  5298. },
  5299. css: function( elem, name, extra, styles ) {
  5300. var val, num, hooks,
  5301. origName = jQuery.camelCase( name ),
  5302. isCustomProp = rcustomProp.test( name );
  5303. // Make sure that we're working with the right name. We don't
  5304. // want to modify the value if it is a CSS custom property
  5305. // since they are user-defined.
  5306. if ( !isCustomProp ) {
  5307. name = finalPropName( origName );
  5308. }
  5309. // Try prefixed name followed by the unprefixed name
  5310. hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  5311. // If a hook was provided get the computed value from there
  5312. if ( hooks && "get" in hooks ) {
  5313. val = hooks.get( elem, true, extra );
  5314. }
  5315. // Otherwise, if a way to get the computed value exists, use that
  5316. if ( val === undefined ) {
  5317. val = curCSS( elem, name, styles );
  5318. }
  5319. // Convert "normal" to computed value
  5320. if ( val === "normal" && name in cssNormalTransform ) {
  5321. val = cssNormalTransform[ name ];
  5322. }
  5323. // Make numeric if forced or a qualifier was provided and val looks numeric
  5324. if ( extra === "" || extra ) {
  5325. num = parseFloat( val );
  5326. return extra === true || isFinite( num ) ? num || 0 : val;
  5327. }
  5328. return val;
  5329. }
  5330. } );
  5331. jQuery.each( [ "height", "width" ], function( i, name ) {
  5332. jQuery.cssHooks[ name ] = {
  5333. get: function( elem, computed, extra ) {
  5334. if ( computed ) {
  5335. // Certain elements can have dimension info if we invisibly show them
  5336. // but it must have a current display style that would benefit
  5337. return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
  5338. // Support: Safari 8+
  5339. // Table columns in Safari have non-zero offsetWidth & zero
  5340. // getBoundingClientRect().width unless display is changed.
  5341. // Support: IE <=11 only
  5342. // Running getBoundingClientRect on a disconnected node
  5343. // in IE throws an error.
  5344. ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
  5345. swap( elem, cssShow, function() {
  5346. return getWidthOrHeight( elem, name, extra );
  5347. } ) :
  5348. getWidthOrHeight( elem, name, extra );
  5349. }
  5350. },
  5351. set: function( elem, value, extra ) {
  5352. var matches,
  5353. styles = extra && getStyles( elem ),
  5354. subtract = extra && augmentWidthOrHeight(
  5355. elem,
  5356. name,
  5357. extra,
  5358. jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
  5359. styles
  5360. );
  5361. // Convert to pixels if value adjustment is needed
  5362. if ( subtract && ( matches = rcssNum.exec( value ) ) &&
  5363. ( matches[ 3 ] || "px" ) !== "px" ) {
  5364. elem.style[ name ] = value;
  5365. value = jQuery.css( elem, name );
  5366. }
  5367. return setPositiveNumber( elem, value, subtract );
  5368. }
  5369. };
  5370. } );
  5371. jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
  5372. function( elem, computed ) {
  5373. if ( computed ) {
  5374. return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
  5375. elem.getBoundingClientRect().left -
  5376. swap( elem, { marginLeft: 0 }, function() {
  5377. return elem.getBoundingClientRect().left;
  5378. } )
  5379. ) + "px";
  5380. }
  5381. }
  5382. );
  5383. // These hooks are used by animate to expand properties
  5384. jQuery.each( {
  5385. margin: "",
  5386. padding: "",
  5387. border: "Width"
  5388. }, function( prefix, suffix ) {
  5389. jQuery.cssHooks[ prefix + suffix ] = {
  5390. expand: function( value ) {
  5391. var i = 0,
  5392. expanded = {},
  5393. // Assumes a single number if not a string
  5394. parts = typeof value === "string" ? value.split( " " ) : [ value ];
  5395. for ( ; i < 4; i++ ) {
  5396. expanded[ prefix + cssExpand[ i ] + suffix ] =
  5397. parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
  5398. }
  5399. return expanded;
  5400. }
  5401. };
  5402. if ( !rmargin.test( prefix ) ) {
  5403. jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
  5404. }
  5405. } );
  5406. jQuery.fn.extend( {
  5407. css: function( name, value ) {
  5408. return access( this, function( elem, name, value ) {
  5409. var styles, len,
  5410. map = {},
  5411. i = 0;
  5412. if ( Array.isArray( name ) ) {
  5413. styles = getStyles( elem );
  5414. len = name.length;
  5415. for ( ; i < len; i++ ) {
  5416. map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
  5417. }
  5418. return map;
  5419. }
  5420. return value !== undefined ?
  5421. jQuery.style( elem, name, value ) :
  5422. jQuery.css( elem, name );
  5423. }, name, value, arguments.length > 1 );
  5424. }
  5425. } );
  5426. function Tween( elem, options, prop, end, easing ) {
  5427. return new Tween.prototype.init( elem, options, prop, end, easing );
  5428. }
  5429. jQuery.Tween = Tween;
  5430. Tween.prototype = {
  5431. constructor: Tween,
  5432. init: function( elem, options, prop, end, easing, unit ) {
  5433. this.elem = elem;
  5434. this.prop = prop;
  5435. this.easing = easing || jQuery.easing._default;
  5436. this.options = options;
  5437. this.start = this.now = this.cur();
  5438. this.end = end;
  5439. this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
  5440. },
  5441. cur: function() {
  5442. var hooks = Tween.propHooks[ this.prop ];
  5443. return hooks && hooks.get ?
  5444. hooks.get( this ) :
  5445. Tween.propHooks._default.get( this );
  5446. },
  5447. run: function( percent ) {
  5448. var eased,
  5449. hooks = Tween.propHooks[ this.prop ];
  5450. if ( this.options.duration ) {
  5451. this.pos = eased = jQuery.easing[ this.easing ](
  5452. percent, this.options.duration * percent, 0, 1, this.options.duration
  5453. );
  5454. } else {
  5455. this.pos = eased = percent;
  5456. }
  5457. this.now = ( this.end - this.start ) * eased + this.start;
  5458. if ( this.options.step ) {
  5459. this.options.step.call( this.elem, this.now, this );
  5460. }
  5461. if ( hooks && hooks.set ) {
  5462. hooks.set( this );
  5463. } else {
  5464. Tween.propHooks._default.set( this );
  5465. }
  5466. return this;
  5467. }
  5468. };
  5469. Tween.prototype.init.prototype = Tween.prototype;
  5470. Tween.propHooks = {
  5471. _default: {
  5472. get: function( tween ) {
  5473. var result;
  5474. // Use a property on the element directly when it is not a DOM element,
  5475. // or when there is no matching style property that exists.
  5476. if ( tween.elem.nodeType !== 1 ||
  5477. tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
  5478. return tween.elem[ tween.prop ];
  5479. }
  5480. // Passing an empty string as a 3rd parameter to .css will automatically
  5481. // attempt a parseFloat and fallback to a string if the parse fails.
  5482. // Simple values such as "10px" are parsed to Float;
  5483. // complex values such as "rotate(1rad)" are returned as-is.
  5484. result = jQuery.css( tween.elem, tween.prop, "" );
  5485. // Empty strings, null, undefined and "auto" are converted to 0.
  5486. return !result || result === "auto" ? 0 : result;
  5487. },
  5488. set: function( tween ) {
  5489. // Use step hook for back compat.
  5490. // Use cssHook if its there.
  5491. // Use .style if available and use plain properties where available.
  5492. if ( jQuery.fx.step[ tween.prop ] ) {
  5493. jQuery.fx.step[ tween.prop ]( tween );
  5494. } else if ( tween.elem.nodeType === 1 &&
  5495. ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
  5496. jQuery.cssHooks[ tween.prop ] ) ) {
  5497. jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
  5498. } else {
  5499. tween.elem[ tween.prop ] = tween.now;
  5500. }
  5501. }
  5502. }
  5503. };
  5504. // Support: IE <=9 only
  5505. // Panic based approach to setting things on disconnected nodes
  5506. Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
  5507. set: function( tween ) {
  5508. if ( tween.elem.nodeType && tween.elem.parentNode ) {
  5509. tween.elem[ tween.prop ] = tween.now;
  5510. }
  5511. }
  5512. };
  5513. jQuery.easing = {
  5514. linear: function( p ) {
  5515. return p;
  5516. },
  5517. swing: function( p ) {
  5518. return 0.5 - Math.cos( p * Math.PI ) / 2;
  5519. },
  5520. _default: "swing"
  5521. };
  5522. jQuery.fx = Tween.prototype.init;
  5523. // Back compat <1.8 extension point
  5524. jQuery.fx.step = {};
  5525. var
  5526. fxNow, inProgress,
  5527. rfxtypes = /^(?:toggle|show|hide)$/,
  5528. rrun = /queueHooks$/;
  5529. function schedule() {
  5530. if ( inProgress ) {
  5531. if ( document.hidden === false && window.requestAnimationFrame ) {
  5532. window.requestAnimationFrame( schedule );
  5533. } else {
  5534. window.setTimeout( schedule, jQuery.fx.interval );
  5535. }
  5536. jQuery.fx.tick();
  5537. }
  5538. }
  5539. // Animations created synchronously will run synchronously
  5540. function createFxNow() {
  5541. window.setTimeout( function() {
  5542. fxNow = undefined;
  5543. } );
  5544. return ( fxNow = jQuery.now() );
  5545. }
  5546. // Generate parameters to create a standard animation
  5547. function genFx( type, includeWidth ) {
  5548. var which,
  5549. i = 0,
  5550. attrs = { height: type };
  5551. // If we include width, step value is 1 to do all cssExpand values,
  5552. // otherwise step value is 2 to skip over Left and Right
  5553. includeWidth = includeWidth ? 1 : 0;
  5554. for ( ; i < 4; i += 2 - includeWidth ) {
  5555. which = cssExpand[ i ];
  5556. attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
  5557. }
  5558. if ( includeWidth ) {
  5559. attrs.opacity = attrs.width = type;
  5560. }
  5561. return attrs;
  5562. }
  5563. function createTween( value, prop, animation ) {
  5564. var tween,
  5565. collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
  5566. index = 0,
  5567. length = collection.length;
  5568. for ( ; index < length; index++ ) {
  5569. if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
  5570. // We're done with this property
  5571. return tween;
  5572. }
  5573. }
  5574. }
  5575. function defaultPrefilter( elem, props, opts ) {
  5576. var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
  5577. isBox = "width" in props || "height" in props,
  5578. anim = this,
  5579. orig = {},
  5580. style = elem.style,
  5581. hidden = elem.nodeType && isHiddenWithinTree( elem ),
  5582. dataShow = dataPriv.get( elem, "fxshow" );
  5583. // Queue-skipping animations hijack the fx hooks
  5584. if ( !opts.queue ) {
  5585. hooks = jQuery._queueHooks( elem, "fx" );
  5586. if ( hooks.unqueued == null ) {
  5587. hooks.unqueued = 0;
  5588. oldfire = hooks.empty.fire;
  5589. hooks.empty.fire = function() {
  5590. if ( !hooks.unqueued ) {
  5591. oldfire();
  5592. }
  5593. };
  5594. }
  5595. hooks.unqueued++;
  5596. anim.always( function() {
  5597. // Ensure the complete handler is called before this completes
  5598. anim.always( function() {
  5599. hooks.unqueued--;
  5600. if ( !jQuery.queue( elem, "fx" ).length ) {
  5601. hooks.empty.fire();
  5602. }
  5603. } );
  5604. } );
  5605. }
  5606. // Detect show/hide animations
  5607. for ( prop in props ) {
  5608. value = props[ prop ];
  5609. if ( rfxtypes.test( value ) ) {
  5610. delete props[ prop ];
  5611. toggle = toggle || value === "toggle";
  5612. if ( value === ( hidden ? "hide" : "show" ) ) {
  5613. // Pretend to be hidden if this is a "show" and
  5614. // there is still data from a stopped show/hide
  5615. if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
  5616. hidden = true;
  5617. // Ignore all other no-op show/hide data
  5618. } else {
  5619. continue;
  5620. }
  5621. }
  5622. orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
  5623. }
  5624. }
  5625. // Bail out if this is a no-op like .hide().hide()
  5626. propTween = !jQuery.isEmptyObject( props );
  5627. if ( !propTween && jQuery.isEmptyObject( orig ) ) {
  5628. return;
  5629. }
  5630. // Restrict "overflow" and "display" styles during box animations
  5631. if ( isBox && elem.nodeType === 1 ) {
  5632. // Support: IE <=9 - 11, Edge 12 - 13
  5633. // Record all 3 overflow attributes because IE does not infer the shorthand
  5634. // from identically-valued overflowX and overflowY
  5635. opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
  5636. // Identify a display type, preferring old show/hide data over the CSS cascade
  5637. restoreDisplay = dataShow && dataShow.display;
  5638. if ( restoreDisplay == null ) {
  5639. restoreDisplay = dataPriv.get( elem, "display" );
  5640. }
  5641. display = jQuery.css( elem, "display" );
  5642. if ( display === "none" ) {
  5643. if ( restoreDisplay ) {
  5644. display = restoreDisplay;
  5645. } else {
  5646. // Get nonempty value(s) by temporarily forcing visibility
  5647. showHide( [ elem ], true );
  5648. restoreDisplay = elem.style.display || restoreDisplay;
  5649. display = jQuery.css( elem, "display" );
  5650. showHide( [ elem ] );
  5651. }
  5652. }
  5653. // Animate inline elements as inline-block
  5654. if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
  5655. if ( jQuery.css( elem, "float" ) === "none" ) {
  5656. // Restore the original display value at the end of pure show/hide animations
  5657. if ( !propTween ) {
  5658. anim.done( function() {
  5659. style.display = restoreDisplay;
  5660. } );
  5661. if ( restoreDisplay == null ) {
  5662. display = style.display;
  5663. restoreDisplay = display === "none" ? "" : display;
  5664. }
  5665. }
  5666. style.display = "inline-block";
  5667. }
  5668. }
  5669. }
  5670. if ( opts.overflow ) {
  5671. style.overflow = "hidden";
  5672. anim.always( function() {
  5673. style.overflow = opts.overflow[ 0 ];
  5674. style.overflowX = opts.overflow[ 1 ];
  5675. style.overflowY = opts.overflow[ 2 ];
  5676. } );
  5677. }
  5678. // Implement show/hide animations
  5679. propTween = false;
  5680. for ( prop in orig ) {
  5681. // General show/hide setup for this element animation
  5682. if ( !propTween ) {
  5683. if ( dataShow ) {
  5684. if ( "hidden" in dataShow ) {
  5685. hidden = dataShow.hidden;
  5686. }
  5687. } else {
  5688. dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
  5689. }
  5690. // Store hidden/visible for toggle so `.stop().toggle()` "reverses"
  5691. if ( toggle ) {
  5692. dataShow.hidden = !hidden;
  5693. }
  5694. // Show elements before animating them
  5695. if ( hidden ) {
  5696. showHide( [ elem ], true );
  5697. }
  5698. /* eslint-disable no-loop-func */
  5699. anim.done( function() {
  5700. /* eslint-enable no-loop-func */
  5701. // The final step of a "hide" animation is actually hiding the element
  5702. if ( !hidden ) {
  5703. showHide( [ elem ] );
  5704. }
  5705. dataPriv.remove( elem, "fxshow" );
  5706. for ( prop in orig ) {
  5707. jQuery.style( elem, prop, orig[ prop ] );
  5708. }
  5709. } );
  5710. }
  5711. // Per-property setup
  5712. propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
  5713. if ( !( prop in dataShow ) ) {
  5714. dataShow[ prop ] = propTween.start;
  5715. if ( hidden ) {
  5716. propTween.end = propTween.start;
  5717. propTween.start = 0;
  5718. }
  5719. }
  5720. }
  5721. }
  5722. function propFilter( props, specialEasing ) {
  5723. var index, name, easing, value, hooks;
  5724. // camelCase, specialEasing and expand cssHook pass
  5725. for ( index in props ) {
  5726. name = jQuery.camelCase( index );
  5727. easing = specialEasing[ name ];
  5728. value = props[ index ];
  5729. if ( Array.isArray( value ) ) {
  5730. easing = value[ 1 ];
  5731. value = props[ index ] = value[ 0 ];
  5732. }
  5733. if ( index !== name ) {
  5734. props[ name ] = value;
  5735. delete props[ index ];
  5736. }
  5737. hooks = jQuery.cssHooks[ name ];
  5738. if ( hooks && "expand" in hooks ) {
  5739. value = hooks.expand( value );
  5740. delete props[ name ];
  5741. // Not quite $.extend, this won't overwrite existing keys.
  5742. // Reusing 'index' because we have the correct "name"
  5743. for ( index in value ) {
  5744. if ( !( index in props ) ) {
  5745. props[ index ] = value[ index ];
  5746. specialEasing[ index ] = easing;
  5747. }
  5748. }
  5749. } else {
  5750. specialEasing[ name ] = easing;
  5751. }
  5752. }
  5753. }
  5754. function Animation( elem, properties, options ) {
  5755. var result,
  5756. stopped,
  5757. index = 0,
  5758. length = Animation.prefilters.length,
  5759. deferred = jQuery.Deferred().always( function() {
  5760. // Don't match elem in the :animated selector
  5761. delete tick.elem;
  5762. } ),
  5763. tick = function() {
  5764. if ( stopped ) {
  5765. return false;
  5766. }
  5767. var currentTime = fxNow || createFxNow(),
  5768. remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
  5769. // Support: Android 2.3 only
  5770. // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
  5771. temp = remaining / animation.duration || 0,
  5772. percent = 1 - temp,
  5773. index = 0,
  5774. length = animation.tweens.length;
  5775. for ( ; index < length; index++ ) {
  5776. animation.tweens[ index ].run( percent );
  5777. }
  5778. deferred.notifyWith( elem, [ animation, percent, remaining ] );
  5779. // If there's more to do, yield
  5780. if ( percent < 1 && length ) {
  5781. return remaining;
  5782. }
  5783. // If this was an empty animation, synthesize a final progress notification
  5784. if ( !length ) {
  5785. deferred.notifyWith( elem, [ animation, 1, 0 ] );
  5786. }
  5787. // Resolve the animation and report its conclusion
  5788. deferred.resolveWith( elem, [ animation ] );
  5789. return false;
  5790. },
  5791. animation = deferred.promise( {
  5792. elem: elem,
  5793. props: jQuery.extend( {}, properties ),
  5794. opts: jQuery.extend( true, {
  5795. specialEasing: {},
  5796. easing: jQuery.easing._default
  5797. }, options ),
  5798. originalProperties: properties,
  5799. originalOptions: options,
  5800. startTime: fxNow || createFxNow(),
  5801. duration: options.duration,
  5802. tweens: [],
  5803. createTween: function( prop, end ) {
  5804. var tween = jQuery.Tween( elem, animation.opts, prop, end,
  5805. animation.opts.specialEasing[ prop ] || animation.opts.easing );
  5806. animation.tweens.push( tween );
  5807. return tween;
  5808. },
  5809. stop: function( gotoEnd ) {
  5810. var index = 0,
  5811. // If we are going to the end, we want to run all the tweens
  5812. // otherwise we skip this part
  5813. length = gotoEnd ? animation.tweens.length : 0;
  5814. if ( stopped ) {
  5815. return this;
  5816. }
  5817. stopped = true;
  5818. for ( ; index < length; index++ ) {
  5819. animation.tweens[ index ].run( 1 );
  5820. }
  5821. // Resolve when we played the last frame; otherwise, reject
  5822. if ( gotoEnd ) {
  5823. deferred.notifyWith( elem, [ animation, 1, 0 ] );
  5824. deferred.resolveWith( elem, [ animation, gotoEnd ] );
  5825. } else {
  5826. deferred.rejectWith( elem, [ animation, gotoEnd ] );
  5827. }
  5828. return this;
  5829. }
  5830. } ),
  5831. props = animation.props;
  5832. propFilter( props, animation.opts.specialEasing );
  5833. for ( ; index < length; index++ ) {
  5834. result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
  5835. if ( result ) {
  5836. if ( jQuery.isFunction( result.stop ) ) {
  5837. jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
  5838. jQuery.proxy( result.stop, result );
  5839. }
  5840. return result;
  5841. }
  5842. }
  5843. jQuery.map( props, createTween, animation );
  5844. if ( jQuery.isFunction( animation.opts.start ) ) {
  5845. animation.opts.start.call( elem, animation );
  5846. }
  5847. // Attach callbacks from options
  5848. animation
  5849. .progress( animation.opts.progress )
  5850. .done( animation.opts.done, animation.opts.complete )
  5851. .fail( animation.opts.fail )
  5852. .always( animation.opts.always );
  5853. jQuery.fx.timer(
  5854. jQuery.extend( tick, {
  5855. elem: elem,
  5856. anim: animation,
  5857. queue: animation.opts.queue
  5858. } )
  5859. );
  5860. return animation;
  5861. }
  5862. jQuery.Animation = jQuery.extend( Animation, {
  5863. tweeners: {
  5864. "*": [ function( prop, value ) {
  5865. var tween = this.createTween( prop, value );
  5866. adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
  5867. return tween;
  5868. } ]
  5869. },
  5870. tweener: function( props, callback ) {
  5871. if ( jQuery.isFunction( props ) ) {
  5872. callback = props;
  5873. props = [ "*" ];
  5874. } else {
  5875. props = props.match( rnothtmlwhite );
  5876. }
  5877. var prop,
  5878. index = 0,
  5879. length = props.length;
  5880. for ( ; index < length; index++ ) {
  5881. prop = props[ index ];
  5882. Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
  5883. Animation.tweeners[ prop ].unshift( callback );
  5884. }
  5885. },
  5886. prefilters: [ defaultPrefilter ],
  5887. prefilter: function( callback, prepend ) {
  5888. if ( prepend ) {
  5889. Animation.prefilters.unshift( callback );
  5890. } else {
  5891. Animation.prefilters.push( callback );
  5892. }
  5893. }
  5894. } );
  5895. jQuery.speed = function( speed, easing, fn ) {
  5896. var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
  5897. complete: fn || !fn && easing ||
  5898. jQuery.isFunction( speed ) && speed,
  5899. duration: speed,
  5900. easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
  5901. };
  5902. // Go to the end state if fx are off
  5903. if ( jQuery.fx.off ) {
  5904. opt.duration = 0;
  5905. } else {
  5906. if ( typeof opt.duration !== "number" ) {
  5907. if ( opt.duration in jQuery.fx.speeds ) {
  5908. opt.duration = jQuery.fx.speeds[ opt.duration ];
  5909. } else {
  5910. opt.duration = jQuery.fx.speeds._default;
  5911. }
  5912. }
  5913. }
  5914. // Normalize opt.queue - true/undefined/null -> "fx"
  5915. if ( opt.queue == null || opt.queue === true ) {
  5916. opt.queue = "fx";
  5917. }
  5918. // Queueing
  5919. opt.old = opt.complete;
  5920. opt.complete = function() {
  5921. if ( jQuery.isFunction( opt.old ) ) {
  5922. opt.old.call( this );
  5923. }
  5924. if ( opt.queue ) {
  5925. jQuery.dequeue( this, opt.queue );
  5926. }
  5927. };
  5928. return opt;
  5929. };
  5930. jQuery.fn.extend( {
  5931. fadeTo: function( speed, to, easing, callback ) {
  5932. // Show any hidden elements after setting opacity to 0
  5933. return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
  5934. // Animate to the value specified
  5935. .end().animate( { opacity: to }, speed, easing, callback );
  5936. },
  5937. animate: function( prop, speed, easing, callback ) {
  5938. var empty = jQuery.isEmptyObject( prop ),
  5939. optall = jQuery.speed( speed, easing, callback ),
  5940. doAnimation = function() {
  5941. // Operate on a copy of prop so per-property easing won't be lost
  5942. var anim = Animation( this, jQuery.extend( {}, prop ), optall );
  5943. // Empty animations, or finishing resolves immediately
  5944. if ( empty || dataPriv.get( this, "finish" ) ) {
  5945. anim.stop( true );
  5946. }
  5947. };
  5948. doAnimation.finish = doAnimation;
  5949. return empty || optall.queue === false ?
  5950. this.each( doAnimation ) :
  5951. this.queue( optall.queue, doAnimation );
  5952. },
  5953. stop: function( type, clearQueue, gotoEnd ) {
  5954. var stopQueue = function( hooks ) {
  5955. var stop = hooks.stop;
  5956. delete hooks.stop;
  5957. stop( gotoEnd );
  5958. };
  5959. if ( typeof type !== "string" ) {
  5960. gotoEnd = clearQueue;
  5961. clearQueue = type;
  5962. type = undefined;
  5963. }
  5964. if ( clearQueue && type !== false ) {
  5965. this.queue( type || "fx", [] );
  5966. }
  5967. return this.each( function() {
  5968. var dequeue = true,
  5969. index = type != null && type + "queueHooks",
  5970. timers = jQuery.timers,
  5971. data = dataPriv.get( this );
  5972. if ( index ) {
  5973. if ( data[ index ] && data[ index ].stop ) {
  5974. stopQueue( data[ index ] );
  5975. }
  5976. } else {
  5977. for ( index in data ) {
  5978. if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
  5979. stopQueue( data[ index ] );
  5980. }
  5981. }
  5982. }
  5983. for ( index = timers.length; index--; ) {
  5984. if ( timers[ index ].elem === this &&
  5985. ( type == null || timers[ index ].queue === type ) ) {
  5986. timers[ index ].anim.stop( gotoEnd );
  5987. dequeue = false;
  5988. timers.splice( index, 1 );
  5989. }
  5990. }
  5991. // Start the next in the queue if the last step wasn't forced.
  5992. // Timers currently will call their complete callbacks, which
  5993. // will dequeue but only if they were gotoEnd.
  5994. if ( dequeue || !gotoEnd ) {
  5995. jQuery.dequeue( this, type );
  5996. }
  5997. } );
  5998. },
  5999. finish: function( type ) {
  6000. if ( type !== false ) {
  6001. type = type || "fx";
  6002. }
  6003. return this.each( function() {
  6004. var index,
  6005. data = dataPriv.get( this ),
  6006. queue = data[ type + "queue" ],
  6007. hooks = data[ type + "queueHooks" ],
  6008. timers = jQuery.timers,
  6009. length = queue ? queue.length : 0;
  6010. // Enable finishing flag on private data
  6011. data.finish = true;
  6012. // Empty the queue first
  6013. jQuery.queue( this, type, [] );
  6014. if ( hooks && hooks.stop ) {
  6015. hooks.stop.call( this, true );
  6016. }
  6017. // Look for any active animations, and finish them
  6018. for ( index = timers.length; index--; ) {
  6019. if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
  6020. timers[ index ].anim.stop( true );
  6021. timers.splice( index, 1 );
  6022. }
  6023. }
  6024. // Look for any animations in the old queue and finish them
  6025. for ( index = 0; index < length; index++ ) {
  6026. if ( queue[ index ] && queue[ index ].finish ) {
  6027. queue[ index ].finish.call( this );
  6028. }
  6029. }
  6030. // Turn off finishing flag
  6031. delete data.finish;
  6032. } );
  6033. }
  6034. } );
  6035. jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
  6036. var cssFn = jQuery.fn[ name ];
  6037. jQuery.fn[ name ] = function( speed, easing, callback ) {
  6038. return speed == null || typeof speed === "boolean" ?
  6039. cssFn.apply( this, arguments ) :
  6040. this.animate( genFx( name, true ), speed, easing, callback );
  6041. };
  6042. } );
  6043. // Generate shortcuts for custom animations
  6044. jQuery.each( {
  6045. slideDown: genFx( "show" ),
  6046. slideUp: genFx( "hide" ),
  6047. slideToggle: genFx( "toggle" ),
  6048. fadeIn: { opacity: "show" },
  6049. fadeOut: { opacity: "hide" },
  6050. fadeToggle: { opacity: "toggle" }
  6051. }, function( name, props ) {
  6052. jQuery.fn[ name ] = function( speed, easing, callback ) {
  6053. return this.animate( props, speed, easing, callback );
  6054. };
  6055. } );
  6056. jQuery.timers = [];
  6057. jQuery.fx.tick = function() {
  6058. var timer,
  6059. i = 0,
  6060. timers = jQuery.timers;
  6061. fxNow = jQuery.now();
  6062. for ( ; i < timers.length; i++ ) {
  6063. timer = timers[ i ];
  6064. // Run the timer and safely remove it when done (allowing for external removal)
  6065. if ( !timer() && timers[ i ] === timer ) {
  6066. timers.splice( i--, 1 );
  6067. }
  6068. }
  6069. if ( !timers.length ) {
  6070. jQuery.fx.stop();
  6071. }
  6072. fxNow = undefined;
  6073. };
  6074. jQuery.fx.timer = function( timer ) {
  6075. jQuery.timers.push( timer );
  6076. jQuery.fx.start();
  6077. };
  6078. jQuery.fx.interval = 13;
  6079. jQuery.fx.start = function() {
  6080. if ( inProgress ) {
  6081. return;
  6082. }
  6083. inProgress = true;
  6084. schedule();
  6085. };
  6086. jQuery.fx.stop = function() {
  6087. inProgress = null;
  6088. };
  6089. jQuery.fx.speeds = {
  6090. slow: 600,
  6091. fast: 200,
  6092. // Default speed
  6093. _default: 400
  6094. };
  6095. // Based off of the plugin by Clint Helfers, with permission.
  6096. // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
  6097. jQuery.fn.delay = function( time, type ) {
  6098. time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
  6099. type = type || "fx";
  6100. return this.queue( type, function( next, hooks ) {
  6101. var timeout = window.setTimeout( next, time );
  6102. hooks.stop = function() {
  6103. window.clearTimeout( timeout );
  6104. };
  6105. } );
  6106. };
  6107. ( function() {
  6108. var input = document.createElement( "input" ),
  6109. select = document.createElement( "select" ),
  6110. opt = select.appendChild( document.createElement( "option" ) );
  6111. input.type = "checkbox";
  6112. // Support: Android <=4.3 only
  6113. // Default value for a checkbox should be "on"
  6114. support.checkOn = input.value !== "";
  6115. // Support: IE <=11 only
  6116. // Must access selectedIndex to make default options select
  6117. support.optSelected = opt.selected;
  6118. // Support: IE <=11 only
  6119. // An input loses its value after becoming a radio
  6120. input = document.createElement( "input" );
  6121. input.value = "t";
  6122. input.type = "radio";
  6123. support.radioValue = input.value === "t";
  6124. } )();
  6125. var boolHook,
  6126. attrHandle = jQuery.expr.attrHandle;
  6127. jQuery.fn.extend( {
  6128. attr: function( name, value ) {
  6129. return access( this, jQuery.attr, name, value, arguments.length > 1 );
  6130. },
  6131. removeAttr: function( name ) {
  6132. return this.each( function() {
  6133. jQuery.removeAttr( this, name );
  6134. } );
  6135. }
  6136. } );
  6137. jQuery.extend( {
  6138. attr: function( elem, name, value ) {
  6139. var ret, hooks,
  6140. nType = elem.nodeType;
  6141. // Don't get/set attributes on text, comment and attribute nodes
  6142. if ( nType === 3 || nType === 8 || nType === 2 ) {
  6143. return;
  6144. }
  6145. // Fallback to prop when attributes are not supported
  6146. if ( typeof elem.getAttribute === "undefined" ) {
  6147. return jQuery.prop( elem, name, value );
  6148. }
  6149. // Attribute hooks are determined by the lowercase version
  6150. // Grab necessary hook if one is defined
  6151. if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
  6152. hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
  6153. ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
  6154. }
  6155. if ( value !== undefined ) {
  6156. if ( value === null ) {
  6157. jQuery.removeAttr( elem, name );
  6158. return;
  6159. }
  6160. if ( hooks && "set" in hooks &&
  6161. ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
  6162. return ret;
  6163. }
  6164. elem.setAttribute( name, value + "" );
  6165. return value;
  6166. }
  6167. if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
  6168. return ret;
  6169. }
  6170. ret = jQuery.find.attr( elem, name );
  6171. // Non-existent attributes return null, we normalize to undefined
  6172. return ret == null ? undefined : ret;
  6173. },
  6174. attrHooks: {
  6175. type: {
  6176. set: function( elem, value ) {
  6177. if ( !support.radioValue && value === "radio" &&
  6178. nodeName( elem, "input" ) ) {
  6179. var val = elem.value;
  6180. elem.setAttribute( "type", value );
  6181. if ( val ) {
  6182. elem.value = val;
  6183. }
  6184. return value;
  6185. }
  6186. }
  6187. }
  6188. },
  6189. removeAttr: function( elem, value ) {
  6190. var name,
  6191. i = 0,
  6192. // Attribute names can contain non-HTML whitespace characters
  6193. // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
  6194. attrNames = value && value.match( rnothtmlwhite );
  6195. if ( attrNames && elem.nodeType === 1 ) {
  6196. while ( ( name = attrNames[ i++ ] ) ) {
  6197. elem.removeAttribute( name );
  6198. }
  6199. }
  6200. }
  6201. } );
  6202. // Hooks for boolean attributes
  6203. boolHook = {
  6204. set: function( elem, value, name ) {
  6205. if ( value === false ) {
  6206. // Remove boolean attributes when set to false
  6207. jQuery.removeAttr( elem, name );
  6208. } else {
  6209. elem.setAttribute( name, name );
  6210. }
  6211. return name;
  6212. }
  6213. };
  6214. jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
  6215. var getter = attrHandle[ name ] || jQuery.find.attr;
  6216. attrHandle[ name ] = function( elem, name, isXML ) {
  6217. var ret, handle,
  6218. lowercaseName = name.toLowerCase();
  6219. if ( !isXML ) {
  6220. // Avoid an infinite loop by temporarily removing this function from the getter
  6221. handle = attrHandle[ lowercaseName ];
  6222. attrHandle[ lowercaseName ] = ret;
  6223. ret = getter( elem, name, isXML ) != null ?
  6224. lowercaseName :
  6225. null;
  6226. attrHandle[ lowercaseName ] = handle;
  6227. }
  6228. return ret;
  6229. };
  6230. } );
  6231. var rfocusable = /^(?:input|select|textarea|button)$/i,
  6232. rclickable = /^(?:a|area)$/i;
  6233. jQuery.fn.extend( {
  6234. prop: function( name, value ) {
  6235. return access( this, jQuery.prop, name, value, arguments.length > 1 );
  6236. },
  6237. removeProp: function( name ) {
  6238. return this.each( function() {
  6239. delete this[ jQuery.propFix[ name ] || name ];
  6240. } );
  6241. }
  6242. } );
  6243. jQuery.extend( {
  6244. prop: function( elem, name, value ) {
  6245. var ret, hooks,
  6246. nType = elem.nodeType;
  6247. // Don't get/set properties on text, comment and attribute nodes
  6248. if ( nType === 3 || nType === 8 || nType === 2 ) {
  6249. return;
  6250. }
  6251. if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
  6252. // Fix name and attach hooks
  6253. name = jQuery.propFix[ name ] || name;
  6254. hooks = jQuery.propHooks[ name ];
  6255. }
  6256. if ( value !== undefined ) {
  6257. if ( hooks && "set" in hooks &&
  6258. ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
  6259. return ret;
  6260. }
  6261. return ( elem[ name ] = value );
  6262. }
  6263. if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
  6264. return ret;
  6265. }
  6266. return elem[ name ];
  6267. },
  6268. propHooks: {
  6269. tabIndex: {
  6270. get: function( elem ) {
  6271. // Support: IE <=9 - 11 only
  6272. // elem.tabIndex doesn't always return the
  6273. // correct value when it hasn't been explicitly set
  6274. // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
  6275. // Use proper attribute retrieval(#12072)
  6276. var tabindex = jQuery.find.attr( elem, "tabindex" );
  6277. if ( tabindex ) {
  6278. return parseInt( tabindex, 10 );
  6279. }
  6280. if (
  6281. rfocusable.test( elem.nodeName ) ||
  6282. rclickable.test( elem.nodeName ) &&
  6283. elem.href
  6284. ) {
  6285. return 0;
  6286. }
  6287. return -1;
  6288. }
  6289. }
  6290. },
  6291. propFix: {
  6292. "for": "htmlFor",
  6293. "class": "className"
  6294. }
  6295. } );
  6296. // Support: IE <=11 only
  6297. // Accessing the selectedIndex property
  6298. // forces the browser to respect setting selected
  6299. // on the option
  6300. // The getter ensures a default option is selected
  6301. // when in an optgroup
  6302. // eslint rule "no-unused-expressions" is disabled for this code
  6303. // since it considers such accessions noop
  6304. if ( !support.optSelected ) {
  6305. jQuery.propHooks.selected = {
  6306. get: function( elem ) {
  6307. /* eslint no-unused-expressions: "off" */
  6308. var parent = elem.parentNode;
  6309. if ( parent && parent.parentNode ) {
  6310. parent.parentNode.selectedIndex;
  6311. }
  6312. return null;
  6313. },
  6314. set: function( elem ) {
  6315. /* eslint no-unused-expressions: "off" */
  6316. var parent = elem.parentNode;
  6317. if ( parent ) {
  6318. parent.selectedIndex;
  6319. if ( parent.parentNode ) {
  6320. parent.parentNode.selectedIndex;
  6321. }
  6322. }
  6323. }
  6324. };
  6325. }
  6326. jQuery.each( [
  6327. "tabIndex",
  6328. "readOnly",
  6329. "maxLength",
  6330. "cellSpacing",
  6331. "cellPadding",
  6332. "rowSpan",
  6333. "colSpan",
  6334. "useMap",
  6335. "frameBorder",
  6336. "contentEditable"
  6337. ], function() {
  6338. jQuery.propFix[ this.toLowerCase() ] = this;
  6339. } );
  6340. // Strip and collapse whitespace according to HTML spec
  6341. // https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace
  6342. function stripAndCollapse( value ) {
  6343. var tokens = value.match( rnothtmlwhite ) || [];
  6344. return tokens.join( " " );
  6345. }
  6346. function getClass( elem ) {
  6347. return elem.getAttribute && elem.getAttribute( "class" ) || "";
  6348. }
  6349. jQuery.fn.extend( {
  6350. addClass: function( value ) {
  6351. var classes, elem, cur, curValue, clazz, j, finalValue,
  6352. i = 0;
  6353. if ( jQuery.isFunction( value ) ) {
  6354. return this.each( function( j ) {
  6355. jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
  6356. } );
  6357. }
  6358. if ( typeof value === "string" && value ) {
  6359. classes = value.match( rnothtmlwhite ) || [];
  6360. while ( ( elem = this[ i++ ] ) ) {
  6361. curValue = getClass( elem );
  6362. cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
  6363. if ( cur ) {
  6364. j = 0;
  6365. while ( ( clazz = classes[ j++ ] ) ) {
  6366. if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
  6367. cur += clazz + " ";
  6368. }
  6369. }
  6370. // Only assign if different to avoid unneeded rendering.
  6371. finalValue = stripAndCollapse( cur );
  6372. if ( curValue !== finalValue ) {
  6373. elem.setAttribute( "class", finalValue );
  6374. }
  6375. }
  6376. }
  6377. }
  6378. return this;
  6379. },
  6380. removeClass: function( value ) {
  6381. var classes, elem, cur, curValue, clazz, j, finalValue,
  6382. i = 0;
  6383. if ( jQuery.isFunction( value ) ) {
  6384. return this.each( function( j ) {
  6385. jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
  6386. } );
  6387. }
  6388. if ( !arguments.length ) {
  6389. return this.attr( "class", "" );
  6390. }
  6391. if ( typeof value === "string" && value ) {
  6392. classes = value.match( rnothtmlwhite ) || [];
  6393. while ( ( elem = this[ i++ ] ) ) {
  6394. curValue = getClass( elem );
  6395. // This expression is here for better compressibility (see addClass)
  6396. cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
  6397. if ( cur ) {
  6398. j = 0;
  6399. while ( ( clazz = classes[ j++ ] ) ) {
  6400. // Remove *all* instances
  6401. while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
  6402. cur = cur.replace( " " + clazz + " ", " " );
  6403. }
  6404. }
  6405. // Only assign if different to avoid unneeded rendering.
  6406. finalValue = stripAndCollapse( cur );
  6407. if ( curValue !== finalValue ) {
  6408. elem.setAttribute( "class", finalValue );
  6409. }
  6410. }
  6411. }
  6412. }
  6413. return this;
  6414. },
  6415. toggleClass: function( value, stateVal ) {
  6416. var type = typeof value;
  6417. if ( typeof stateVal === "boolean" && type === "string" ) {
  6418. return stateVal ? this.addClass( value ) : this.removeClass( value );
  6419. }
  6420. if ( jQuery.isFunction( value ) ) {
  6421. return this.each( function( i ) {
  6422. jQuery( this ).toggleClass(
  6423. value.call( this, i, getClass( this ), stateVal ),
  6424. stateVal
  6425. );
  6426. } );
  6427. }
  6428. return this.each( function() {
  6429. var className, i, self, classNames;
  6430. if ( type === "string" ) {
  6431. // Toggle individual class names
  6432. i = 0;
  6433. self = jQuery( this );
  6434. classNames = value.match( rnothtmlwhite ) || [];
  6435. while ( ( className = classNames[ i++ ] ) ) {
  6436. // Check each className given, space separated list
  6437. if ( self.hasClass( className ) ) {
  6438. self.removeClass( className );
  6439. } else {
  6440. self.addClass( className );
  6441. }
  6442. }
  6443. // Toggle whole class name
  6444. } else if ( value === undefined || type === "boolean" ) {
  6445. className = getClass( this );
  6446. if ( className ) {
  6447. // Store className if set
  6448. dataPriv.set( this, "__className__", className );
  6449. }
  6450. // If the element has a class name or if we're passed `false`,
  6451. // then remove the whole classname (if there was one, the above saved it).
  6452. // Otherwise bring back whatever was previously saved (if anything),
  6453. // falling back to the empty string if nothing was stored.
  6454. if ( this.setAttribute ) {
  6455. this.setAttribute( "class",
  6456. className || value === false ?
  6457. "" :
  6458. dataPriv.get( this, "__className__" ) || ""
  6459. );
  6460. }
  6461. }
  6462. } );
  6463. },
  6464. hasClass: function( selector ) {
  6465. var className, elem,
  6466. i = 0;
  6467. className = " " + selector + " ";
  6468. while ( ( elem = this[ i++ ] ) ) {
  6469. if ( elem.nodeType === 1 &&
  6470. ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
  6471. return true;
  6472. }
  6473. }
  6474. return false;
  6475. }
  6476. } );
  6477. var rreturn = /\r/g;
  6478. jQuery.fn.extend( {
  6479. val: function( value ) {
  6480. var hooks, ret, isFunction,
  6481. elem = this[ 0 ];
  6482. if ( !arguments.length ) {
  6483. if ( elem ) {
  6484. hooks = jQuery.valHooks[ elem.type ] ||
  6485. jQuery.valHooks[ elem.nodeName.toLowerCase() ];
  6486. if ( hooks &&
  6487. "get" in hooks &&
  6488. ( ret = hooks.get( elem, "value" ) ) !== undefined
  6489. ) {
  6490. return ret;
  6491. }
  6492. ret = elem.value;
  6493. // Handle most common string cases
  6494. if ( typeof ret === "string" ) {
  6495. return ret.replace( rreturn, "" );
  6496. }
  6497. // Handle cases where value is null/undef or number
  6498. return ret == null ? "" : ret;
  6499. }
  6500. return;
  6501. }
  6502. isFunction = jQuery.isFunction( value );
  6503. return this.each( function( i ) {
  6504. var val;
  6505. if ( this.nodeType !== 1 ) {
  6506. return;
  6507. }
  6508. if ( isFunction ) {
  6509. val = value.call( this, i, jQuery( this ).val() );
  6510. } else {
  6511. val = value;
  6512. }
  6513. // Treat null/undefined as ""; convert numbers to string
  6514. if ( val == null ) {
  6515. val = "";
  6516. } else if ( typeof val === "number" ) {
  6517. val += "";
  6518. } else if ( Array.isArray( val ) ) {
  6519. val = jQuery.map( val, function( value ) {
  6520. return value == null ? "" : value + "";
  6521. } );
  6522. }
  6523. hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
  6524. // If set returns undefined, fall back to normal setting
  6525. if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
  6526. this.value = val;
  6527. }
  6528. } );
  6529. }
  6530. } );
  6531. jQuery.extend( {
  6532. valHooks: {
  6533. option: {
  6534. get: function( elem ) {
  6535. var val = jQuery.find.attr( elem, "value" );
  6536. return val != null ?
  6537. val :
  6538. // Support: IE <=10 - 11 only
  6539. // option.text throws exceptions (#14686, #14858)
  6540. // Strip and collapse whitespace
  6541. // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
  6542. stripAndCollapse( jQuery.text( elem ) );
  6543. }
  6544. },
  6545. select: {
  6546. get: function( elem ) {
  6547. var value, option, i,
  6548. options = elem.options,
  6549. index = elem.selectedIndex,
  6550. one = elem.type === "select-one",
  6551. values = one ? null : [],
  6552. max = one ? index + 1 : options.length;
  6553. if ( index < 0 ) {
  6554. i = max;
  6555. } else {
  6556. i = one ? index : 0;
  6557. }
  6558. // Loop through all the selected options
  6559. for ( ; i < max; i++ ) {
  6560. option = options[ i ];
  6561. // Support: IE <=9 only
  6562. // IE8-9 doesn't update selected after form reset (#2551)
  6563. if ( ( option.selected || i === index ) &&
  6564. // Don't return options that are disabled or in a disabled optgroup
  6565. !option.disabled &&
  6566. ( !option.parentNode.disabled ||
  6567. !nodeName( option.parentNode, "optgroup" ) ) ) {
  6568. // Get the specific value for the option
  6569. value = jQuery( option ).val();
  6570. // We don't need an array for one selects
  6571. if ( one ) {
  6572. return value;
  6573. }
  6574. // Multi-Selects return an array
  6575. values.push( value );
  6576. }
  6577. }
  6578. return values;
  6579. },
  6580. set: function( elem, value ) {
  6581. var optionSet, option,
  6582. options = elem.options,
  6583. values = jQuery.makeArray( value ),
  6584. i = options.length;
  6585. while ( i-- ) {
  6586. option = options[ i ];
  6587. /* eslint-disable no-cond-assign */
  6588. if ( option.selected =
  6589. jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
  6590. ) {
  6591. optionSet = true;
  6592. }
  6593. /* eslint-enable no-cond-assign */
  6594. }
  6595. // Force browsers to behave consistently when non-matching value is set
  6596. if ( !optionSet ) {
  6597. elem.selectedIndex = -1;
  6598. }
  6599. return values;
  6600. }
  6601. }
  6602. }
  6603. } );
  6604. // Radios and checkboxes getter/setter
  6605. jQuery.each( [ "radio", "checkbox" ], function() {
  6606. jQuery.valHooks[ this ] = {
  6607. set: function( elem, value ) {
  6608. if ( Array.isArray( value ) ) {
  6609. return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
  6610. }
  6611. }
  6612. };
  6613. if ( !support.checkOn ) {
  6614. jQuery.valHooks[ this ].get = function( elem ) {
  6615. return elem.getAttribute( "value" ) === null ? "on" : elem.value;
  6616. };
  6617. }
  6618. } );
  6619. // Return jQuery for attributes-only inclusion
  6620. var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
  6621. jQuery.extend( jQuery.event, {
  6622. trigger: function( event, data, elem, onlyHandlers ) {
  6623. var i, cur, tmp, bubbleType, ontype, handle, special,
  6624. eventPath = [ elem || document ],
  6625. type = hasOwn.call( event, "type" ) ? event.type : event,
  6626. namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
  6627. cur = tmp = elem = elem || document;
  6628. // Don't do events on text and comment nodes
  6629. if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
  6630. return;
  6631. }
  6632. // focus/blur morphs to focusin/out; ensure we're not firing them right now
  6633. if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
  6634. return;
  6635. }
  6636. if ( type.indexOf( "." ) > -1 ) {
  6637. // Namespaced trigger; create a regexp to match event type in handle()
  6638. namespaces = type.split( "." );
  6639. type = namespaces.shift();
  6640. namespaces.sort();
  6641. }
  6642. ontype = type.indexOf( ":" ) < 0 && "on" + type;
  6643. // Caller can pass in a jQuery.Event object, Object, or just an event type string
  6644. event = event[ jQuery.expando ] ?
  6645. event :
  6646. new jQuery.Event( type, typeof event === "object" && event );
  6647. // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
  6648. event.isTrigger = onlyHandlers ? 2 : 3;
  6649. event.namespace = namespaces.join( "." );
  6650. event.rnamespace = event.namespace ?
  6651. new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
  6652. null;
  6653. // Clean up the event in case it is being reused
  6654. event.result = undefined;
  6655. if ( !event.target ) {
  6656. event.target = elem;
  6657. }
  6658. // Clone any incoming data and prepend the event, creating the handler arg list
  6659. data = data == null ?
  6660. [ event ] :
  6661. jQuery.makeArray( data, [ event ] );
  6662. // Allow special events to draw outside the lines
  6663. special = jQuery.event.special[ type ] || {};
  6664. if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
  6665. return;
  6666. }
  6667. // Determine event propagation path in advance, per W3C events spec (#9951)
  6668. // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
  6669. if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
  6670. bubbleType = special.delegateType || type;
  6671. if ( !rfocusMorph.test( bubbleType + type ) ) {
  6672. cur = cur.parentNode;
  6673. }
  6674. for ( ; cur; cur = cur.parentNode ) {
  6675. eventPath.push( cur );
  6676. tmp = cur;
  6677. }
  6678. // Only add window if we got to document (e.g., not plain obj or detached DOM)
  6679. if ( tmp === ( elem.ownerDocument || document ) ) {
  6680. eventPath.push( tmp.defaultView || tmp.parentWindow || window );
  6681. }
  6682. }
  6683. // Fire handlers on the event path
  6684. i = 0;
  6685. while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
  6686. event.type = i > 1 ?
  6687. bubbleType :
  6688. special.bindType || type;
  6689. // jQuery handler
  6690. handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
  6691. dataPriv.get( cur, "handle" );
  6692. if ( handle ) {
  6693. handle.apply( cur, data );
  6694. }
  6695. // Native handler
  6696. handle = ontype && cur[ ontype ];
  6697. if ( handle && handle.apply && acceptData( cur ) ) {
  6698. event.result = handle.apply( cur, data );
  6699. if ( event.result === false ) {
  6700. event.preventDefault();
  6701. }
  6702. }
  6703. }
  6704. event.type = type;
  6705. // If nobody prevented the default action, do it now
  6706. if ( !onlyHandlers && !event.isDefaultPrevented() ) {
  6707. if ( ( !special._default ||
  6708. special._default.apply( eventPath.pop(), data ) === false ) &&
  6709. acceptData( elem ) ) {
  6710. // Call a native DOM method on the target with the same name as the event.
  6711. // Don't do default actions on window, that's where global variables be (#6170)
  6712. if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
  6713. // Don't re-trigger an onFOO event when we call its FOO() method
  6714. tmp = elem[ ontype ];
  6715. if ( tmp ) {
  6716. elem[ ontype ] = null;
  6717. }
  6718. // Prevent re-triggering of the same event, since we already bubbled it above
  6719. jQuery.event.triggered = type;
  6720. elem[ type ]();
  6721. jQuery.event.triggered = undefined;
  6722. if ( tmp ) {
  6723. elem[ ontype ] = tmp;
  6724. }
  6725. }
  6726. }
  6727. }
  6728. return event.result;
  6729. },
  6730. // Piggyback on a donor event to simulate a different one
  6731. // Used only for `focus(in | out)` events
  6732. simulate: function( type, elem, event ) {
  6733. var e = jQuery.extend(
  6734. new jQuery.Event(),
  6735. event,
  6736. {
  6737. type: type,
  6738. isSimulated: true
  6739. }
  6740. );
  6741. jQuery.event.trigger( e, null, elem );
  6742. }
  6743. } );
  6744. jQuery.fn.extend( {
  6745. trigger: function( type, data ) {
  6746. return this.each( function() {
  6747. jQuery.event.trigger( type, data, this );
  6748. } );
  6749. },
  6750. triggerHandler: function( type, data ) {
  6751. var elem = this[ 0 ];
  6752. if ( elem ) {
  6753. return jQuery.event.trigger( type, data, elem, true );
  6754. }
  6755. }
  6756. } );
  6757. jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
  6758. "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
  6759. "change select submit keydown keypress keyup contextmenu" ).split( " " ),
  6760. function( i, name ) {
  6761. // Handle event binding
  6762. jQuery.fn[ name ] = function( data, fn ) {
  6763. return arguments.length > 0 ?
  6764. this.on( name, null, data, fn ) :
  6765. this.trigger( name );
  6766. };
  6767. } );
  6768. jQuery.fn.extend( {
  6769. hover: function( fnOver, fnOut ) {
  6770. return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
  6771. }
  6772. } );
  6773. support.focusin = "onfocusin" in window;
  6774. // Support: Firefox <=44
  6775. // Firefox doesn't have focus(in | out) events
  6776. // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
  6777. //
  6778. // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
  6779. // focus(in | out) events fire after focus & blur events,
  6780. // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
  6781. // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
  6782. if ( !support.focusin ) {
  6783. jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
  6784. // Attach a single capturing handler on the document while someone wants focusin/focusout
  6785. var handler = function( event ) {
  6786. jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
  6787. };
  6788. jQuery.event.special[ fix ] = {
  6789. setup: function() {
  6790. var doc = this.ownerDocument || this,
  6791. attaches = dataPriv.access( doc, fix );
  6792. if ( !attaches ) {
  6793. doc.addEventListener( orig, handler, true );
  6794. }
  6795. dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
  6796. },
  6797. teardown: function() {
  6798. var doc = this.ownerDocument || this,
  6799. attaches = dataPriv.access( doc, fix ) - 1;
  6800. if ( !attaches ) {
  6801. doc.removeEventListener( orig, handler, true );
  6802. dataPriv.remove( doc, fix );
  6803. } else {
  6804. dataPriv.access( doc, fix, attaches );
  6805. }
  6806. }
  6807. };
  6808. } );
  6809. }
  6810. var location = window.location;
  6811. var nonce = jQuery.now();
  6812. var rquery = ( /\?/ );
  6813. // Cross-browser xml parsing
  6814. jQuery.parseXML = function( data ) {
  6815. var xml;
  6816. if ( !data || typeof data !== "string" ) {
  6817. return null;
  6818. }
  6819. // Support: IE 9 - 11 only
  6820. // IE throws on parseFromString with invalid input.
  6821. try {
  6822. xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
  6823. } catch ( e ) {
  6824. xml = undefined;
  6825. }
  6826. if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
  6827. jQuery.error( "Invalid XML: " + data );
  6828. }
  6829. return xml;
  6830. };
  6831. var
  6832. rbracket = /\[\]$/,
  6833. rCRLF = /\r?\n/g,
  6834. rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
  6835. rsubmittable = /^(?:input|select|textarea|keygen)/i;
  6836. function buildParams( prefix, obj, traditional, add ) {
  6837. var name;
  6838. if ( Array.isArray( obj ) ) {
  6839. // Serialize array item.
  6840. jQuery.each( obj, function( i, v ) {
  6841. if ( traditional || rbracket.test( prefix ) ) {
  6842. // Treat each array item as a scalar.
  6843. add( prefix, v );
  6844. } else {
  6845. // Item is non-scalar (array or object), encode its numeric index.
  6846. buildParams(
  6847. prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
  6848. v,
  6849. traditional,
  6850. add
  6851. );
  6852. }
  6853. } );
  6854. } else if ( !traditional && jQuery.type( obj ) === "object" ) {
  6855. // Serialize object item.
  6856. for ( name in obj ) {
  6857. buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
  6858. }
  6859. } else {
  6860. // Serialize scalar item.
  6861. add( prefix, obj );
  6862. }
  6863. }
  6864. // Serialize an array of form elements or a set of
  6865. // key/values into a query string
  6866. jQuery.param = function( a, traditional ) {
  6867. var prefix,
  6868. s = [],
  6869. add = function( key, valueOrFunction ) {
  6870. // If value is a function, invoke it and use its return value
  6871. var value = jQuery.isFunction( valueOrFunction ) ?
  6872. valueOrFunction() :
  6873. valueOrFunction;
  6874. s[ s.length ] = encodeURIComponent( key ) + "=" +
  6875. encodeURIComponent( value == null ? "" : value );
  6876. };
  6877. // If an array was passed in, assume that it is an array of form elements.
  6878. if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
  6879. // Serialize the form elements
  6880. jQuery.each( a, function() {
  6881. add( this.name, this.value );
  6882. } );
  6883. } else {
  6884. // If traditional, encode the "old" way (the way 1.3.2 or older
  6885. // did it), otherwise encode params recursively.
  6886. for ( prefix in a ) {
  6887. buildParams( prefix, a[ prefix ], traditional, add );
  6888. }
  6889. }
  6890. // Return the resulting serialization
  6891. return s.join( "&" );
  6892. };
  6893. jQuery.fn.extend( {
  6894. serialize: function() {
  6895. return jQuery.param( this.serializeArray() );
  6896. },
  6897. serializeArray: function() {
  6898. return this.map( function() {
  6899. // Can add propHook for "elements" to filter or add form elements
  6900. var elements = jQuery.prop( this, "elements" );
  6901. return elements ? jQuery.makeArray( elements ) : this;
  6902. } )
  6903. .filter( function() {
  6904. var type = this.type;
  6905. // Use .is( ":disabled" ) so that fieldset[disabled] works
  6906. return this.name && !jQuery( this ).is( ":disabled" ) &&
  6907. rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
  6908. ( this.checked || !rcheckableType.test( type ) );
  6909. } )
  6910. .map( function( i, elem ) {
  6911. var val = jQuery( this ).val();
  6912. if ( val == null ) {
  6913. return null;
  6914. }
  6915. if ( Array.isArray( val ) ) {
  6916. return jQuery.map( val, function( val ) {
  6917. return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
  6918. } );
  6919. }
  6920. return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
  6921. } ).get();
  6922. }
  6923. } );
  6924. var
  6925. r20 = /%20/g,
  6926. rhash = /#.*$/,
  6927. rantiCache = /([?&])_=[^&]*/,
  6928. rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
  6929. // #7653, #8125, #8152: local protocol detection
  6930. rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
  6931. rnoContent = /^(?:GET|HEAD)$/,
  6932. rprotocol = /^\/\//,
  6933. /* Prefilters
  6934. * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
  6935. * 2) These are called:
  6936. * - BEFORE asking for a transport
  6937. * - AFTER param serialization (s.data is a string if s.processData is true)
  6938. * 3) key is the dataType
  6939. * 4) the catchall symbol "*" can be used
  6940. * 5) execution will start with transport dataType and THEN continue down to "*" if needed
  6941. */
  6942. prefilters = {},
  6943. /* Transports bindings
  6944. * 1) key is the dataType
  6945. * 2) the catchall symbol "*" can be used
  6946. * 3) selection will start with transport dataType and THEN go to "*" if needed
  6947. */
  6948. transports = {},
  6949. // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
  6950. allTypes = "*/".concat( "*" ),
  6951. // Anchor tag for parsing the document origin
  6952. originAnchor = document.createElement( "a" );
  6953. originAnchor.href = location.href;
  6954. // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
  6955. function addToPrefiltersOrTransports( structure ) {
  6956. // dataTypeExpression is optional and defaults to "*"
  6957. return function( dataTypeExpression, func ) {
  6958. if ( typeof dataTypeExpression !== "string" ) {
  6959. func = dataTypeExpression;
  6960. dataTypeExpression = "*";
  6961. }
  6962. var dataType,
  6963. i = 0,
  6964. dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
  6965. if ( jQuery.isFunction( func ) ) {
  6966. // For each dataType in the dataTypeExpression
  6967. while ( ( dataType = dataTypes[ i++ ] ) ) {
  6968. // Prepend if requested
  6969. if ( dataType[ 0 ] === "+" ) {
  6970. dataType = dataType.slice( 1 ) || "*";
  6971. ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
  6972. // Otherwise append
  6973. } else {
  6974. ( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
  6975. }
  6976. }
  6977. }
  6978. };
  6979. }
  6980. // Base inspection function for prefilters and transports
  6981. function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
  6982. var inspected = {},
  6983. seekingTransport = ( structure === transports );
  6984. function inspect( dataType ) {
  6985. var selected;
  6986. inspected[ dataType ] = true;
  6987. jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
  6988. var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
  6989. if ( typeof dataTypeOrTransport === "string" &&
  6990. !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
  6991. options.dataTypes.unshift( dataTypeOrTransport );
  6992. inspect( dataTypeOrTransport );
  6993. return false;
  6994. } else if ( seekingTransport ) {
  6995. return !( selected = dataTypeOrTransport );
  6996. }
  6997. } );
  6998. return selected;
  6999. }
  7000. return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
  7001. }
  7002. // A special extend for ajax options
  7003. // that takes "flat" options (not to be deep extended)
  7004. // Fixes #9887
  7005. function ajaxExtend( target, src ) {
  7006. var key, deep,
  7007. flatOptions = jQuery.ajaxSettings.flatOptions || {};
  7008. for ( key in src ) {
  7009. if ( src[ key ] !== undefined ) {
  7010. ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
  7011. }
  7012. }
  7013. if ( deep ) {
  7014. jQuery.extend( true, target, deep );
  7015. }
  7016. return target;
  7017. }
  7018. /* Handles responses to an ajax request:
  7019. * - finds the right dataType (mediates between content-type and expected dataType)
  7020. * - returns the corresponding response
  7021. */
  7022. function ajaxHandleResponses( s, jqXHR, responses ) {
  7023. var ct, type, finalDataType, firstDataType,
  7024. contents = s.contents,
  7025. dataTypes = s.dataTypes;
  7026. // Remove auto dataType and get content-type in the process
  7027. while ( dataTypes[ 0 ] === "*" ) {
  7028. dataTypes.shift();
  7029. if ( ct === undefined ) {
  7030. ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
  7031. }
  7032. }
  7033. // Check if we're dealing with a known content-type
  7034. if ( ct ) {
  7035. for ( type in contents ) {
  7036. if ( contents[ type ] && contents[ type ].test( ct ) ) {
  7037. dataTypes.unshift( type );
  7038. break;
  7039. }
  7040. }
  7041. }
  7042. // Check to see if we have a response for the expected dataType
  7043. if ( dataTypes[ 0 ] in responses ) {
  7044. finalDataType = dataTypes[ 0 ];
  7045. } else {
  7046. // Try convertible dataTypes
  7047. for ( type in responses ) {
  7048. if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
  7049. finalDataType = type;
  7050. break;
  7051. }
  7052. if ( !firstDataType ) {
  7053. firstDataType = type;
  7054. }
  7055. }
  7056. // Or just use first one
  7057. finalDataType = finalDataType || firstDataType;
  7058. }
  7059. // If we found a dataType
  7060. // We add the dataType to the list if needed
  7061. // and return the corresponding response
  7062. if ( finalDataType ) {
  7063. if ( finalDataType !== dataTypes[ 0 ] ) {
  7064. dataTypes.unshift( finalDataType );
  7065. }
  7066. return responses[ finalDataType ];
  7067. }
  7068. }
  7069. /* Chain conversions given the request and the original response
  7070. * Also sets the responseXXX fields on the jqXHR instance
  7071. */
  7072. function ajaxConvert( s, response, jqXHR, isSuccess ) {
  7073. var conv2, current, conv, tmp, prev,
  7074. converters = {},
  7075. // Work with a copy of dataTypes in case we need to modify it for conversion
  7076. dataTypes = s.dataTypes.slice();
  7077. // Create converters map with lowercased keys
  7078. if ( dataTypes[ 1 ] ) {
  7079. for ( conv in s.converters ) {
  7080. converters[ conv.toLowerCase() ] = s.converters[ conv ];
  7081. }
  7082. }
  7083. current = dataTypes.shift();
  7084. // Convert to each sequential dataType
  7085. while ( current ) {
  7086. if ( s.responseFields[ current ] ) {
  7087. jqXHR[ s.responseFields[ current ] ] = response;
  7088. }
  7089. // Apply the dataFilter if provided
  7090. if ( !prev && isSuccess && s.dataFilter ) {
  7091. response = s.dataFilter( response, s.dataType );
  7092. }
  7093. prev = current;
  7094. current = dataTypes.shift();
  7095. if ( current ) {
  7096. // There's only work to do if current dataType is non-auto
  7097. if ( current === "*" ) {
  7098. current = prev;
  7099. // Convert response if prev dataType is non-auto and differs from current
  7100. } else if ( prev !== "*" && prev !== current ) {
  7101. // Seek a direct converter
  7102. conv = converters[ prev + " " + current ] || converters[ "* " + current ];
  7103. // If none found, seek a pair
  7104. if ( !conv ) {
  7105. for ( conv2 in converters ) {
  7106. // If conv2 outputs current
  7107. tmp = conv2.split( " " );
  7108. if ( tmp[ 1 ] === current ) {
  7109. // If prev can be converted to accepted input
  7110. conv = converters[ prev + " " + tmp[ 0 ] ] ||
  7111. converters[ "* " + tmp[ 0 ] ];
  7112. if ( conv ) {
  7113. // Condense equivalence converters
  7114. if ( conv === true ) {
  7115. conv = converters[ conv2 ];
  7116. // Otherwise, insert the intermediate dataType
  7117. } else if ( converters[ conv2 ] !== true ) {
  7118. current = tmp[ 0 ];
  7119. dataTypes.unshift( tmp[ 1 ] );
  7120. }
  7121. break;
  7122. }
  7123. }
  7124. }
  7125. }
  7126. // Apply converter (if not an equivalence)
  7127. if ( conv !== true ) {
  7128. // Unless errors are allowed to bubble, catch and return them
  7129. if ( conv && s.throws ) {
  7130. response = conv( response );
  7131. } else {
  7132. try {
  7133. response = conv( response );
  7134. } catch ( e ) {
  7135. return {
  7136. state: "parsererror",
  7137. error: conv ? e : "No conversion from " + prev + " to " + current
  7138. };
  7139. }
  7140. }
  7141. }
  7142. }
  7143. }
  7144. }
  7145. return { state: "success", data: response };
  7146. }
  7147. jQuery.extend( {
  7148. // Counter for holding the number of active queries
  7149. active: 0,
  7150. // Last-Modified header cache for next request
  7151. lastModified: {},
  7152. etag: {},
  7153. ajaxSettings: {
  7154. url: location.href,
  7155. type: "GET",
  7156. isLocal: rlocalProtocol.test( location.protocol ),
  7157. global: true,
  7158. processData: true,
  7159. async: true,
  7160. contentType: "application/x-www-form-urlencoded; charset=UTF-8",
  7161. /*
  7162. timeout: 0,
  7163. data: null,
  7164. dataType: null,
  7165. username: null,
  7166. password: null,
  7167. cache: null,
  7168. throws: false,
  7169. traditional: false,
  7170. headers: {},
  7171. */
  7172. accepts: {
  7173. "*": allTypes,
  7174. text: "text/plain",
  7175. html: "text/html",
  7176. xml: "application/xml, text/xml",
  7177. json: "application/json, text/javascript"
  7178. },
  7179. contents: {
  7180. xml: /\bxml\b/,
  7181. html: /\bhtml/,
  7182. json: /\bjson\b/
  7183. },
  7184. responseFields: {
  7185. xml: "responseXML",
  7186. text: "responseText",
  7187. json: "responseJSON"
  7188. },
  7189. // Data converters
  7190. // Keys separate source (or catchall "*") and destination types with a single space
  7191. converters: {
  7192. // Convert anything to text
  7193. "* text": String,
  7194. // Text to html (true = no transformation)
  7195. "text html": true,
  7196. // Evaluate text as a json expression
  7197. "text json": JSON.parse,
  7198. // Parse text as xml
  7199. "text xml": jQuery.parseXML
  7200. },
  7201. // For options that shouldn't be deep extended:
  7202. // you can add your own custom options here if
  7203. // and when you create one that shouldn't be
  7204. // deep extended (see ajaxExtend)
  7205. flatOptions: {
  7206. url: true,
  7207. context: true
  7208. }
  7209. },
  7210. // Creates a full fledged settings object into target
  7211. // with both ajaxSettings and settings fields.
  7212. // If target is omitted, writes into ajaxSettings.
  7213. ajaxSetup: function( target, settings ) {
  7214. return settings ?
  7215. // Building a settings object
  7216. ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
  7217. // Extending ajaxSettings
  7218. ajaxExtend( jQuery.ajaxSettings, target );
  7219. },
  7220. ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
  7221. ajaxTransport: addToPrefiltersOrTransports( transports ),
  7222. // Main method
  7223. ajax: function( url, options ) {
  7224. // If url is an object, simulate pre-1.5 signature
  7225. if ( typeof url === "object" ) {
  7226. options = url;
  7227. url = undefined;
  7228. }
  7229. // Force options to be an object
  7230. options = options || {};
  7231. var transport,
  7232. // URL without anti-cache param
  7233. cacheURL,
  7234. // Response headers
  7235. responseHeadersString,
  7236. responseHeaders,
  7237. // timeout handle
  7238. timeoutTimer,
  7239. // Url cleanup var
  7240. urlAnchor,
  7241. // Request state (becomes false upon send and true upon completion)
  7242. completed,
  7243. // To know if global events are to be dispatched
  7244. fireGlobals,
  7245. // Loop variable
  7246. i,
  7247. // uncached part of the url
  7248. uncached,
  7249. // Create the final options object
  7250. s = jQuery.ajaxSetup( {}, options ),
  7251. // Callbacks context
  7252. callbackContext = s.context || s,
  7253. // Context for global events is callbackContext if it is a DOM node or jQuery collection
  7254. globalEventContext = s.context &&
  7255. ( callbackContext.nodeType || callbackContext.jquery ) ?
  7256. jQuery( callbackContext ) :
  7257. jQuery.event,
  7258. // Deferreds
  7259. deferred = jQuery.Deferred(),
  7260. completeDeferred = jQuery.Callbacks( "once memory" ),
  7261. // Status-dependent callbacks
  7262. statusCode = s.statusCode || {},
  7263. // Headers (they are sent all at once)
  7264. requestHeaders = {},
  7265. requestHeadersNames = {},
  7266. // Default abort message
  7267. strAbort = "canceled",
  7268. // Fake xhr
  7269. jqXHR = {
  7270. readyState: 0,
  7271. // Builds headers hashtable if needed
  7272. getResponseHeader: function( key ) {
  7273. var match;
  7274. if ( completed ) {
  7275. if ( !responseHeaders ) {
  7276. responseHeaders = {};
  7277. while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
  7278. responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
  7279. }
  7280. }
  7281. match = responseHeaders[ key.toLowerCase() ];
  7282. }
  7283. return match == null ? null : match;
  7284. },
  7285. // Raw string
  7286. getAllResponseHeaders: function() {
  7287. return completed ? responseHeadersString : null;
  7288. },
  7289. // Caches the header
  7290. setRequestHeader: function( name, value ) {
  7291. if ( completed == null ) {
  7292. name = requestHeadersNames[ name.toLowerCase() ] =
  7293. requestHeadersNames[ name.toLowerCase() ] || name;
  7294. requestHeaders[ name ] = value;
  7295. }
  7296. return this;
  7297. },
  7298. // Overrides response content-type header
  7299. overrideMimeType: function( type ) {
  7300. if ( completed == null ) {
  7301. s.mimeType = type;
  7302. }
  7303. return this;
  7304. },
  7305. // Status-dependent callbacks
  7306. statusCode: function( map ) {
  7307. var code;
  7308. if ( map ) {
  7309. if ( completed ) {
  7310. // Execute the appropriate callbacks
  7311. jqXHR.always( map[ jqXHR.status ] );
  7312. } else {
  7313. // Lazy-add the new callbacks in a way that preserves old ones
  7314. for ( code in map ) {
  7315. statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
  7316. }
  7317. }
  7318. }
  7319. return this;
  7320. },
  7321. // Cancel the request
  7322. abort: function( statusText ) {
  7323. var finalText = statusText || strAbort;
  7324. if ( transport ) {
  7325. transport.abort( finalText );
  7326. }
  7327. done( 0, finalText );
  7328. return this;
  7329. }
  7330. };
  7331. // Attach deferreds
  7332. deferred.promise( jqXHR );
  7333. // Add protocol if not provided (prefilters might expect it)
  7334. // Handle falsy url in the settings object (#10093: consistency with old signature)
  7335. // We also use the url parameter if available
  7336. s.url = ( ( url || s.url || location.href ) + "" )
  7337. .replace( rprotocol, location.protocol + "//" );
  7338. // Alias method option to type as per ticket #12004
  7339. s.type = options.method || options.type || s.method || s.type;
  7340. // Extract dataTypes list
  7341. s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
  7342. // A cross-domain request is in order when the origin doesn't match the current origin.
  7343. if ( s.crossDomain == null ) {
  7344. urlAnchor = document.createElement( "a" );
  7345. // Support: IE <=8 - 11, Edge 12 - 13
  7346. // IE throws exception on accessing the href property if url is malformed,
  7347. // e.g. http://example.com:80x/
  7348. try {
  7349. urlAnchor.href = s.url;
  7350. // Support: IE <=8 - 11 only
  7351. // Anchor's host property isn't correctly set when s.url is relative
  7352. urlAnchor.href = urlAnchor.href;
  7353. s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
  7354. urlAnchor.protocol + "//" + urlAnchor.host;
  7355. } catch ( e ) {
  7356. // If there is an error parsing the URL, assume it is crossDomain,
  7357. // it can be rejected by the transport if it is invalid
  7358. s.crossDomain = true;
  7359. }
  7360. }
  7361. // Convert data if not already a string
  7362. if ( s.data && s.processData && typeof s.data !== "string" ) {
  7363. s.data = jQuery.param( s.data, s.traditional );
  7364. }
  7365. // Apply prefilters
  7366. inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
  7367. // If request was aborted inside a prefilter, stop there
  7368. if ( completed ) {
  7369. return jqXHR;
  7370. }
  7371. // We can fire global events as of now if asked to
  7372. // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
  7373. fireGlobals = jQuery.event && s.global;
  7374. // Watch for a new set of requests
  7375. if ( fireGlobals && jQuery.active++ === 0 ) {
  7376. jQuery.event.trigger( "ajaxStart" );
  7377. }
  7378. // Uppercase the type
  7379. s.type = s.type.toUpperCase();
  7380. // Determine if request has content
  7381. s.hasContent = !rnoContent.test( s.type );
  7382. // Save the URL in case we're toying with the If-Modified-Since
  7383. // and/or If-None-Match header later on
  7384. // Remove hash to simplify url manipulation
  7385. cacheURL = s.url.replace( rhash, "" );
  7386. // More options handling for requests with no content
  7387. if ( !s.hasContent ) {
  7388. // Remember the hash so we can put it back
  7389. uncached = s.url.slice( cacheURL.length );
  7390. // If data is available, append data to url
  7391. if ( s.data ) {
  7392. cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
  7393. // #9682: remove data so that it's not used in an eventual retry
  7394. delete s.data;
  7395. }
  7396. // Add or update anti-cache param if needed
  7397. if ( s.cache === false ) {
  7398. cacheURL = cacheURL.replace( rantiCache, "$1" );
  7399. uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
  7400. }
  7401. // Put hash and anti-cache on the URL that will be requested (gh-1732)
  7402. s.url = cacheURL + uncached;
  7403. // Change '%20' to '+' if this is encoded form body content (gh-2658)
  7404. } else if ( s.data && s.processData &&
  7405. ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
  7406. s.data = s.data.replace( r20, "+" );
  7407. }
  7408. // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  7409. if ( s.ifModified ) {
  7410. if ( jQuery.lastModified[ cacheURL ] ) {
  7411. jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
  7412. }
  7413. if ( jQuery.etag[ cacheURL ] ) {
  7414. jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
  7415. }
  7416. }
  7417. // Set the correct header, if data is being sent
  7418. if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
  7419. jqXHR.setRequestHeader( "Content-Type", s.contentType );
  7420. }
  7421. // Set the Accepts header for the server, depending on the dataType
  7422. jqXHR.setRequestHeader(
  7423. "Accept",
  7424. s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
  7425. s.accepts[ s.dataTypes[ 0 ] ] +
  7426. ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
  7427. s.accepts[ "*" ]
  7428. );
  7429. // Check for headers option
  7430. for ( i in s.headers ) {
  7431. jqXHR.setRequestHeader( i, s.headers[ i ] );
  7432. }
  7433. // Allow custom headers/mimetypes and early abort
  7434. if ( s.beforeSend &&
  7435. ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
  7436. // Abort if not done already and return
  7437. return jqXHR.abort();
  7438. }
  7439. // Aborting is no longer a cancellation
  7440. strAbort = "abort";
  7441. // Install callbacks on deferreds
  7442. completeDeferred.add( s.complete );
  7443. jqXHR.done( s.success );
  7444. jqXHR.fail( s.error );
  7445. // Get transport
  7446. transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
  7447. // If no transport, we auto-abort
  7448. if ( !transport ) {
  7449. done( -1, "No Transport" );
  7450. } else {
  7451. jqXHR.readyState = 1;
  7452. // Send global event
  7453. if ( fireGlobals ) {
  7454. globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
  7455. }
  7456. // If request was aborted inside ajaxSend, stop there
  7457. if ( completed ) {
  7458. return jqXHR;
  7459. }
  7460. // Timeout
  7461. if ( s.async && s.timeout > 0 ) {
  7462. timeoutTimer = window.setTimeout( function() {
  7463. jqXHR.abort( "timeout" );
  7464. }, s.timeout );
  7465. }
  7466. try {
  7467. completed = false;
  7468. transport.send( requestHeaders, done );
  7469. } catch ( e ) {
  7470. // Rethrow post-completion exceptions
  7471. if ( completed ) {
  7472. throw e;
  7473. }
  7474. // Propagate others as results
  7475. done( -1, e );
  7476. }
  7477. }
  7478. // Callback for when everything is done
  7479. function done( status, nativeStatusText, responses, headers ) {
  7480. var isSuccess, success, error, response, modified,
  7481. statusText = nativeStatusText;
  7482. // Ignore repeat invocations
  7483. if ( completed ) {
  7484. return;
  7485. }
  7486. completed = true;
  7487. // Clear timeout if it exists
  7488. if ( timeoutTimer ) {
  7489. window.clearTimeout( timeoutTimer );
  7490. }
  7491. // Dereference transport for early garbage collection
  7492. // (no matter how long the jqXHR object will be used)
  7493. transport = undefined;
  7494. // Cache response headers
  7495. responseHeadersString = headers || "";
  7496. // Set readyState
  7497. jqXHR.readyState = status > 0 ? 4 : 0;
  7498. // Determine if successful
  7499. isSuccess = status >= 200 && status < 300 || status === 304;
  7500. // Get response data
  7501. if ( responses ) {
  7502. response = ajaxHandleResponses( s, jqXHR, responses );
  7503. }
  7504. // Convert no matter what (that way responseXXX fields are always set)
  7505. response = ajaxConvert( s, response, jqXHR, isSuccess );
  7506. // If successful, handle type chaining
  7507. if ( isSuccess ) {
  7508. // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  7509. if ( s.ifModified ) {
  7510. modified = jqXHR.getResponseHeader( "Last-Modified" );
  7511. if ( modified ) {
  7512. jQuery.lastModified[ cacheURL ] = modified;
  7513. }
  7514. modified = jqXHR.getResponseHeader( "etag" );
  7515. if ( modified ) {
  7516. jQuery.etag[ cacheURL ] = modified;
  7517. }
  7518. }
  7519. // if no content
  7520. if ( status === 204 || s.type === "HEAD" ) {
  7521. statusText = "nocontent";
  7522. // if not modified
  7523. } else if ( status === 304 ) {
  7524. statusText = "notmodified";
  7525. // If we have data, let's convert it
  7526. } else {
  7527. statusText = response.state;
  7528. success = response.data;
  7529. error = response.error;
  7530. isSuccess = !error;
  7531. }
  7532. } else {
  7533. // Extract error from statusText and normalize for non-aborts
  7534. error = statusText;
  7535. if ( status || !statusText ) {
  7536. statusText = "error";
  7537. if ( status < 0 ) {
  7538. status = 0;
  7539. }
  7540. }
  7541. }
  7542. // Set data for the fake xhr object
  7543. jqXHR.status = status;
  7544. jqXHR.statusText = ( nativeStatusText || statusText ) + "";
  7545. // Success/Error
  7546. if ( isSuccess ) {
  7547. deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
  7548. } else {
  7549. deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
  7550. }
  7551. // Status-dependent callbacks
  7552. jqXHR.statusCode( statusCode );
  7553. statusCode = undefined;
  7554. if ( fireGlobals ) {
  7555. globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
  7556. [ jqXHR, s, isSuccess ? success : error ] );
  7557. }
  7558. // Complete
  7559. completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
  7560. if ( fireGlobals ) {
  7561. globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
  7562. // Handle the global AJAX counter
  7563. if ( !( --jQuery.active ) ) {
  7564. jQuery.event.trigger( "ajaxStop" );
  7565. }
  7566. }
  7567. }
  7568. return jqXHR;
  7569. },
  7570. getJSON: function( url, data, callback ) {
  7571. return jQuery.get( url, data, callback, "json" );
  7572. },
  7573. getScript: function( url, callback ) {
  7574. return jQuery.get( url, undefined, callback, "script" );
  7575. }
  7576. } );
  7577. jQuery.each( [ "get", "post" ], function( i, method ) {
  7578. jQuery[ method ] = function( url, data, callback, type ) {
  7579. // Shift arguments if data argument was omitted
  7580. if ( jQuery.isFunction( data ) ) {
  7581. type = type || callback;
  7582. callback = data;
  7583. data = undefined;
  7584. }
  7585. // The url can be an options object (which then must have .url)
  7586. return jQuery.ajax( jQuery.extend( {
  7587. url: url,
  7588. type: method,
  7589. dataType: type,
  7590. data: data,
  7591. success: callback
  7592. }, jQuery.isPlainObject( url ) && url ) );
  7593. };
  7594. } );
  7595. jQuery._evalUrl = function( url ) {
  7596. return jQuery.ajax( {
  7597. url: url,
  7598. // Make this explicit, since user can override this through ajaxSetup (#11264)
  7599. type: "GET",
  7600. dataType: "script",
  7601. cache: true,
  7602. async: false,
  7603. global: false,
  7604. "throws": true
  7605. } );
  7606. };
  7607. jQuery.fn.extend( {
  7608. wrapAll: function( html ) {
  7609. var wrap;
  7610. if ( this[ 0 ] ) {
  7611. if ( jQuery.isFunction( html ) ) {
  7612. html = html.call( this[ 0 ] );
  7613. }
  7614. // The elements to wrap the target around
  7615. wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
  7616. if ( this[ 0 ].parentNode ) {
  7617. wrap.insertBefore( this[ 0 ] );
  7618. }
  7619. wrap.map( function() {
  7620. var elem = this;
  7621. while ( elem.firstElementChild ) {
  7622. elem = elem.firstElementChild;
  7623. }
  7624. return elem;
  7625. } ).append( this );
  7626. }
  7627. return this;
  7628. },
  7629. wrapInner: function( html ) {
  7630. if ( jQuery.isFunction( html ) ) {
  7631. return this.each( function( i ) {
  7632. jQuery( this ).wrapInner( html.call( this, i ) );
  7633. } );
  7634. }
  7635. return this.each( function() {
  7636. var self = jQuery( this ),
  7637. contents = self.contents();
  7638. if ( contents.length ) {
  7639. contents.wrapAll( html );
  7640. } else {
  7641. self.append( html );
  7642. }
  7643. } );
  7644. },
  7645. wrap: function( html ) {
  7646. var isFunction = jQuery.isFunction( html );
  7647. return this.each( function( i ) {
  7648. jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
  7649. } );
  7650. },
  7651. unwrap: function( selector ) {
  7652. this.parent( selector ).not( "body" ).each( function() {
  7653. jQuery( this ).replaceWith( this.childNodes );
  7654. } );
  7655. return this;
  7656. }
  7657. } );
  7658. jQuery.expr.pseudos.hidden = function( elem ) {
  7659. return !jQuery.expr.pseudos.visible( elem );
  7660. };
  7661. jQuery.expr.pseudos.visible = function( elem ) {
  7662. return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
  7663. };
  7664. jQuery.ajaxSettings.xhr = function() {
  7665. try {
  7666. return new window.XMLHttpRequest();
  7667. } catch ( e ) {}
  7668. };
  7669. var xhrSuccessStatus = {
  7670. // File protocol always yields status code 0, assume 200
  7671. 0: 200,
  7672. // Support: IE <=9 only
  7673. // #1450: sometimes IE returns 1223 when it should be 204
  7674. 1223: 204
  7675. },
  7676. xhrSupported = jQuery.ajaxSettings.xhr();
  7677. support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
  7678. support.ajax = xhrSupported = !!xhrSupported;
  7679. jQuery.ajaxTransport( function( options ) {
  7680. var callback, errorCallback;
  7681. // Cross domain only allowed if supported through XMLHttpRequest
  7682. if ( support.cors || xhrSupported && !options.crossDomain ) {
  7683. return {
  7684. send: function( headers, complete ) {
  7685. var i,
  7686. xhr = options.xhr();
  7687. xhr.open(
  7688. options.type,
  7689. options.url,
  7690. options.async,
  7691. options.username,
  7692. options.password
  7693. );
  7694. // Apply custom fields if provided
  7695. if ( options.xhrFields ) {
  7696. for ( i in options.xhrFields ) {
  7697. xhr[ i ] = options.xhrFields[ i ];
  7698. }
  7699. }
  7700. // Override mime type if needed
  7701. if ( options.mimeType && xhr.overrideMimeType ) {
  7702. xhr.overrideMimeType( options.mimeType );
  7703. }
  7704. // X-Requested-With header
  7705. // For cross-domain requests, seeing as conditions for a preflight are
  7706. // akin to a jigsaw puzzle, we simply never set it to be sure.
  7707. // (it can always be set on a per-request basis or even using ajaxSetup)
  7708. // For same-domain requests, won't change header if already provided.
  7709. if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
  7710. headers[ "X-Requested-With" ] = "XMLHttpRequest";
  7711. }
  7712. // Set headers
  7713. for ( i in headers ) {
  7714. xhr.setRequestHeader( i, headers[ i ] );
  7715. }
  7716. // Callback
  7717. callback = function( type ) {
  7718. return function() {
  7719. if ( callback ) {
  7720. callback = errorCallback = xhr.onload =
  7721. xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
  7722. if ( type === "abort" ) {
  7723. xhr.abort();
  7724. } else if ( type === "error" ) {
  7725. // Support: IE <=9 only
  7726. // On a manual native abort, IE9 throws
  7727. // errors on any property access that is not readyState
  7728. if ( typeof xhr.status !== "number" ) {
  7729. complete( 0, "error" );
  7730. } else {
  7731. complete(
  7732. // File: protocol always yields status 0; see #8605, #14207
  7733. xhr.status,
  7734. xhr.statusText
  7735. );
  7736. }
  7737. } else {
  7738. complete(
  7739. xhrSuccessStatus[ xhr.status ] || xhr.status,
  7740. xhr.statusText,
  7741. // Support: IE <=9 only
  7742. // IE9 has no XHR2 but throws on binary (trac-11426)
  7743. // For XHR2 non-text, let the caller handle it (gh-2498)
  7744. ( xhr.responseType || "text" ) !== "text" ||
  7745. typeof xhr.responseText !== "string" ?
  7746. { binary: xhr.response } :
  7747. { text: xhr.responseText },
  7748. xhr.getAllResponseHeaders()
  7749. );
  7750. }
  7751. }
  7752. };
  7753. };
  7754. // Listen to events
  7755. xhr.onload = callback();
  7756. errorCallback = xhr.onerror = callback( "error" );
  7757. // Support: IE 9 only
  7758. // Use onreadystatechange to replace onabort
  7759. // to handle uncaught aborts
  7760. if ( xhr.onabort !== undefined ) {
  7761. xhr.onabort = errorCallback;
  7762. } else {
  7763. xhr.onreadystatechange = function() {
  7764. // Check readyState before timeout as it changes
  7765. if ( xhr.readyState === 4 ) {
  7766. // Allow onerror to be called first,
  7767. // but that will not handle a native abort
  7768. // Also, save errorCallback to a variable
  7769. // as xhr.onerror cannot be accessed
  7770. window.setTimeout( function() {
  7771. if ( callback ) {
  7772. errorCallback();
  7773. }
  7774. } );
  7775. }
  7776. };
  7777. }
  7778. // Create the abort callback
  7779. callback = callback( "abort" );
  7780. try {
  7781. // Do send the request (this may raise an exception)
  7782. xhr.send( options.hasContent && options.data || null );
  7783. } catch ( e ) {
  7784. // #14683: Only rethrow if this hasn't been notified as an error yet
  7785. if ( callback ) {
  7786. throw e;
  7787. }
  7788. }
  7789. },
  7790. abort: function() {
  7791. if ( callback ) {
  7792. callback();
  7793. }
  7794. }
  7795. };
  7796. }
  7797. } );
  7798. // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
  7799. jQuery.ajaxPrefilter( function( s ) {
  7800. if ( s.crossDomain ) {
  7801. s.contents.script = false;
  7802. }
  7803. } );
  7804. // Install script dataType
  7805. jQuery.ajaxSetup( {
  7806. accepts: {
  7807. script: "text/javascript, application/javascript, " +
  7808. "application/ecmascript, application/x-ecmascript"
  7809. },
  7810. contents: {
  7811. script: /\b(?:java|ecma)script\b/
  7812. },
  7813. converters: {
  7814. "text script": function( text ) {
  7815. jQuery.globalEval( text );
  7816. return text;
  7817. }
  7818. }
  7819. } );
  7820. // Handle cache's special case and crossDomain
  7821. jQuery.ajaxPrefilter( "script", function( s ) {
  7822. if ( s.cache === undefined ) {
  7823. s.cache = false;
  7824. }
  7825. if ( s.crossDomain ) {
  7826. s.type = "GET";
  7827. }
  7828. } );
  7829. // Bind script tag hack transport
  7830. jQuery.ajaxTransport( "script", function( s ) {
  7831. // This transport only deals with cross domain requests
  7832. if ( s.crossDomain ) {
  7833. var script, callback;
  7834. return {
  7835. send: function( _, complete ) {
  7836. script = jQuery( "<script>" ).prop( {
  7837. charset: s.scriptCharset,
  7838. src: s.url
  7839. } ).on(
  7840. "load error",
  7841. callback = function( evt ) {
  7842. script.remove();
  7843. callback = null;
  7844. if ( evt ) {
  7845. complete( evt.type === "error" ? 404 : 200, evt.type );
  7846. }
  7847. }
  7848. );
  7849. // Use native DOM manipulation to avoid our domManip AJAX trickery
  7850. document.head.appendChild( script[ 0 ] );
  7851. },
  7852. abort: function() {
  7853. if ( callback ) {
  7854. callback();
  7855. }
  7856. }
  7857. };
  7858. }
  7859. } );
  7860. var oldCallbacks = [],
  7861. rjsonp = /(=)\?(?=&|$)|\?\?/;
  7862. // Default jsonp settings
  7863. jQuery.ajaxSetup( {
  7864. jsonp: "callback",
  7865. jsonpCallback: function() {
  7866. var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
  7867. this[ callback ] = true;
  7868. return callback;
  7869. }
  7870. } );
  7871. // Detect, normalize options and install callbacks for jsonp requests
  7872. jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
  7873. var callbackName, overwritten, responseContainer,
  7874. jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
  7875. "url" :
  7876. typeof s.data === "string" &&
  7877. ( s.contentType || "" )
  7878. .indexOf( "application/x-www-form-urlencoded" ) === 0 &&
  7879. rjsonp.test( s.data ) && "data"
  7880. );
  7881. // Handle iff the expected data type is "jsonp" or we have a parameter to set
  7882. if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
  7883. // Get callback name, remembering preexisting value associated with it
  7884. callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
  7885. s.jsonpCallback() :
  7886. s.jsonpCallback;
  7887. // Insert callback into url or form data
  7888. if ( jsonProp ) {
  7889. s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
  7890. } else if ( s.jsonp !== false ) {
  7891. s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
  7892. }
  7893. // Use data converter to retrieve json after script execution
  7894. s.converters[ "script json" ] = function() {
  7895. if ( !responseContainer ) {
  7896. jQuery.error( callbackName + " was not called" );
  7897. }
  7898. return responseContainer[ 0 ];
  7899. };
  7900. // Force json dataType
  7901. s.dataTypes[ 0 ] = "json";
  7902. // Install callback
  7903. overwritten = window[ callbackName ];
  7904. window[ callbackName ] = function() {
  7905. responseContainer = arguments;
  7906. };
  7907. // Clean-up function (fires after converters)
  7908. jqXHR.always( function() {
  7909. // If previous value didn't exist - remove it
  7910. if ( overwritten === undefined ) {
  7911. jQuery( window ).removeProp( callbackName );
  7912. // Otherwise restore preexisting value
  7913. } else {
  7914. window[ callbackName ] = overwritten;
  7915. }
  7916. // Save back as free
  7917. if ( s[ callbackName ] ) {
  7918. // Make sure that re-using the options doesn't screw things around
  7919. s.jsonpCallback = originalSettings.jsonpCallback;
  7920. // Save the callback name for future use
  7921. oldCallbacks.push( callbackName );
  7922. }
  7923. // Call if it was a function and we have a response
  7924. if ( responseContainer && jQuery.isFunction( overwritten ) ) {
  7925. overwritten( responseContainer[ 0 ] );
  7926. }
  7927. responseContainer = overwritten = undefined;
  7928. } );
  7929. // Delegate to script
  7930. return "script";
  7931. }
  7932. } );
  7933. // Support: Safari 8 only
  7934. // In Safari 8 documents created via document.implementation.createHTMLDocument
  7935. // collapse sibling forms: the second one becomes a child of the first one.
  7936. // Because of that, this security measure has to be disabled in Safari 8.
  7937. // https://bugs.webkit.org/show_bug.cgi?id=137337
  7938. support.createHTMLDocument = ( function() {
  7939. var body = document.implementation.createHTMLDocument( "" ).body;
  7940. body.innerHTML = "<form></form><form></form>";
  7941. return body.childNodes.length === 2;
  7942. } )();
  7943. // Argument "data" should be string of html
  7944. // context (optional): If specified, the fragment will be created in this context,
  7945. // defaults to document
  7946. // keepScripts (optional): If true, will include scripts passed in the html string
  7947. jQuery.parseHTML = function( data, context, keepScripts ) {
  7948. if ( typeof data !== "string" ) {
  7949. return [];
  7950. }
  7951. if ( typeof context === "boolean" ) {
  7952. keepScripts = context;
  7953. context = false;
  7954. }
  7955. var base, parsed, scripts;
  7956. if ( !context ) {
  7957. // Stop scripts or inline event handlers from being executed immediately
  7958. // by using document.implementation
  7959. if ( support.createHTMLDocument ) {
  7960. context = document.implementation.createHTMLDocument( "" );
  7961. // Set the base href for the created document
  7962. // so any parsed elements with URLs
  7963. // are based on the document's URL (gh-2965)
  7964. base = context.createElement( "base" );
  7965. base.href = document.location.href;
  7966. context.head.appendChild( base );
  7967. } else {
  7968. context = document;
  7969. }
  7970. }
  7971. parsed = rsingleTag.exec( data );
  7972. scripts = !keepScripts && [];
  7973. // Single tag
  7974. if ( parsed ) {
  7975. return [ context.createElement( parsed[ 1 ] ) ];
  7976. }
  7977. parsed = buildFragment( [ data ], context, scripts );
  7978. if ( scripts && scripts.length ) {
  7979. jQuery( scripts ).remove();
  7980. }
  7981. return jQuery.merge( [], parsed.childNodes );
  7982. };
  7983. /**
  7984. * Load a url into a page
  7985. */
  7986. jQuery.fn.load = function( url, params, callback ) {
  7987. var selector, type, response,
  7988. self = this,
  7989. off = url.indexOf( " " );
  7990. if ( off > -1 ) {
  7991. selector = stripAndCollapse( url.slice( off ) );
  7992. url = url.slice( 0, off );
  7993. }
  7994. // If it's a function
  7995. if ( jQuery.isFunction( params ) ) {
  7996. // We assume that it's the callback
  7997. callback = params;
  7998. params = undefined;
  7999. // Otherwise, build a param string
  8000. } else if ( params && typeof params === "object" ) {
  8001. type = "POST";
  8002. }
  8003. // If we have elements to modify, make the request
  8004. if ( self.length > 0 ) {
  8005. jQuery.ajax( {
  8006. url: url,
  8007. // If "type" variable is undefined, then "GET" method will be used.
  8008. // Make value of this field explicit since
  8009. // user can override it through ajaxSetup method
  8010. type: type || "GET",
  8011. dataType: "html",
  8012. data: params
  8013. } ).done( function( responseText ) {
  8014. // Save response for use in complete callback
  8015. response = arguments;
  8016. self.html( selector ?
  8017. // If a selector was specified, locate the right elements in a dummy div
  8018. // Exclude scripts to avoid IE 'Permission Denied' errors
  8019. jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
  8020. // Otherwise use the full result
  8021. responseText );
  8022. // If the request succeeds, this function gets "data", "status", "jqXHR"
  8023. // but they are ignored because response was set above.
  8024. // If it fails, this function gets "jqXHR", "status", "error"
  8025. } ).always( callback && function( jqXHR, status ) {
  8026. self.each( function() {
  8027. callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
  8028. } );
  8029. } );
  8030. }
  8031. return this;
  8032. };
  8033. // Attach a bunch of functions for handling common AJAX events
  8034. jQuery.each( [
  8035. "ajaxStart",
  8036. "ajaxStop",
  8037. "ajaxComplete",
  8038. "ajaxError",
  8039. "ajaxSuccess",
  8040. "ajaxSend"
  8041. ], function( i, type ) {
  8042. jQuery.fn[ type ] = function( fn ) {
  8043. return this.on( type, fn );
  8044. };
  8045. } );
  8046. jQuery.expr.pseudos.animated = function( elem ) {
  8047. return jQuery.grep( jQuery.timers, function( fn ) {
  8048. return elem === fn.elem;
  8049. } ).length;
  8050. };
  8051. jQuery.offset = {
  8052. setOffset: function( elem, options, i ) {
  8053. var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
  8054. position = jQuery.css( elem, "position" ),
  8055. curElem = jQuery( elem ),
  8056. props = {};
  8057. // Set position first, in-case top/left are set even on static elem
  8058. if ( position === "static" ) {
  8059. elem.style.position = "relative";
  8060. }
  8061. curOffset = curElem.offset();
  8062. curCSSTop = jQuery.css( elem, "top" );
  8063. curCSSLeft = jQuery.css( elem, "left" );
  8064. calculatePosition = ( position === "absolute" || position === "fixed" ) &&
  8065. ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
  8066. // Need to be able to calculate position if either
  8067. // top or left is auto and position is either absolute or fixed
  8068. if ( calculatePosition ) {
  8069. curPosition = curElem.position();
  8070. curTop = curPosition.top;
  8071. curLeft = curPosition.left;
  8072. } else {
  8073. curTop = parseFloat( curCSSTop ) || 0;
  8074. curLeft = parseFloat( curCSSLeft ) || 0;
  8075. }
  8076. if ( jQuery.isFunction( options ) ) {
  8077. // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
  8078. options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
  8079. }
  8080. if ( options.top != null ) {
  8081. props.top = ( options.top - curOffset.top ) + curTop;
  8082. }
  8083. if ( options.left != null ) {
  8084. props.left = ( options.left - curOffset.left ) + curLeft;
  8085. }
  8086. if ( "using" in options ) {
  8087. options.using.call( elem, props );
  8088. } else {
  8089. curElem.css( props );
  8090. }
  8091. }
  8092. };
  8093. jQuery.fn.extend( {
  8094. offset: function( options ) {
  8095. // Preserve chaining for setter
  8096. if ( arguments.length ) {
  8097. return options === undefined ?
  8098. this :
  8099. this.each( function( i ) {
  8100. jQuery.offset.setOffset( this, options, i );
  8101. } );
  8102. }
  8103. var doc, docElem, rect, win,
  8104. elem = this[ 0 ];
  8105. if ( !elem ) {
  8106. return;
  8107. }
  8108. // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
  8109. // Support: IE <=11 only
  8110. // Running getBoundingClientRect on a
  8111. // disconnected node in IE throws an error
  8112. if ( !elem.getClientRects().length ) {
  8113. return { top: 0, left: 0 };
  8114. }
  8115. rect = elem.getBoundingClientRect();
  8116. doc = elem.ownerDocument;
  8117. docElem = doc.documentElement;
  8118. win = doc.defaultView;
  8119. return {
  8120. top: rect.top + win.pageYOffset - docElem.clientTop,
  8121. left: rect.left + win.pageXOffset - docElem.clientLeft
  8122. };
  8123. },
  8124. position: function() {
  8125. if ( !this[ 0 ] ) {
  8126. return;
  8127. }
  8128. var offsetParent, offset,
  8129. elem = this[ 0 ],
  8130. parentOffset = { top: 0, left: 0 };
  8131. // Fixed elements are offset from window (parentOffset = {top:0, left: 0},
  8132. // because it is its only offset parent
  8133. if ( jQuery.css( elem, "position" ) === "fixed" ) {
  8134. // Assume getBoundingClientRect is there when computed position is fixed
  8135. offset = elem.getBoundingClientRect();
  8136. } else {
  8137. // Get *real* offsetParent
  8138. offsetParent = this.offsetParent();
  8139. // Get correct offsets
  8140. offset = this.offset();
  8141. if ( !nodeName( offsetParent[ 0 ], "html" ) ) {
  8142. parentOffset = offsetParent.offset();
  8143. }
  8144. // Add offsetParent borders
  8145. parentOffset = {
  8146. top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ),
  8147. left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true )
  8148. };
  8149. }
  8150. // Subtract parent offsets and element margins
  8151. return {
  8152. top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
  8153. left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
  8154. };
  8155. },
  8156. // This method will return documentElement in the following cases:
  8157. // 1) For the element inside the iframe without offsetParent, this method will return
  8158. // documentElement of the parent window
  8159. // 2) For the hidden or detached element
  8160. // 3) For body or html element, i.e. in case of the html node - it will return itself
  8161. //
  8162. // but those exceptions were never presented as a real life use-cases
  8163. // and might be considered as more preferable results.
  8164. //
  8165. // This logic, however, is not guaranteed and can change at any point in the future
  8166. offsetParent: function() {
  8167. return this.map( function() {
  8168. var offsetParent = this.offsetParent;
  8169. while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
  8170. offsetParent = offsetParent.offsetParent;
  8171. }
  8172. return offsetParent || documentElement;
  8173. } );
  8174. }
  8175. } );
  8176. // Create scrollLeft and scrollTop methods
  8177. jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
  8178. var top = "pageYOffset" === prop;
  8179. jQuery.fn[ method ] = function( val ) {
  8180. return access( this, function( elem, method, val ) {
  8181. // Coalesce documents and windows
  8182. var win;
  8183. if ( jQuery.isWindow( elem ) ) {
  8184. win = elem;
  8185. } else if ( elem.nodeType === 9 ) {
  8186. win = elem.defaultView;
  8187. }
  8188. if ( val === undefined ) {
  8189. return win ? win[ prop ] : elem[ method ];
  8190. }
  8191. if ( win ) {
  8192. win.scrollTo(
  8193. !top ? val : win.pageXOffset,
  8194. top ? val : win.pageYOffset
  8195. );
  8196. } else {
  8197. elem[ method ] = val;
  8198. }
  8199. }, method, val, arguments.length );
  8200. };
  8201. } );
  8202. // Support: Safari <=7 - 9.1, Chrome <=37 - 49
  8203. // Add the top/left cssHooks using jQuery.fn.position
  8204. // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
  8205. // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
  8206. // getComputedStyle returns percent when specified for top/left/bottom/right;
  8207. // rather than make the css module depend on the offset module, just check for it here
  8208. jQuery.each( [ "top", "left" ], function( i, prop ) {
  8209. jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
  8210. function( elem, computed ) {
  8211. if ( computed ) {
  8212. computed = curCSS( elem, prop );
  8213. // If curCSS returns percentage, fallback to offset
  8214. return rnumnonpx.test( computed ) ?
  8215. jQuery( elem ).position()[ prop ] + "px" :
  8216. computed;
  8217. }
  8218. }
  8219. );
  8220. } );
  8221. // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
  8222. jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
  8223. jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
  8224. function( defaultExtra, funcName ) {
  8225. // Margin is only for outerHeight, outerWidth
  8226. jQuery.fn[ funcName ] = function( margin, value ) {
  8227. var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
  8228. extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
  8229. return access( this, function( elem, type, value ) {
  8230. var doc;
  8231. if ( jQuery.isWindow( elem ) ) {
  8232. // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
  8233. return funcName.indexOf( "outer" ) === 0 ?
  8234. elem[ "inner" + name ] :
  8235. elem.document.documentElement[ "client" + name ];
  8236. }
  8237. // Get document width or height
  8238. if ( elem.nodeType === 9 ) {
  8239. doc = elem.documentElement;
  8240. // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
  8241. // whichever is greatest
  8242. return Math.max(
  8243. elem.body[ "scroll" + name ], doc[ "scroll" + name ],
  8244. elem.body[ "offset" + name ], doc[ "offset" + name ],
  8245. doc[ "client" + name ]
  8246. );
  8247. }
  8248. return value === undefined ?
  8249. // Get width or height on the element, requesting but not forcing parseFloat
  8250. jQuery.css( elem, type, extra ) :
  8251. // Set width or height on the element
  8252. jQuery.style( elem, type, value, extra );
  8253. }, type, chainable ? margin : undefined, chainable );
  8254. };
  8255. } );
  8256. } );
  8257. jQuery.fn.extend( {
  8258. bind: function( types, data, fn ) {
  8259. return this.on( types, null, data, fn );
  8260. },
  8261. unbind: function( types, fn ) {
  8262. return this.off( types, null, fn );
  8263. },
  8264. delegate: function( selector, types, data, fn ) {
  8265. return this.on( types, selector, data, fn );
  8266. },
  8267. undelegate: function( selector, types, fn ) {
  8268. // ( namespace ) or ( selector, types [, fn] )
  8269. return arguments.length === 1 ?
  8270. this.off( selector, "**" ) :
  8271. this.off( types, selector || "**", fn );
  8272. }
  8273. } );
  8274. jQuery.holdReady = function( hold ) {
  8275. if ( hold ) {
  8276. jQuery.readyWait++;
  8277. } else {
  8278. jQuery.ready( true );
  8279. }
  8280. };
  8281. jQuery.isArray = Array.isArray;
  8282. jQuery.parseJSON = JSON.parse;
  8283. jQuery.nodeName = nodeName;
  8284. // Register as a named AMD module, since jQuery can be concatenated with other
  8285. // files that may use define, but not via a proper concatenation script that
  8286. // understands anonymous AMD modules. A named AMD is safest and most robust
  8287. // way to register. Lowercase jquery is used because AMD module names are
  8288. // derived from file names, and jQuery is normally delivered in a lowercase
  8289. // file name. Do this after creating the global so that if an AMD module wants
  8290. // to call noConflict to hide this version of jQuery, it will work.
  8291. // Note that for maximum portability, libraries that are not jQuery should
  8292. // declare themselves as anonymous modules, and avoid setting a global if an
  8293. // AMD loader is present. jQuery is a special case. For more information, see
  8294. // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
  8295. if ( typeof define === "function" && define.amd ) {
  8296. define( "jquery", [], function() {
  8297. return jQuery;
  8298. } );
  8299. }
  8300. var
  8301. // Map over jQuery in case of overwrite
  8302. _jQuery = window.jQuery,
  8303. // Map over the $ in case of overwrite
  8304. _$ = window.$;
  8305. jQuery.noConflict = function( deep ) {
  8306. if ( window.$ === jQuery ) {
  8307. window.$ = _$;
  8308. }
  8309. if ( deep && window.jQuery === jQuery ) {
  8310. window.jQuery = _jQuery;
  8311. }
  8312. return jQuery;
  8313. };
  8314. // Expose jQuery and $ identifiers, even in AMD
  8315. // (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
  8316. // and CommonJS for browser emulators (#13566)
  8317. if ( !noGlobal ) {
  8318. window.jQuery = window.$ = jQuery;
  8319. }
  8320. return jQuery;
  8321. } );
  8322. ;
  8323. /*!
  8324. * Bootstrap v3.3.7 (http://getbootstrap.com)
  8325. * Copyright 2011-2016 Twitter, Inc.
  8326. * Licensed under the MIT license
  8327. */
  8328. if (typeof jQuery === 'undefined') {
  8329. throw new Error('Bootstrap\'s JavaScript requires jQuery')
  8330. }
  8331. +function ($) {
  8332. 'use strict';
  8333. var version = $.fn.jquery.split(' ')[0].split('.')
  8334. if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) {
  8335. throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')
  8336. }
  8337. }(jQuery);
  8338. /* ========================================================================
  8339. * Bootstrap: transition.js v3.3.7
  8340. * http://getbootstrap.com/javascript/#transitions
  8341. * ========================================================================
  8342. * Copyright 2011-2016 Twitter, Inc.
  8343. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  8344. * ======================================================================== */
  8345. +function ($) {
  8346. 'use strict';
  8347. // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
  8348. // ============================================================
  8349. function transitionEnd() {
  8350. var el = document.createElement('bootstrap')
  8351. var transEndEventNames = {
  8352. WebkitTransition : 'webkitTransitionEnd',
  8353. MozTransition : 'transitionend',
  8354. OTransition : 'oTransitionEnd otransitionend',
  8355. transition : 'transitionend'
  8356. }
  8357. for (var name in transEndEventNames) {
  8358. if (el.style[name] !== undefined) {
  8359. return { end: transEndEventNames[name] }
  8360. }
  8361. }
  8362. return false // explicit for ie8 ( ._.)
  8363. }
  8364. // http://blog.alexmaccaw.com/css-transitions
  8365. $.fn.emulateTransitionEnd = function (duration) {
  8366. var called = false
  8367. var $el = this
  8368. $(this).one('bsTransitionEnd', function () { called = true })
  8369. var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
  8370. setTimeout(callback, duration)
  8371. return this
  8372. }
  8373. $(function () {
  8374. $.support.transition = transitionEnd()
  8375. if (!$.support.transition) return
  8376. $.event.special.bsTransitionEnd = {
  8377. bindType: $.support.transition.end,
  8378. delegateType: $.support.transition.end,
  8379. handle: function (e) {
  8380. if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
  8381. }
  8382. }
  8383. })
  8384. }(jQuery);
  8385. /* ========================================================================
  8386. * Bootstrap: alert.js v3.3.7
  8387. * http://getbootstrap.com/javascript/#alerts
  8388. * ========================================================================
  8389. * Copyright 2011-2016 Twitter, Inc.
  8390. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  8391. * ======================================================================== */
  8392. +function ($) {
  8393. 'use strict';
  8394. // ALERT CLASS DEFINITION
  8395. // ======================
  8396. var dismiss = '[data-dismiss="alert"]'
  8397. var Alert = function (el) {
  8398. $(el).on('click', dismiss, this.close)
  8399. }
  8400. Alert.VERSION = '3.3.7'
  8401. Alert.TRANSITION_DURATION = 150
  8402. Alert.prototype.close = function (e) {
  8403. var $this = $(this)
  8404. var selector = $this.attr('data-target')
  8405. if (!selector) {
  8406. selector = $this.attr('href')
  8407. selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
  8408. }
  8409. var $parent = $(selector === '#' ? [] : selector)
  8410. if (e) e.preventDefault()
  8411. if (!$parent.length) {
  8412. $parent = $this.closest('.alert')
  8413. }
  8414. $parent.trigger(e = $.Event('close.bs.alert'))
  8415. if (e.isDefaultPrevented()) return
  8416. $parent.removeClass('in')
  8417. function removeElement() {
  8418. // detach from parent, fire event then clean up data
  8419. $parent.detach().trigger('closed.bs.alert').remove()
  8420. }
  8421. $.support.transition && $parent.hasClass('fade') ?
  8422. $parent
  8423. .one('bsTransitionEnd', removeElement)
  8424. .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
  8425. removeElement()
  8426. }
  8427. // ALERT PLUGIN DEFINITION
  8428. // =======================
  8429. function Plugin(option) {
  8430. return this.each(function () {
  8431. var $this = $(this)
  8432. var data = $this.data('bs.alert')
  8433. if (!data) $this.data('bs.alert', (data = new Alert(this)))
  8434. if (typeof option == 'string') data[option].call($this)
  8435. })
  8436. }
  8437. var old = $.fn.alert
  8438. $.fn.alert = Plugin
  8439. $.fn.alert.Constructor = Alert
  8440. // ALERT NO CONFLICT
  8441. // =================
  8442. $.fn.alert.noConflict = function () {
  8443. $.fn.alert = old
  8444. return this
  8445. }
  8446. // ALERT DATA-API
  8447. // ==============
  8448. $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
  8449. }(jQuery);
  8450. /* ========================================================================
  8451. * Bootstrap: button.js v3.3.7
  8452. * http://getbootstrap.com/javascript/#buttons
  8453. * ========================================================================
  8454. * Copyright 2011-2016 Twitter, Inc.
  8455. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  8456. * ======================================================================== */
  8457. +function ($) {
  8458. 'use strict';
  8459. // BUTTON PUBLIC CLASS DEFINITION
  8460. // ==============================
  8461. var Button = function (element, options) {
  8462. this.$element = $(element)
  8463. this.options = $.extend({}, Button.DEFAULTS, options)
  8464. this.isLoading = false
  8465. }
  8466. Button.VERSION = '3.3.7'
  8467. Button.DEFAULTS = {
  8468. loadingText: 'loading...'
  8469. }
  8470. Button.prototype.setState = function (state) {
  8471. var d = 'disabled'
  8472. var $el = this.$element
  8473. var val = $el.is('input') ? 'val' : 'html'
  8474. var data = $el.data()
  8475. state += 'Text'
  8476. if (data.resetText == null) $el.data('resetText', $el[val]())
  8477. // push to event loop to allow forms to submit
  8478. setTimeout($.proxy(function () {
  8479. $el[val](data[state] == null ? this.options[state] : data[state])
  8480. if (state == 'loadingText') {
  8481. this.isLoading = true
  8482. $el.addClass(d).attr(d, d).prop(d, true)
  8483. } else if (this.isLoading) {
  8484. this.isLoading = false
  8485. $el.removeClass(d).removeAttr(d).prop(d, false)
  8486. }
  8487. }, this), 0)
  8488. }
  8489. Button.prototype.toggle = function () {
  8490. var changed = true
  8491. var $parent = this.$element.closest('[data-toggle="buttons"]')
  8492. if ($parent.length) {
  8493. var $input = this.$element.find('input')
  8494. if ($input.prop('type') == 'radio') {
  8495. if ($input.prop('checked')) changed = false
  8496. $parent.find('.active').removeClass('active')
  8497. this.$element.addClass('active')
  8498. } else if ($input.prop('type') == 'checkbox') {
  8499. if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
  8500. this.$element.toggleClass('active')
  8501. }
  8502. $input.prop('checked', this.$element.hasClass('active'))
  8503. if (changed) $input.trigger('change')
  8504. } else {
  8505. this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
  8506. this.$element.toggleClass('active')
  8507. }
  8508. }
  8509. // BUTTON PLUGIN DEFINITION
  8510. // ========================
  8511. function Plugin(option) {
  8512. return this.each(function () {
  8513. var $this = $(this)
  8514. var data = $this.data('bs.button')
  8515. var options = typeof option == 'object' && option
  8516. if (!data) $this.data('bs.button', (data = new Button(this, options)))
  8517. if (option == 'toggle') data.toggle()
  8518. else if (option) data.setState(option)
  8519. })
  8520. }
  8521. var old = $.fn.button
  8522. $.fn.button = Plugin
  8523. $.fn.button.Constructor = Button
  8524. // BUTTON NO CONFLICT
  8525. // ==================
  8526. $.fn.button.noConflict = function () {
  8527. $.fn.button = old
  8528. return this
  8529. }
  8530. // BUTTON DATA-API
  8531. // ===============
  8532. $(document)
  8533. .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
  8534. var $btn = $(e.target).closest('.btn')
  8535. Plugin.call($btn, 'toggle')
  8536. if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) {
  8537. // Prevent double click on radios, and the double selections (so cancellation) on checkboxes
  8538. e.preventDefault()
  8539. // The target component still receive the focus
  8540. if ($btn.is('input,button')) $btn.trigger('focus')
  8541. else $btn.find('input:visible,button:visible').first().trigger('focus')
  8542. }
  8543. })
  8544. .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
  8545. $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
  8546. })
  8547. }(jQuery);
  8548. /* ========================================================================
  8549. * Bootstrap: carousel.js v3.3.7
  8550. * http://getbootstrap.com/javascript/#carousel
  8551. * ========================================================================
  8552. * Copyright 2011-2016 Twitter, Inc.
  8553. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  8554. * ======================================================================== */
  8555. +function ($) {
  8556. 'use strict';
  8557. // CAROUSEL CLASS DEFINITION
  8558. // =========================
  8559. var Carousel = function (element, options) {
  8560. this.$element = $(element)
  8561. this.$indicators = this.$element.find('.carousel-indicators')
  8562. this.options = options
  8563. this.paused = null
  8564. this.sliding = null
  8565. this.interval = null
  8566. this.$active = null
  8567. this.$items = null
  8568. this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
  8569. this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
  8570. .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
  8571. .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
  8572. }
  8573. Carousel.VERSION = '3.3.7'
  8574. Carousel.TRANSITION_DURATION = 600
  8575. Carousel.DEFAULTS = {
  8576. interval: 5000,
  8577. pause: 'hover',
  8578. wrap: true,
  8579. keyboard: true
  8580. }
  8581. Carousel.prototype.keydown = function (e) {
  8582. if (/input|textarea/i.test(e.target.tagName)) return
  8583. switch (e.which) {
  8584. case 37: this.prev(); break
  8585. case 39: this.next(); break
  8586. default: return
  8587. }
  8588. e.preventDefault()
  8589. }
  8590. Carousel.prototype.cycle = function (e) {
  8591. e || (this.paused = false)
  8592. this.interval && clearInterval(this.interval)
  8593. this.options.interval
  8594. && !this.paused
  8595. && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
  8596. return this
  8597. }
  8598. Carousel.prototype.getItemIndex = function (item) {
  8599. this.$items = item.parent().children('.item')
  8600. return this.$items.index(item || this.$active)
  8601. }
  8602. Carousel.prototype.getItemForDirection = function (direction, active) {
  8603. var activeIndex = this.getItemIndex(active)
  8604. var willWrap = (direction == 'prev' && activeIndex === 0)
  8605. || (direction == 'next' && activeIndex == (this.$items.length - 1))
  8606. if (willWrap && !this.options.wrap) return active
  8607. var delta = direction == 'prev' ? -1 : 1
  8608. var itemIndex = (activeIndex + delta) % this.$items.length
  8609. return this.$items.eq(itemIndex)
  8610. }
  8611. Carousel.prototype.to = function (pos) {
  8612. var that = this
  8613. var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
  8614. if (pos > (this.$items.length - 1) || pos < 0) return
  8615. if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
  8616. if (activeIndex == pos) return this.pause().cycle()
  8617. return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
  8618. }
  8619. Carousel.prototype.pause = function (e) {
  8620. e || (this.paused = true)
  8621. if (this.$element.find('.next, .prev').length && $.support.transition) {
  8622. this.$element.trigger($.support.transition.end)
  8623. this.cycle(true)
  8624. }
  8625. this.interval = clearInterval(this.interval)
  8626. return this
  8627. }
  8628. Carousel.prototype.next = function () {
  8629. if (this.sliding) return
  8630. return this.slide('next')
  8631. }
  8632. Carousel.prototype.prev = function () {
  8633. if (this.sliding) return
  8634. return this.slide('prev')
  8635. }
  8636. Carousel.prototype.slide = function (type, next) {
  8637. var $active = this.$element.find('.item.active')
  8638. var $next = next || this.getItemForDirection(type, $active)
  8639. var isCycling = this.interval
  8640. var direction = type == 'next' ? 'left' : 'right'
  8641. var that = this
  8642. if ($next.hasClass('active')) return (this.sliding = false)
  8643. var relatedTarget = $next[0]
  8644. var slideEvent = $.Event('slide.bs.carousel', {
  8645. relatedTarget: relatedTarget,
  8646. direction: direction
  8647. })
  8648. this.$element.trigger(slideEvent)
  8649. if (slideEvent.isDefaultPrevented()) return
  8650. this.sliding = true
  8651. isCycling && this.pause()
  8652. if (this.$indicators.length) {
  8653. this.$indicators.find('.active').removeClass('active')
  8654. var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
  8655. $nextIndicator && $nextIndicator.addClass('active')
  8656. }
  8657. var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
  8658. if ($.support.transition && this.$element.hasClass('slide')) {
  8659. $next.addClass(type)
  8660. $next[0].offsetWidth // force reflow
  8661. $active.addClass(direction)
  8662. $next.addClass(direction)
  8663. $active
  8664. .one('bsTransitionEnd', function () {
  8665. $next.removeClass([type, direction].join(' ')).addClass('active')
  8666. $active.removeClass(['active', direction].join(' '))
  8667. that.sliding = false
  8668. setTimeout(function () {
  8669. that.$element.trigger(slidEvent)
  8670. }, 0)
  8671. })
  8672. .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
  8673. } else {
  8674. $active.removeClass('active')
  8675. $next.addClass('active')
  8676. this.sliding = false
  8677. this.$element.trigger(slidEvent)
  8678. }
  8679. isCycling && this.cycle()
  8680. return this
  8681. }
  8682. // CAROUSEL PLUGIN DEFINITION
  8683. // ==========================
  8684. function Plugin(option) {
  8685. return this.each(function () {
  8686. var $this = $(this)
  8687. var data = $this.data('bs.carousel')
  8688. var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
  8689. var action = typeof option == 'string' ? option : options.slide
  8690. if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
  8691. if (typeof option == 'number') data.to(option)
  8692. else if (action) data[action]()
  8693. else if (options.interval) data.pause().cycle()
  8694. })
  8695. }
  8696. var old = $.fn.carousel
  8697. $.fn.carousel = Plugin
  8698. $.fn.carousel.Constructor = Carousel
  8699. // CAROUSEL NO CONFLICT
  8700. // ====================
  8701. $.fn.carousel.noConflict = function () {
  8702. $.fn.carousel = old
  8703. return this
  8704. }
  8705. // CAROUSEL DATA-API
  8706. // =================
  8707. var clickHandler = function (e) {
  8708. var href
  8709. var $this = $(this)
  8710. var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
  8711. if (!$target.hasClass('carousel')) return
  8712. var options = $.extend({}, $target.data(), $this.data())
  8713. var slideIndex = $this.attr('data-slide-to')
  8714. if (slideIndex) options.interval = false
  8715. Plugin.call($target, options)
  8716. if (slideIndex) {
  8717. $target.data('bs.carousel').to(slideIndex)
  8718. }
  8719. e.preventDefault()
  8720. }
  8721. $(document)
  8722. .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
  8723. .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
  8724. $(window).on('load', function () {
  8725. $('[data-ride="carousel"]').each(function () {
  8726. var $carousel = $(this)
  8727. Plugin.call($carousel, $carousel.data())
  8728. })
  8729. })
  8730. }(jQuery);
  8731. /* ========================================================================
  8732. * Bootstrap: collapse.js v3.3.7
  8733. * http://getbootstrap.com/javascript/#collapse
  8734. * ========================================================================
  8735. * Copyright 2011-2016 Twitter, Inc.
  8736. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  8737. * ======================================================================== */
  8738. /* jshint latedef: false */
  8739. +function ($) {
  8740. 'use strict';
  8741. // COLLAPSE PUBLIC CLASS DEFINITION
  8742. // ================================
  8743. var Collapse = function (element, options) {
  8744. this.$element = $(element)
  8745. this.options = $.extend({}, Collapse.DEFAULTS, options)
  8746. this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
  8747. '[data-toggle="collapse"][data-target="#' + element.id + '"]')
  8748. this.transitioning = null
  8749. if (this.options.parent) {
  8750. this.$parent = this.getParent()
  8751. } else {
  8752. this.addAriaAndCollapsedClass(this.$element, this.$trigger)
  8753. }
  8754. if (this.options.toggle) this.toggle()
  8755. }
  8756. Collapse.VERSION = '3.3.7'
  8757. Collapse.TRANSITION_DURATION = 350
  8758. Collapse.DEFAULTS = {
  8759. toggle: true
  8760. }
  8761. Collapse.prototype.dimension = function () {
  8762. var hasWidth = this.$element.hasClass('width')
  8763. return hasWidth ? 'width' : 'height'
  8764. }
  8765. Collapse.prototype.show = function () {
  8766. if (this.transitioning || this.$element.hasClass('in')) return
  8767. var activesData
  8768. var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
  8769. if (actives && actives.length) {
  8770. activesData = actives.data('bs.collapse')
  8771. if (activesData && activesData.transitioning) return
  8772. }
  8773. var startEvent = $.Event('show.bs.collapse')
  8774. this.$element.trigger(startEvent)
  8775. if (startEvent.isDefaultPrevented()) return
  8776. if (actives && actives.length) {
  8777. Plugin.call(actives, 'hide')
  8778. activesData || actives.data('bs.collapse', null)
  8779. }
  8780. var dimension = this.dimension()
  8781. this.$element
  8782. .removeClass('collapse')
  8783. .addClass('collapsing')[dimension](0)
  8784. .attr('aria-expanded', true)
  8785. this.$trigger
  8786. .removeClass('collapsed')
  8787. .attr('aria-expanded', true)
  8788. this.transitioning = 1
  8789. var complete = function () {
  8790. this.$element
  8791. .removeClass('collapsing')
  8792. .addClass('collapse in')[dimension]('')
  8793. this.transitioning = 0
  8794. this.$element
  8795. .trigger('shown.bs.collapse')
  8796. }
  8797. if (!$.support.transition) return complete.call(this)
  8798. var scrollSize = $.camelCase(['scroll', dimension].join('-'))
  8799. this.$element
  8800. .one('bsTransitionEnd', $.proxy(complete, this))
  8801. .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
  8802. }
  8803. Collapse.prototype.hide = function () {
  8804. if (this.transitioning || !this.$element.hasClass('in')) return
  8805. var startEvent = $.Event('hide.bs.collapse')
  8806. this.$element.trigger(startEvent)
  8807. if (startEvent.isDefaultPrevented()) return
  8808. var dimension = this.dimension()
  8809. this.$element[dimension](this.$element[dimension]())[0].offsetHeight
  8810. this.$element
  8811. .addClass('collapsing')
  8812. .removeClass('collapse in')
  8813. .attr('aria-expanded', false)
  8814. this.$trigger
  8815. .addClass('collapsed')
  8816. .attr('aria-expanded', false)
  8817. this.transitioning = 1
  8818. var complete = function () {
  8819. this.transitioning = 0
  8820. this.$element
  8821. .removeClass('collapsing')
  8822. .addClass('collapse')
  8823. .trigger('hidden.bs.collapse')
  8824. }
  8825. if (!$.support.transition) return complete.call(this)
  8826. this.$element
  8827. [dimension](0)
  8828. .one('bsTransitionEnd', $.proxy(complete, this))
  8829. .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
  8830. }
  8831. Collapse.prototype.toggle = function () {
  8832. this[this.$element.hasClass('in') ? 'hide' : 'show']()
  8833. }
  8834. Collapse.prototype.getParent = function () {
  8835. return $(this.options.parent)
  8836. .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
  8837. .each($.proxy(function (i, element) {
  8838. var $element = $(element)
  8839. this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
  8840. }, this))
  8841. .end()
  8842. }
  8843. Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
  8844. var isOpen = $element.hasClass('in')
  8845. $element.attr('aria-expanded', isOpen)
  8846. $trigger
  8847. .toggleClass('collapsed', !isOpen)
  8848. .attr('aria-expanded', isOpen)
  8849. }
  8850. function getTargetFromTrigger($trigger) {
  8851. var href
  8852. var target = $trigger.attr('data-target')
  8853. || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
  8854. return $(target)
  8855. }
  8856. // COLLAPSE PLUGIN DEFINITION
  8857. // ==========================
  8858. function Plugin(option) {
  8859. return this.each(function () {
  8860. var $this = $(this)
  8861. var data = $this.data('bs.collapse')
  8862. var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
  8863. if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
  8864. if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
  8865. if (typeof option == 'string') data[option]()
  8866. })
  8867. }
  8868. var old = $.fn.collapse
  8869. $.fn.collapse = Plugin
  8870. $.fn.collapse.Constructor = Collapse
  8871. // COLLAPSE NO CONFLICT
  8872. // ====================
  8873. $.fn.collapse.noConflict = function () {
  8874. $.fn.collapse = old
  8875. return this
  8876. }
  8877. // COLLAPSE DATA-API
  8878. // =================
  8879. $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
  8880. var $this = $(this)
  8881. if (!$this.attr('data-target')) e.preventDefault()
  8882. var $target = getTargetFromTrigger($this)
  8883. var data = $target.data('bs.collapse')
  8884. var option = data ? 'toggle' : $this.data()
  8885. Plugin.call($target, option)
  8886. })
  8887. }(jQuery);
  8888. /* ========================================================================
  8889. * Bootstrap: dropdown.js v3.3.7
  8890. * http://getbootstrap.com/javascript/#dropdowns
  8891. * ========================================================================
  8892. * Copyright 2011-2016 Twitter, Inc.
  8893. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  8894. * ======================================================================== */
  8895. +function ($) {
  8896. 'use strict';
  8897. // DROPDOWN CLASS DEFINITION
  8898. // =========================
  8899. var backdrop = '.dropdown-backdrop'
  8900. var toggle = '[data-toggle="dropdown"]'
  8901. var Dropdown = function (element) {
  8902. $(element).on('click.bs.dropdown', this.toggle)
  8903. }
  8904. Dropdown.VERSION = '3.3.7'
  8905. function getParent($this) {
  8906. var selector = $this.attr('data-target')
  8907. if (!selector) {
  8908. selector = $this.attr('href')
  8909. selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
  8910. }
  8911. var $parent = selector && $(selector)
  8912. return $parent && $parent.length ? $parent : $this.parent()
  8913. }
  8914. function clearMenus(e) {
  8915. if (e && e.which === 3) return
  8916. $(backdrop).remove()
  8917. $(toggle).each(function () {
  8918. var $this = $(this)
  8919. var $parent = getParent($this)
  8920. var relatedTarget = { relatedTarget: this }
  8921. if (!$parent.hasClass('open')) return
  8922. if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
  8923. $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
  8924. if (e.isDefaultPrevented()) return
  8925. $this.attr('aria-expanded', 'false')
  8926. $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
  8927. })
  8928. }
  8929. Dropdown.prototype.toggle = function (e) {
  8930. var $this = $(this)
  8931. if ($this.is('.disabled, :disabled')) return
  8932. var $parent = getParent($this)
  8933. var isActive = $parent.hasClass('open')
  8934. clearMenus()
  8935. if (!isActive) {
  8936. if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
  8937. // if mobile we use a backdrop because click events don't delegate
  8938. $(document.createElement('div'))
  8939. .addClass('dropdown-backdrop')
  8940. .insertAfter($(this))
  8941. .on('click', clearMenus)
  8942. }
  8943. var relatedTarget = { relatedTarget: this }
  8944. $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
  8945. if (e.isDefaultPrevented()) return
  8946. $this
  8947. .trigger('focus')
  8948. .attr('aria-expanded', 'true')
  8949. $parent
  8950. .toggleClass('open')
  8951. .trigger($.Event('shown.bs.dropdown', relatedTarget))
  8952. }
  8953. return false
  8954. }
  8955. Dropdown.prototype.keydown = function (e) {
  8956. if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
  8957. var $this = $(this)
  8958. e.preventDefault()
  8959. e.stopPropagation()
  8960. if ($this.is('.disabled, :disabled')) return
  8961. var $parent = getParent($this)
  8962. var isActive = $parent.hasClass('open')
  8963. if (!isActive && e.which != 27 || isActive && e.which == 27) {
  8964. if (e.which == 27) $parent.find(toggle).trigger('focus')
  8965. return $this.trigger('click')
  8966. }
  8967. var desc = ' li:not(.disabled):visible a'
  8968. var $items = $parent.find('.dropdown-menu' + desc)
  8969. if (!$items.length) return
  8970. var index = $items.index(e.target)
  8971. if (e.which == 38 && index > 0) index-- // up
  8972. if (e.which == 40 && index < $items.length - 1) index++ // down
  8973. if (!~index) index = 0
  8974. $items.eq(index).trigger('focus')
  8975. }
  8976. // DROPDOWN PLUGIN DEFINITION
  8977. // ==========================
  8978. function Plugin(option) {
  8979. return this.each(function () {
  8980. var $this = $(this)
  8981. var data = $this.data('bs.dropdown')
  8982. if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
  8983. if (typeof option == 'string') data[option].call($this)
  8984. })
  8985. }
  8986. var old = $.fn.dropdown
  8987. $.fn.dropdown = Plugin
  8988. $.fn.dropdown.Constructor = Dropdown
  8989. // DROPDOWN NO CONFLICT
  8990. // ====================
  8991. $.fn.dropdown.noConflict = function () {
  8992. $.fn.dropdown = old
  8993. return this
  8994. }
  8995. // APPLY TO STANDARD DROPDOWN ELEMENTS
  8996. // ===================================
  8997. $(document)
  8998. .on('click.bs.dropdown.data-api', clearMenus)
  8999. .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
  9000. .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
  9001. .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
  9002. .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
  9003. }(jQuery);
  9004. /* ========================================================================
  9005. * Bootstrap: modal.js v3.3.7
  9006. * http://getbootstrap.com/javascript/#modals
  9007. * ========================================================================
  9008. * Copyright 2011-2016 Twitter, Inc.
  9009. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  9010. * ======================================================================== */
  9011. +function ($) {
  9012. 'use strict';
  9013. // MODAL CLASS DEFINITION
  9014. // ======================
  9015. var Modal = function (element, options) {
  9016. this.options = options
  9017. this.$body = $(document.body)
  9018. this.$element = $(element)
  9019. this.$dialog = this.$element.find('.modal-dialog')
  9020. this.$backdrop = null
  9021. this.isShown = null
  9022. this.originalBodyPad = null
  9023. this.scrollbarWidth = 0
  9024. this.ignoreBackdropClick = false
  9025. if (this.options.remote) {
  9026. this.$element
  9027. .find('.modal-content')
  9028. .load(this.options.remote, $.proxy(function () {
  9029. this.$element.trigger('loaded.bs.modal')
  9030. }, this))
  9031. }
  9032. }
  9033. Modal.VERSION = '3.3.7'
  9034. Modal.TRANSITION_DURATION = 300
  9035. Modal.BACKDROP_TRANSITION_DURATION = 150
  9036. Modal.DEFAULTS = {
  9037. backdrop: true,
  9038. keyboard: true,
  9039. show: true
  9040. }
  9041. Modal.prototype.toggle = function (_relatedTarget) {
  9042. return this.isShown ? this.hide() : this.show(_relatedTarget)
  9043. }
  9044. Modal.prototype.show = function (_relatedTarget) {
  9045. var that = this
  9046. var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
  9047. this.$element.trigger(e)
  9048. if (this.isShown || e.isDefaultPrevented()) return
  9049. this.isShown = true
  9050. this.checkScrollbar()
  9051. this.setScrollbar()
  9052. this.$body.addClass('modal-open')
  9053. this.escape()
  9054. this.resize()
  9055. this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
  9056. this.$dialog.on('mousedown.dismiss.bs.modal', function () {
  9057. that.$element.one('mouseup.dismiss.bs.modal', function (e) {
  9058. if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
  9059. })
  9060. })
  9061. this.backdrop(function () {
  9062. var transition = $.support.transition && that.$element.hasClass('fade')
  9063. if (!that.$element.parent().length) {
  9064. that.$element.appendTo(that.$body) // don't move modals dom position
  9065. }
  9066. that.$element
  9067. .show()
  9068. .scrollTop(0)
  9069. that.adjustDialog()
  9070. if (transition) {
  9071. that.$element[0].offsetWidth // force reflow
  9072. }
  9073. that.$element.addClass('in')
  9074. that.enforceFocus()
  9075. var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
  9076. transition ?
  9077. that.$dialog // wait for modal to slide in
  9078. .one('bsTransitionEnd', function () {
  9079. that.$element.trigger('focus').trigger(e)
  9080. })
  9081. .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
  9082. that.$element.trigger('focus').trigger(e)
  9083. })
  9084. }
  9085. Modal.prototype.hide = function (e) {
  9086. if (e) e.preventDefault()
  9087. e = $.Event('hide.bs.modal')
  9088. this.$element.trigger(e)
  9089. if (!this.isShown || e.isDefaultPrevented()) return
  9090. this.isShown = false
  9091. this.escape()
  9092. this.resize()
  9093. $(document).off('focusin.bs.modal')
  9094. this.$element
  9095. .removeClass('in')
  9096. .off('click.dismiss.bs.modal')
  9097. .off('mouseup.dismiss.bs.modal')
  9098. this.$dialog.off('mousedown.dismiss.bs.modal')
  9099. $.support.transition && this.$element.hasClass('fade') ?
  9100. this.$element
  9101. .one('bsTransitionEnd', $.proxy(this.hideModal, this))
  9102. .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
  9103. this.hideModal()
  9104. }
  9105. Modal.prototype.enforceFocus = function () {
  9106. $(document)
  9107. .off('focusin.bs.modal') // guard against infinite focus loop
  9108. .on('focusin.bs.modal', $.proxy(function (e) {
  9109. if (document !== e.target &&
  9110. this.$element[0] !== e.target &&
  9111. !this.$element.has(e.target).length) {
  9112. this.$element.trigger('focus')
  9113. }
  9114. }, this))
  9115. }
  9116. Modal.prototype.escape = function () {
  9117. if (this.isShown && this.options.keyboard) {
  9118. this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
  9119. e.which == 27 && this.hide()
  9120. }, this))
  9121. } else if (!this.isShown) {
  9122. this.$element.off('keydown.dismiss.bs.modal')
  9123. }
  9124. }
  9125. Modal.prototype.resize = function () {
  9126. if (this.isShown) {
  9127. $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
  9128. } else {
  9129. $(window).off('resize.bs.modal')
  9130. }
  9131. }
  9132. Modal.prototype.hideModal = function () {
  9133. var that = this
  9134. this.$element.hide()
  9135. this.backdrop(function () {
  9136. that.$body.removeClass('modal-open')
  9137. that.resetAdjustments()
  9138. that.resetScrollbar()
  9139. that.$element.trigger('hidden.bs.modal')
  9140. })
  9141. }
  9142. Modal.prototype.removeBackdrop = function () {
  9143. this.$backdrop && this.$backdrop.remove()
  9144. this.$backdrop = null
  9145. }
  9146. Modal.prototype.backdrop = function (callback) {
  9147. var that = this
  9148. var animate = this.$element.hasClass('fade') ? 'fade' : ''
  9149. if (this.isShown && this.options.backdrop) {
  9150. var doAnimate = $.support.transition && animate
  9151. this.$backdrop = $(document.createElement('div'))
  9152. .addClass('modal-backdrop ' + animate)
  9153. .appendTo(this.$body)
  9154. this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
  9155. if (this.ignoreBackdropClick) {
  9156. this.ignoreBackdropClick = false
  9157. return
  9158. }
  9159. if (e.target !== e.currentTarget) return
  9160. this.options.backdrop == 'static'
  9161. ? this.$element[0].focus()
  9162. : this.hide()
  9163. }, this))
  9164. if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
  9165. this.$backdrop.addClass('in')
  9166. if (!callback) return
  9167. doAnimate ?
  9168. this.$backdrop
  9169. .one('bsTransitionEnd', callback)
  9170. .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
  9171. callback()
  9172. } else if (!this.isShown && this.$backdrop) {
  9173. this.$backdrop.removeClass('in')
  9174. var callbackRemove = function () {
  9175. that.removeBackdrop()
  9176. callback && callback()
  9177. }
  9178. $.support.transition && this.$element.hasClass('fade') ?
  9179. this.$backdrop
  9180. .one('bsTransitionEnd', callbackRemove)
  9181. .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
  9182. callbackRemove()
  9183. } else if (callback) {
  9184. callback()
  9185. }
  9186. }
  9187. // these following methods are used to handle overflowing modals
  9188. Modal.prototype.handleUpdate = function () {
  9189. this.adjustDialog()
  9190. }
  9191. Modal.prototype.adjustDialog = function () {
  9192. var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
  9193. this.$element.css({
  9194. paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
  9195. paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
  9196. })
  9197. }
  9198. Modal.prototype.resetAdjustments = function () {
  9199. this.$element.css({
  9200. paddingLeft: '',
  9201. paddingRight: ''
  9202. })
  9203. }
  9204. Modal.prototype.checkScrollbar = function () {
  9205. var fullWindowWidth = window.innerWidth
  9206. if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
  9207. var documentElementRect = document.documentElement.getBoundingClientRect()
  9208. fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
  9209. }
  9210. this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
  9211. this.scrollbarWidth = this.measureScrollbar()
  9212. }
  9213. Modal.prototype.setScrollbar = function () {
  9214. var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
  9215. this.originalBodyPad = document.body.style.paddingRight || ''
  9216. if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
  9217. }
  9218. Modal.prototype.resetScrollbar = function () {
  9219. this.$body.css('padding-right', this.originalBodyPad)
  9220. }
  9221. Modal.prototype.measureScrollbar = function () { // thx walsh
  9222. var scrollDiv = document.createElement('div')
  9223. scrollDiv.className = 'modal-scrollbar-measure'
  9224. this.$body.append(scrollDiv)
  9225. var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
  9226. this.$body[0].removeChild(scrollDiv)
  9227. return scrollbarWidth
  9228. }
  9229. // MODAL PLUGIN DEFINITION
  9230. // =======================
  9231. function Plugin(option, _relatedTarget) {
  9232. return this.each(function () {
  9233. var $this = $(this)
  9234. var data = $this.data('bs.modal')
  9235. var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
  9236. if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
  9237. if (typeof option == 'string') data[option](_relatedTarget)
  9238. else if (options.show) data.show(_relatedTarget)
  9239. })
  9240. }
  9241. var old = $.fn.modal
  9242. $.fn.modal = Plugin
  9243. $.fn.modal.Constructor = Modal
  9244. // MODAL NO CONFLICT
  9245. // =================
  9246. $.fn.modal.noConflict = function () {
  9247. $.fn.modal = old
  9248. return this
  9249. }
  9250. // MODAL DATA-API
  9251. // ==============
  9252. $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
  9253. var $this = $(this)
  9254. var href = $this.attr('href')
  9255. var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
  9256. var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
  9257. if ($this.is('a')) e.preventDefault()
  9258. $target.one('show.bs.modal', function (showEvent) {
  9259. if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
  9260. $target.one('hidden.bs.modal', function () {
  9261. $this.is(':visible') && $this.trigger('focus')
  9262. })
  9263. })
  9264. Plugin.call($target, option, this)
  9265. })
  9266. }(jQuery);
  9267. /* ========================================================================
  9268. * Bootstrap: tooltip.js v3.3.7
  9269. * http://getbootstrap.com/javascript/#tooltip
  9270. * Inspired by the original jQuery.tipsy by Jason Frame
  9271. * ========================================================================
  9272. * Copyright 2011-2016 Twitter, Inc.
  9273. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  9274. * ======================================================================== */
  9275. +function ($) {
  9276. 'use strict';
  9277. // TOOLTIP PUBLIC CLASS DEFINITION
  9278. // ===============================
  9279. var Tooltip = function (element, options) {
  9280. this.type = null
  9281. this.options = null
  9282. this.enabled = null
  9283. this.timeout = null
  9284. this.hoverState = null
  9285. this.$element = null
  9286. this.inState = null
  9287. this.init('tooltip', element, options)
  9288. }
  9289. Tooltip.VERSION = '3.3.7'
  9290. Tooltip.TRANSITION_DURATION = 150
  9291. Tooltip.DEFAULTS = {
  9292. animation: true,
  9293. placement: 'top',
  9294. selector: false,
  9295. template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
  9296. trigger: 'hover focus',
  9297. title: '',
  9298. delay: 0,
  9299. html: false,
  9300. container: false,
  9301. viewport: {
  9302. selector: 'body',
  9303. padding: 0
  9304. }
  9305. }
  9306. Tooltip.prototype.init = function (type, element, options) {
  9307. this.enabled = true
  9308. this.type = type
  9309. this.$element = $(element)
  9310. this.options = this.getOptions(options)
  9311. this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
  9312. this.inState = { click: false, hover: false, focus: false }
  9313. if (this.$element[0] instanceof document.constructor && !this.options.selector) {
  9314. throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
  9315. }
  9316. var triggers = this.options.trigger.split(' ')
  9317. for (var i = triggers.length; i--;) {
  9318. var trigger = triggers[i]
  9319. if (trigger == 'click') {
  9320. this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
  9321. } else if (trigger != 'manual') {
  9322. var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
  9323. var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
  9324. this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
  9325. this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
  9326. }
  9327. }
  9328. this.options.selector ?
  9329. (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
  9330. this.fixTitle()
  9331. }
  9332. Tooltip.prototype.getDefaults = function () {
  9333. return Tooltip.DEFAULTS
  9334. }
  9335. Tooltip.prototype.getOptions = function (options) {
  9336. options = $.extend({}, this.getDefaults(), this.$element.data(), options)
  9337. if (options.delay && typeof options.delay == 'number') {
  9338. options.delay = {
  9339. show: options.delay,
  9340. hide: options.delay
  9341. }
  9342. }
  9343. return options
  9344. }
  9345. Tooltip.prototype.getDelegateOptions = function () {
  9346. var options = {}
  9347. var defaults = this.getDefaults()
  9348. this._options && $.each(this._options, function (key, value) {
  9349. if (defaults[key] != value) options[key] = value
  9350. })
  9351. return options
  9352. }
  9353. Tooltip.prototype.enter = function (obj) {
  9354. var self = obj instanceof this.constructor ?
  9355. obj : $(obj.currentTarget).data('bs.' + this.type)
  9356. if (!self) {
  9357. self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
  9358. $(obj.currentTarget).data('bs.' + this.type, self)
  9359. }
  9360. if (obj instanceof $.Event) {
  9361. self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
  9362. }
  9363. if (self.tip().hasClass('in') || self.hoverState == 'in') {
  9364. self.hoverState = 'in'
  9365. return
  9366. }
  9367. clearTimeout(self.timeout)
  9368. self.hoverState = 'in'
  9369. if (!self.options.delay || !self.options.delay.show) return self.show()
  9370. self.timeout = setTimeout(function () {
  9371. if (self.hoverState == 'in') self.show()
  9372. }, self.options.delay.show)
  9373. }
  9374. Tooltip.prototype.isInStateTrue = function () {
  9375. for (var key in this.inState) {
  9376. if (this.inState[key]) return true
  9377. }
  9378. return false
  9379. }
  9380. Tooltip.prototype.leave = function (obj) {
  9381. var self = obj instanceof this.constructor ?
  9382. obj : $(obj.currentTarget).data('bs.' + this.type)
  9383. if (!self) {
  9384. self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
  9385. $(obj.currentTarget).data('bs.' + this.type, self)
  9386. }
  9387. if (obj instanceof $.Event) {
  9388. self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
  9389. }
  9390. if (self.isInStateTrue()) return
  9391. clearTimeout(self.timeout)
  9392. self.hoverState = 'out'
  9393. if (!self.options.delay || !self.options.delay.hide) return self.hide()
  9394. self.timeout = setTimeout(function () {
  9395. if (self.hoverState == 'out') self.hide()
  9396. }, self.options.delay.hide)
  9397. }
  9398. Tooltip.prototype.show = function () {
  9399. var e = $.Event('show.bs.' + this.type)
  9400. if (this.hasContent() && this.enabled) {
  9401. this.$element.trigger(e)
  9402. var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
  9403. if (e.isDefaultPrevented() || !inDom) return
  9404. var that = this
  9405. var $tip = this.tip()
  9406. var tipId = this.getUID(this.type)
  9407. this.setContent()
  9408. $tip.attr('id', tipId)
  9409. this.$element.attr('aria-describedby', tipId)
  9410. if (this.options.animation) $tip.addClass('fade')
  9411. var placement = typeof this.options.placement == 'function' ?
  9412. this.options.placement.call(this, $tip[0], this.$element[0]) :
  9413. this.options.placement
  9414. var autoToken = /\s?auto?\s?/i
  9415. var autoPlace = autoToken.test(placement)
  9416. if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
  9417. $tip
  9418. .detach()
  9419. .css({ top: 0, left: 0, display: 'block' })
  9420. .addClass(placement)
  9421. .data('bs.' + this.type, this)
  9422. this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
  9423. this.$element.trigger('inserted.bs.' + this.type)
  9424. var pos = this.getPosition()
  9425. var actualWidth = $tip[0].offsetWidth
  9426. var actualHeight = $tip[0].offsetHeight
  9427. if (autoPlace) {
  9428. var orgPlacement = placement
  9429. var viewportDim = this.getPosition(this.$viewport)
  9430. placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
  9431. placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
  9432. placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
  9433. placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
  9434. placement
  9435. $tip
  9436. .removeClass(orgPlacement)
  9437. .addClass(placement)
  9438. }
  9439. var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
  9440. this.applyPlacement(calculatedOffset, placement)
  9441. var complete = function () {
  9442. var prevHoverState = that.hoverState
  9443. that.$element.trigger('shown.bs.' + that.type)
  9444. that.hoverState = null
  9445. if (prevHoverState == 'out') that.leave(that)
  9446. }
  9447. $.support.transition && this.$tip.hasClass('fade') ?
  9448. $tip
  9449. .one('bsTransitionEnd', complete)
  9450. .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
  9451. complete()
  9452. }
  9453. }
  9454. Tooltip.prototype.applyPlacement = function (offset, placement) {
  9455. var $tip = this.tip()
  9456. var width = $tip[0].offsetWidth
  9457. var height = $tip[0].offsetHeight
  9458. // manually read margins because getBoundingClientRect includes difference
  9459. var marginTop = parseInt($tip.css('margin-top'), 10)
  9460. var marginLeft = parseInt($tip.css('margin-left'), 10)
  9461. // we must check for NaN for ie 8/9
  9462. if (isNaN(marginTop)) marginTop = 0
  9463. if (isNaN(marginLeft)) marginLeft = 0
  9464. offset.top += marginTop
  9465. offset.left += marginLeft
  9466. // $.fn.offset doesn't round pixel values
  9467. // so we use setOffset directly with our own function B-0
  9468. $.offset.setOffset($tip[0], $.extend({
  9469. using: function (props) {
  9470. $tip.css({
  9471. top: Math.round(props.top),
  9472. left: Math.round(props.left)
  9473. })
  9474. }
  9475. }, offset), 0)
  9476. $tip.addClass('in')
  9477. // check to see if placing tip in new offset caused the tip to resize itself
  9478. var actualWidth = $tip[0].offsetWidth
  9479. var actualHeight = $tip[0].offsetHeight
  9480. if (placement == 'top' && actualHeight != height) {
  9481. offset.top = offset.top + height - actualHeight
  9482. }
  9483. var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
  9484. if (delta.left) offset.left += delta.left
  9485. else offset.top += delta.top
  9486. var isVertical = /top|bottom/.test(placement)
  9487. var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
  9488. var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
  9489. $tip.offset(offset)
  9490. this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
  9491. }
  9492. Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
  9493. this.arrow()
  9494. .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
  9495. .css(isVertical ? 'top' : 'left', '')
  9496. }
  9497. Tooltip.prototype.setContent = function () {
  9498. var $tip = this.tip()
  9499. var title = this.getTitle()
  9500. $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
  9501. $tip.removeClass('fade in top bottom left right')
  9502. }
  9503. Tooltip.prototype.hide = function (callback) {
  9504. var that = this
  9505. var $tip = $(this.$tip)
  9506. var e = $.Event('hide.bs.' + this.type)
  9507. function complete() {
  9508. if (that.hoverState != 'in') $tip.detach()
  9509. if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.
  9510. that.$element
  9511. .removeAttr('aria-describedby')
  9512. .trigger('hidden.bs.' + that.type)
  9513. }
  9514. callback && callback()
  9515. }
  9516. this.$element.trigger(e)
  9517. if (e.isDefaultPrevented()) return
  9518. $tip.removeClass('in')
  9519. $.support.transition && $tip.hasClass('fade') ?
  9520. $tip
  9521. .one('bsTransitionEnd', complete)
  9522. .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
  9523. complete()
  9524. this.hoverState = null
  9525. return this
  9526. }
  9527. Tooltip.prototype.fixTitle = function () {
  9528. var $e = this.$element
  9529. if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
  9530. $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
  9531. }
  9532. }
  9533. Tooltip.prototype.hasContent = function () {
  9534. return this.getTitle()
  9535. }
  9536. Tooltip.prototype.getPosition = function ($element) {
  9537. $element = $element || this.$element
  9538. var el = $element[0]
  9539. var isBody = el.tagName == 'BODY'
  9540. var elRect = el.getBoundingClientRect()
  9541. if (elRect.width == null) {
  9542. // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
  9543. elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
  9544. }
  9545. var isSvg = window.SVGElement && el instanceof window.SVGElement
  9546. // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.
  9547. // See https://github.com/twbs/bootstrap/issues/20280
  9548. var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())
  9549. var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
  9550. var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
  9551. return $.extend({}, elRect, scroll, outerDims, elOffset)
  9552. }
  9553. Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
  9554. return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
  9555. placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
  9556. placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
  9557. /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
  9558. }
  9559. Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
  9560. var delta = { top: 0, left: 0 }
  9561. if (!this.$viewport) return delta
  9562. var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
  9563. var viewportDimensions = this.getPosition(this.$viewport)
  9564. if (/right|left/.test(placement)) {
  9565. var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
  9566. var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
  9567. if (topEdgeOffset < viewportDimensions.top) { // top overflow
  9568. delta.top = viewportDimensions.top - topEdgeOffset
  9569. } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
  9570. delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
  9571. }
  9572. } else {
  9573. var leftEdgeOffset = pos.left - viewportPadding
  9574. var rightEdgeOffset = pos.left + viewportPadding + actualWidth
  9575. if (leftEdgeOffset < viewportDimensions.left) { // left overflow
  9576. delta.left = viewportDimensions.left - leftEdgeOffset
  9577. } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
  9578. delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
  9579. }
  9580. }
  9581. return delta
  9582. }
  9583. Tooltip.prototype.getTitle = function () {
  9584. var title
  9585. var $e = this.$element
  9586. var o = this.options
  9587. title = $e.attr('data-original-title')
  9588. || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
  9589. return title
  9590. }
  9591. Tooltip.prototype.getUID = function (prefix) {
  9592. do prefix += ~~(Math.random() * 1000000)
  9593. while (document.getElementById(prefix))
  9594. return prefix
  9595. }
  9596. Tooltip.prototype.tip = function () {
  9597. if (!this.$tip) {
  9598. this.$tip = $(this.options.template)
  9599. if (this.$tip.length != 1) {
  9600. throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
  9601. }
  9602. }
  9603. return this.$tip
  9604. }
  9605. Tooltip.prototype.arrow = function () {
  9606. return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
  9607. }
  9608. Tooltip.prototype.enable = function () {
  9609. this.enabled = true
  9610. }
  9611. Tooltip.prototype.disable = function () {
  9612. this.enabled = false
  9613. }
  9614. Tooltip.prototype.toggleEnabled = function () {
  9615. this.enabled = !this.enabled
  9616. }
  9617. Tooltip.prototype.toggle = function (e) {
  9618. var self = this
  9619. if (e) {
  9620. self = $(e.currentTarget).data('bs.' + this.type)
  9621. if (!self) {
  9622. self = new this.constructor(e.currentTarget, this.getDelegateOptions())
  9623. $(e.currentTarget).data('bs.' + this.type, self)
  9624. }
  9625. }
  9626. if (e) {
  9627. self.inState.click = !self.inState.click
  9628. if (self.isInStateTrue()) self.enter(self)
  9629. else self.leave(self)
  9630. } else {
  9631. self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
  9632. }
  9633. }
  9634. Tooltip.prototype.destroy = function () {
  9635. var that = this
  9636. clearTimeout(this.timeout)
  9637. this.hide(function () {
  9638. that.$element.off('.' + that.type).removeData('bs.' + that.type)
  9639. if (that.$tip) {
  9640. that.$tip.detach()
  9641. }
  9642. that.$tip = null
  9643. that.$arrow = null
  9644. that.$viewport = null
  9645. that.$element = null
  9646. })
  9647. }
  9648. // TOOLTIP PLUGIN DEFINITION
  9649. // =========================
  9650. function Plugin(option) {
  9651. return this.each(function () {
  9652. var $this = $(this)
  9653. var data = $this.data('bs.tooltip')
  9654. var options = typeof option == 'object' && option
  9655. if (!data && /destroy|hide/.test(option)) return
  9656. if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
  9657. if (typeof option == 'string') data[option]()
  9658. })
  9659. }
  9660. var old = $.fn.tooltip
  9661. $.fn.tooltip = Plugin
  9662. $.fn.tooltip.Constructor = Tooltip
  9663. // TOOLTIP NO CONFLICT
  9664. // ===================
  9665. $.fn.tooltip.noConflict = function () {
  9666. $.fn.tooltip = old
  9667. return this
  9668. }
  9669. }(jQuery);
  9670. /* ========================================================================
  9671. * Bootstrap: popover.js v3.3.7
  9672. * http://getbootstrap.com/javascript/#popovers
  9673. * ========================================================================
  9674. * Copyright 2011-2016 Twitter, Inc.
  9675. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  9676. * ======================================================================== */
  9677. +function ($) {
  9678. 'use strict';
  9679. // POPOVER PUBLIC CLASS DEFINITION
  9680. // ===============================
  9681. var Popover = function (element, options) {
  9682. this.init('popover', element, options)
  9683. }
  9684. if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
  9685. Popover.VERSION = '3.3.7'
  9686. Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
  9687. placement: 'right',
  9688. trigger: 'click',
  9689. content: '',
  9690. template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
  9691. })
  9692. // NOTE: POPOVER EXTENDS tooltip.js
  9693. // ================================
  9694. Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
  9695. Popover.prototype.constructor = Popover
  9696. Popover.prototype.getDefaults = function () {
  9697. return Popover.DEFAULTS
  9698. }
  9699. Popover.prototype.setContent = function () {
  9700. var $tip = this.tip()
  9701. var title = this.getTitle()
  9702. var content = this.getContent()
  9703. $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
  9704. $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
  9705. this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
  9706. ](content)
  9707. $tip.removeClass('fade top bottom left right in')
  9708. // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
  9709. // this manually by checking the contents.
  9710. if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
  9711. }
  9712. Popover.prototype.hasContent = function () {
  9713. return this.getTitle() || this.getContent()
  9714. }
  9715. Popover.prototype.getContent = function () {
  9716. var $e = this.$element
  9717. var o = this.options
  9718. return $e.attr('data-content')
  9719. || (typeof o.content == 'function' ?
  9720. o.content.call($e[0]) :
  9721. o.content)
  9722. }
  9723. Popover.prototype.arrow = function () {
  9724. return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
  9725. }
  9726. // POPOVER PLUGIN DEFINITION
  9727. // =========================
  9728. function Plugin(option) {
  9729. return this.each(function () {
  9730. var $this = $(this)
  9731. var data = $this.data('bs.popover')
  9732. var options = typeof option == 'object' && option
  9733. if (!data && /destroy|hide/.test(option)) return
  9734. if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
  9735. if (typeof option == 'string') data[option]()
  9736. })
  9737. }
  9738. var old = $.fn.popover
  9739. $.fn.popover = Plugin
  9740. $.fn.popover.Constructor = Popover
  9741. // POPOVER NO CONFLICT
  9742. // ===================
  9743. $.fn.popover.noConflict = function () {
  9744. $.fn.popover = old
  9745. return this
  9746. }
  9747. }(jQuery);
  9748. /* ========================================================================
  9749. * Bootstrap: scrollspy.js v3.3.7
  9750. * http://getbootstrap.com/javascript/#scrollspy
  9751. * ========================================================================
  9752. * Copyright 2011-2016 Twitter, Inc.
  9753. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  9754. * ======================================================================== */
  9755. +function ($) {
  9756. 'use strict';
  9757. // SCROLLSPY CLASS DEFINITION
  9758. // ==========================
  9759. function ScrollSpy(element, options) {
  9760. this.$body = $(document.body)
  9761. this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
  9762. this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
  9763. this.selector = (this.options.target || '') + ' .nav li > a'
  9764. this.offsets = []
  9765. this.targets = []
  9766. this.activeTarget = null
  9767. this.scrollHeight = 0
  9768. this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
  9769. this.refresh()
  9770. this.process()
  9771. }
  9772. ScrollSpy.VERSION = '3.3.7'
  9773. ScrollSpy.DEFAULTS = {
  9774. offset: 10
  9775. }
  9776. ScrollSpy.prototype.getScrollHeight = function () {
  9777. return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
  9778. }
  9779. ScrollSpy.prototype.refresh = function () {
  9780. var that = this
  9781. var offsetMethod = 'offset'
  9782. var offsetBase = 0
  9783. this.offsets = []
  9784. this.targets = []
  9785. this.scrollHeight = this.getScrollHeight()
  9786. if (!$.isWindow(this.$scrollElement[0])) {
  9787. offsetMethod = 'position'
  9788. offsetBase = this.$scrollElement.scrollTop()
  9789. }
  9790. this.$body
  9791. .find(this.selector)
  9792. .map(function () {
  9793. var $el = $(this)
  9794. var href = $el.data('target') || $el.attr('href')
  9795. var $href = /^#./.test(href) && $(href)
  9796. return ($href
  9797. && $href.length
  9798. && $href.is(':visible')
  9799. && [[$href[offsetMethod]().top + offsetBase, href]]) || null
  9800. })
  9801. .sort(function (a, b) { return a[0] - b[0] })
  9802. .each(function () {
  9803. that.offsets.push(this[0])
  9804. that.targets.push(this[1])
  9805. })
  9806. }
  9807. ScrollSpy.prototype.process = function () {
  9808. var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
  9809. var scrollHeight = this.getScrollHeight()
  9810. var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
  9811. var offsets = this.offsets
  9812. var targets = this.targets
  9813. var activeTarget = this.activeTarget
  9814. var i
  9815. if (this.scrollHeight != scrollHeight) {
  9816. this.refresh()
  9817. }
  9818. if (scrollTop >= maxScroll) {
  9819. return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
  9820. }
  9821. if (activeTarget && scrollTop < offsets[0]) {
  9822. this.activeTarget = null
  9823. return this.clear()
  9824. }
  9825. for (i = offsets.length; i--;) {
  9826. activeTarget != targets[i]
  9827. && scrollTop >= offsets[i]
  9828. && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
  9829. && this.activate(targets[i])
  9830. }
  9831. }
  9832. ScrollSpy.prototype.activate = function (target) {
  9833. this.activeTarget = target
  9834. this.clear()
  9835. var selector = this.selector +
  9836. '[data-target="' + target + '"],' +
  9837. this.selector + '[href="' + target + '"]'
  9838. var active = $(selector)
  9839. .parents('li')
  9840. .addClass('active')
  9841. if (active.parent('.dropdown-menu').length) {
  9842. active = active
  9843. .closest('li.dropdown')
  9844. .addClass('active')
  9845. }
  9846. active.trigger('activate.bs.scrollspy')
  9847. }
  9848. ScrollSpy.prototype.clear = function () {
  9849. $(this.selector)
  9850. .parentsUntil(this.options.target, '.active')
  9851. .removeClass('active')
  9852. }
  9853. // SCROLLSPY PLUGIN DEFINITION
  9854. // ===========================
  9855. function Plugin(option) {
  9856. return this.each(function () {
  9857. var $this = $(this)
  9858. var data = $this.data('bs.scrollspy')
  9859. var options = typeof option == 'object' && option
  9860. if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
  9861. if (typeof option == 'string') data[option]()
  9862. })
  9863. }
  9864. var old = $.fn.scrollspy
  9865. $.fn.scrollspy = Plugin
  9866. $.fn.scrollspy.Constructor = ScrollSpy
  9867. // SCROLLSPY NO CONFLICT
  9868. // =====================
  9869. $.fn.scrollspy.noConflict = function () {
  9870. $.fn.scrollspy = old
  9871. return this
  9872. }
  9873. // SCROLLSPY DATA-API
  9874. // ==================
  9875. $(window).on('load.bs.scrollspy.data-api', function () {
  9876. $('[data-spy="scroll"]').each(function () {
  9877. var $spy = $(this)
  9878. Plugin.call($spy, $spy.data())
  9879. })
  9880. })
  9881. }(jQuery);
  9882. /* ========================================================================
  9883. * Bootstrap: tab.js v3.3.7
  9884. * http://getbootstrap.com/javascript/#tabs
  9885. * ========================================================================
  9886. * Copyright 2011-2016 Twitter, Inc.
  9887. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  9888. * ======================================================================== */
  9889. +function ($) {
  9890. 'use strict';
  9891. // TAB CLASS DEFINITION
  9892. // ====================
  9893. var Tab = function (element) {
  9894. // jscs:disable requireDollarBeforejQueryAssignment
  9895. this.element = $(element)
  9896. // jscs:enable requireDollarBeforejQueryAssignment
  9897. }
  9898. Tab.VERSION = '3.3.7'
  9899. Tab.TRANSITION_DURATION = 150
  9900. Tab.prototype.show = function () {
  9901. var $this = this.element
  9902. var $ul = $this.closest('ul:not(.dropdown-menu)')
  9903. var selector = $this.data('target')
  9904. if (!selector) {
  9905. selector = $this.attr('href')
  9906. selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
  9907. }
  9908. if ($this.parent('li').hasClass('active')) return
  9909. var $previous = $ul.find('.active:last a')
  9910. var hideEvent = $.Event('hide.bs.tab', {
  9911. relatedTarget: $this[0]
  9912. })
  9913. var showEvent = $.Event('show.bs.tab', {
  9914. relatedTarget: $previous[0]
  9915. })
  9916. $previous.trigger(hideEvent)
  9917. $this.trigger(showEvent)
  9918. if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
  9919. var $target = $(selector)
  9920. this.activate($this.closest('li'), $ul)
  9921. this.activate($target, $target.parent(), function () {
  9922. $previous.trigger({
  9923. type: 'hidden.bs.tab',
  9924. relatedTarget: $this[0]
  9925. })
  9926. $this.trigger({
  9927. type: 'shown.bs.tab',
  9928. relatedTarget: $previous[0]
  9929. })
  9930. })
  9931. }
  9932. Tab.prototype.activate = function (element, container, callback) {
  9933. var $active = container.find('> .active')
  9934. var transition = callback
  9935. && $.support.transition
  9936. && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
  9937. function next() {
  9938. $active
  9939. .removeClass('active')
  9940. .find('> .dropdown-menu > .active')
  9941. .removeClass('active')
  9942. .end()
  9943. .find('[data-toggle="tab"]')
  9944. .attr('aria-expanded', false)
  9945. element
  9946. .addClass('active')
  9947. .find('[data-toggle="tab"]')
  9948. .attr('aria-expanded', true)
  9949. if (transition) {
  9950. element[0].offsetWidth // reflow for transition
  9951. element.addClass('in')
  9952. } else {
  9953. element.removeClass('fade')
  9954. }
  9955. if (element.parent('.dropdown-menu').length) {
  9956. element
  9957. .closest('li.dropdown')
  9958. .addClass('active')
  9959. .end()
  9960. .find('[data-toggle="tab"]')
  9961. .attr('aria-expanded', true)
  9962. }
  9963. callback && callback()
  9964. }
  9965. $active.length && transition ?
  9966. $active
  9967. .one('bsTransitionEnd', next)
  9968. .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
  9969. next()
  9970. $active.removeClass('in')
  9971. }
  9972. // TAB PLUGIN DEFINITION
  9973. // =====================
  9974. function Plugin(option) {
  9975. return this.each(function () {
  9976. var $this = $(this)
  9977. var data = $this.data('bs.tab')
  9978. if (!data) $this.data('bs.tab', (data = new Tab(this)))
  9979. if (typeof option == 'string') data[option]()
  9980. })
  9981. }
  9982. var old = $.fn.tab
  9983. $.fn.tab = Plugin
  9984. $.fn.tab.Constructor = Tab
  9985. // TAB NO CONFLICT
  9986. // ===============
  9987. $.fn.tab.noConflict = function () {
  9988. $.fn.tab = old
  9989. return this
  9990. }
  9991. // TAB DATA-API
  9992. // ============
  9993. var clickHandler = function (e) {
  9994. e.preventDefault()
  9995. Plugin.call($(this), 'show')
  9996. }
  9997. $(document)
  9998. .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
  9999. .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
  10000. }(jQuery);
  10001. /* ========================================================================
  10002. * Bootstrap: affix.js v3.3.7
  10003. * http://getbootstrap.com/javascript/#affix
  10004. * ========================================================================
  10005. * Copyright 2011-2016 Twitter, Inc.
  10006. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  10007. * ======================================================================== */
  10008. +function ($) {
  10009. 'use strict';
  10010. // AFFIX CLASS DEFINITION
  10011. // ======================
  10012. var Affix = function (element, options) {
  10013. this.options = $.extend({}, Affix.DEFAULTS, options)
  10014. this.$target = $(this.options.target)
  10015. .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
  10016. .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
  10017. this.$element = $(element)
  10018. this.affixed = null
  10019. this.unpin = null
  10020. this.pinnedOffset = null
  10021. this.checkPosition()
  10022. }
  10023. Affix.VERSION = '3.3.7'
  10024. Affix.RESET = 'affix affix-top affix-bottom'
  10025. Affix.DEFAULTS = {
  10026. offset: 0,
  10027. target: window
  10028. }
  10029. Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
  10030. var scrollTop = this.$target.scrollTop()
  10031. var position = this.$element.offset()
  10032. var targetHeight = this.$target.height()
  10033. if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
  10034. if (this.affixed == 'bottom') {
  10035. if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
  10036. return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
  10037. }
  10038. var initializing = this.affixed == null
  10039. var colliderTop = initializing ? scrollTop : position.top
  10040. var colliderHeight = initializing ? targetHeight : height
  10041. if (offsetTop != null && scrollTop <= offsetTop) return 'top'
  10042. if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
  10043. return false
  10044. }
  10045. Affix.prototype.getPinnedOffset = function () {
  10046. if (this.pinnedOffset) return this.pinnedOffset
  10047. this.$element.removeClass(Affix.RESET).addClass('affix')
  10048. var scrollTop = this.$target.scrollTop()
  10049. var position = this.$element.offset()
  10050. return (this.pinnedOffset = position.top - scrollTop)
  10051. }
  10052. Affix.prototype.checkPositionWithEventLoop = function () {
  10053. setTimeout($.proxy(this.checkPosition, this), 1)
  10054. }
  10055. Affix.prototype.checkPosition = function () {
  10056. if (!this.$element.is(':visible')) return
  10057. var height = this.$element.height()
  10058. var offset = this.options.offset
  10059. var offsetTop = offset.top
  10060. var offsetBottom = offset.bottom
  10061. var scrollHeight = Math.max($(document).height(), $(document.body).height())
  10062. if (typeof offset != 'object') offsetBottom = offsetTop = offset
  10063. if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
  10064. if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
  10065. var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
  10066. if (this.affixed != affix) {
  10067. if (this.unpin != null) this.$element.css('top', '')
  10068. var affixType = 'affix' + (affix ? '-' + affix : '')
  10069. var e = $.Event(affixType + '.bs.affix')
  10070. this.$element.trigger(e)
  10071. if (e.isDefaultPrevented()) return
  10072. this.affixed = affix
  10073. this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
  10074. this.$element
  10075. .removeClass(Affix.RESET)
  10076. .addClass(affixType)
  10077. .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
  10078. }
  10079. if (affix == 'bottom') {
  10080. this.$element.offset({
  10081. top: scrollHeight - height - offsetBottom
  10082. })
  10083. }
  10084. }
  10085. // AFFIX PLUGIN DEFINITION
  10086. // =======================
  10087. function Plugin(option) {
  10088. return this.each(function () {
  10089. var $this = $(this)
  10090. var data = $this.data('bs.affix')
  10091. var options = typeof option == 'object' && option
  10092. if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
  10093. if (typeof option == 'string') data[option]()
  10094. })
  10095. }
  10096. var old = $.fn.affix
  10097. $.fn.affix = Plugin
  10098. $.fn.affix.Constructor = Affix
  10099. // AFFIX NO CONFLICT
  10100. // =================
  10101. $.fn.affix.noConflict = function () {
  10102. $.fn.affix = old
  10103. return this
  10104. }
  10105. // AFFIX DATA-API
  10106. // ==============
  10107. $(window).on('load', function () {
  10108. $('[data-spy="affix"]').each(function () {
  10109. var $spy = $(this)
  10110. var data = $spy.data()
  10111. data.offset = data.offset || {}
  10112. if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
  10113. if (data.offsetTop != null) data.offset.top = data.offsetTop
  10114. Plugin.call($spy, data)
  10115. })
  10116. })
  10117. }(jQuery);
  10118. ;
  10119. /*! DataTables 1.10.15
  10120. * ©2008-2017 SpryMedia Ltd - datatables.net/license
  10121. */
  10122. /**
  10123. * @summary DataTables
  10124. * @description Paginate, search and order HTML tables
  10125. * @version 1.10.15
  10126. * @file jquery.dataTables.js
  10127. * @author SpryMedia Ltd
  10128. * @contact www.datatables.net
  10129. * @copyright Copyright 2008-2017 SpryMedia Ltd.
  10130. *
  10131. * This source file is free software, available under the following license:
  10132. * MIT license - http://datatables.net/license
  10133. *
  10134. * This source file is distributed in the hope that it will be useful, but
  10135. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10136. * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
  10137. *
  10138. * For details please refer to: http://www.datatables.net
  10139. */
  10140. /*jslint evil: true, undef: true, browser: true */
  10141. /*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/
  10142. (function( factory ) {
  10143. "use strict";
  10144. if ( typeof define === 'function' && define.amd ) {
  10145. // AMD
  10146. define( ['jquery'], function ( $ ) {
  10147. return factory( $, window, document );
  10148. } );
  10149. }
  10150. else if ( typeof exports === 'object' ) {
  10151. // CommonJS
  10152. module.exports = function (root, $) {
  10153. if ( ! root ) {
  10154. // CommonJS environments without a window global must pass a
  10155. // root. This will give an error otherwise
  10156. root = window;
  10157. }
  10158. if ( ! $ ) {
  10159. $ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
  10160. require('jquery') :
  10161. require('jquery')( root );
  10162. }
  10163. return factory( $, root, root.document );
  10164. };
  10165. }
  10166. else {
  10167. // Browser
  10168. factory( jQuery, window, document );
  10169. }
  10170. }
  10171. (function( $, window, document, undefined ) {
  10172. "use strict";
  10173. /**
  10174. * DataTables is a plug-in for the jQuery Javascript library. It is a highly
  10175. * flexible tool, based upon the foundations of progressive enhancement,
  10176. * which will add advanced interaction controls to any HTML table. For a
  10177. * full list of features please refer to
  10178. * [DataTables.net](href="http://datatables.net).
  10179. *
  10180. * Note that the `DataTable` object is not a global variable but is aliased
  10181. * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may
  10182. * be accessed.
  10183. *
  10184. * @class
  10185. * @param {object} [init={}] Configuration object for DataTables. Options
  10186. * are defined by {@link DataTable.defaults}
  10187. * @requires jQuery 1.7+
  10188. *
  10189. * @example
  10190. * // Basic initialisation
  10191. * $(document).ready( function {
  10192. * $('#example').dataTable();
  10193. * } );
  10194. *
  10195. * @example
  10196. * // Initialisation with configuration options - in this case, disable
  10197. * // pagination and sorting.
  10198. * $(document).ready( function {
  10199. * $('#example').dataTable( {
  10200. * "paginate": false,
  10201. * "sort": false
  10202. * } );
  10203. * } );
  10204. */
  10205. var DataTable = function ( options )
  10206. {
  10207. /**
  10208. * Perform a jQuery selector action on the table's TR elements (from the tbody) and
  10209. * return the resulting jQuery object.
  10210. * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
  10211. * @param {object} [oOpts] Optional parameters for modifying the rows to be included
  10212. * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
  10213. * criterion ("applied") or all TR elements (i.e. no filter).
  10214. * @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
  10215. * Can be either 'current', whereby the current sorting of the table is used, or
  10216. * 'original' whereby the original order the data was read into the table is used.
  10217. * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
  10218. * ("current") or not ("all"). If 'current' is given, then order is assumed to be
  10219. * 'current' and filter is 'applied', regardless of what they might be given as.
  10220. * @returns {object} jQuery object, filtered by the given selector.
  10221. * @dtopt API
  10222. * @deprecated Since v1.10
  10223. *
  10224. * @example
  10225. * $(document).ready(function() {
  10226. * var oTable = $('#example').dataTable();
  10227. *
  10228. * // Highlight every second row
  10229. * oTable.$('tr:odd').css('backgroundColor', 'blue');
  10230. * } );
  10231. *
  10232. * @example
  10233. * $(document).ready(function() {
  10234. * var oTable = $('#example').dataTable();
  10235. *
  10236. * // Filter to rows with 'Webkit' in them, add a background colour and then
  10237. * // remove the filter, thus highlighting the 'Webkit' rows only.
  10238. * oTable.fnFilter('Webkit');
  10239. * oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue');
  10240. * oTable.fnFilter('');
  10241. * } );
  10242. */
  10243. this.$ = function ( sSelector, oOpts )
  10244. {
  10245. return this.api(true).$( sSelector, oOpts );
  10246. };
  10247. /**
  10248. * Almost identical to $ in operation, but in this case returns the data for the matched
  10249. * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
  10250. * rather than any descendants, so the data can be obtained for the row/cell. If matching
  10251. * rows are found, the data returned is the original data array/object that was used to
  10252. * create the row (or a generated array if from a DOM source).
  10253. *
  10254. * This method is often useful in-combination with $ where both functions are given the
  10255. * same parameters and the array indexes will match identically.
  10256. * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
  10257. * @param {object} [oOpts] Optional parameters for modifying the rows to be included
  10258. * @param {string} [oOpts.filter=none] Select elements that meet the current filter
  10259. * criterion ("applied") or all elements (i.e. no filter).
  10260. * @param {string} [oOpts.order=current] Order of the data in the processed array.
  10261. * Can be either 'current', whereby the current sorting of the table is used, or
  10262. * 'original' whereby the original order the data was read into the table is used.
  10263. * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
  10264. * ("current") or not ("all"). If 'current' is given, then order is assumed to be
  10265. * 'current' and filter is 'applied', regardless of what they might be given as.
  10266. * @returns {array} Data for the matched elements. If any elements, as a result of the
  10267. * selector, were not TR, TD or TH elements in the DataTable, they will have a null
  10268. * entry in the array.
  10269. * @dtopt API
  10270. * @deprecated Since v1.10
  10271. *
  10272. * @example
  10273. * $(document).ready(function() {
  10274. * var oTable = $('#example').dataTable();
  10275. *
  10276. * // Get the data from the first row in the table
  10277. * var data = oTable._('tr:first');
  10278. *
  10279. * // Do something useful with the data
  10280. * alert( "First cell is: "+data[0] );
  10281. * } );
  10282. *
  10283. * @example
  10284. * $(document).ready(function() {
  10285. * var oTable = $('#example').dataTable();
  10286. *
  10287. * // Filter to 'Webkit' and get all data for
  10288. * oTable.fnFilter('Webkit');
  10289. * var data = oTable._('tr', {"search": "applied"});
  10290. *
  10291. * // Do something with the data
  10292. * alert( data.length+" rows matched the search" );
  10293. * } );
  10294. */
  10295. this._ = function ( sSelector, oOpts )
  10296. {
  10297. return this.api(true).rows( sSelector, oOpts ).data();
  10298. };
  10299. /**
  10300. * Create a DataTables Api instance, with the currently selected tables for
  10301. * the Api's context.
  10302. * @param {boolean} [traditional=false] Set the API instance's context to be
  10303. * only the table referred to by the `DataTable.ext.iApiIndex` option, as was
  10304. * used in the API presented by DataTables 1.9- (i.e. the traditional mode),
  10305. * or if all tables captured in the jQuery object should be used.
  10306. * @return {DataTables.Api}
  10307. */
  10308. this.api = function ( traditional )
  10309. {
  10310. return traditional ?
  10311. new _Api(
  10312. _fnSettingsFromNode( this[ _ext.iApiIndex ] )
  10313. ) :
  10314. new _Api( this );
  10315. };
  10316. /**
  10317. * Add a single new row or multiple rows of data to the table. Please note
  10318. * that this is suitable for client-side processing only - if you are using
  10319. * server-side processing (i.e. "bServerSide": true), then to add data, you
  10320. * must add it to the data source, i.e. the server-side, through an Ajax call.
  10321. * @param {array|object} data The data to be added to the table. This can be:
  10322. * <ul>
  10323. * <li>1D array of data - add a single row with the data provided</li>
  10324. * <li>2D array of arrays - add multiple rows in a single call</li>
  10325. * <li>object - data object when using <i>mData</i></li>
  10326. * <li>array of objects - multiple data objects when using <i>mData</i></li>
  10327. * </ul>
  10328. * @param {bool} [redraw=true] redraw the table or not
  10329. * @returns {array} An array of integers, representing the list of indexes in
  10330. * <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
  10331. * the table.
  10332. * @dtopt API
  10333. * @deprecated Since v1.10
  10334. *
  10335. * @example
  10336. * // Global var for counter
  10337. * var giCount = 2;
  10338. *
  10339. * $(document).ready(function() {
  10340. * $('#example').dataTable();
  10341. * } );
  10342. *
  10343. * function fnClickAddRow() {
  10344. * $('#example').dataTable().fnAddData( [
  10345. * giCount+".1",
  10346. * giCount+".2",
  10347. * giCount+".3",
  10348. * giCount+".4" ]
  10349. * );
  10350. *
  10351. * giCount++;
  10352. * }
  10353. */
  10354. this.fnAddData = function( data, redraw )
  10355. {
  10356. var api = this.api( true );
  10357. /* Check if we want to add multiple rows or not */
  10358. var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?
  10359. api.rows.add( data ) :
  10360. api.row.add( data );
  10361. if ( redraw === undefined || redraw ) {
  10362. api.draw();
  10363. }
  10364. return rows.flatten().toArray();
  10365. };
  10366. /**
  10367. * This function will make DataTables recalculate the column sizes, based on the data
  10368. * contained in the table and the sizes applied to the columns (in the DOM, CSS or
  10369. * through the sWidth parameter). This can be useful when the width of the table's
  10370. * parent element changes (for example a window resize).
  10371. * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
  10372. * @dtopt API
  10373. * @deprecated Since v1.10
  10374. *
  10375. * @example
  10376. * $(document).ready(function() {
  10377. * var oTable = $('#example').dataTable( {
  10378. * "sScrollY": "200px",
  10379. * "bPaginate": false
  10380. * } );
  10381. *
  10382. * $(window).on('resize', function () {
  10383. * oTable.fnAdjustColumnSizing();
  10384. * } );
  10385. * } );
  10386. */
  10387. this.fnAdjustColumnSizing = function ( bRedraw )
  10388. {
  10389. var api = this.api( true ).columns.adjust();
  10390. var settings = api.settings()[0];
  10391. var scroll = settings.oScroll;
  10392. if ( bRedraw === undefined || bRedraw ) {
  10393. api.draw( false );
  10394. }
  10395. else if ( scroll.sX !== "" || scroll.sY !== "" ) {
  10396. /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
  10397. _fnScrollDraw( settings );
  10398. }
  10399. };
  10400. /**
  10401. * Quickly and simply clear a table
  10402. * @param {bool} [bRedraw=true] redraw the table or not
  10403. * @dtopt API
  10404. * @deprecated Since v1.10
  10405. *
  10406. * @example
  10407. * $(document).ready(function() {
  10408. * var oTable = $('#example').dataTable();
  10409. *
  10410. * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
  10411. * oTable.fnClearTable();
  10412. * } );
  10413. */
  10414. this.fnClearTable = function( bRedraw )
  10415. {
  10416. var api = this.api( true ).clear();
  10417. if ( bRedraw === undefined || bRedraw ) {
  10418. api.draw();
  10419. }
  10420. };
  10421. /**
  10422. * The exact opposite of 'opening' a row, this function will close any rows which
  10423. * are currently 'open'.
  10424. * @param {node} nTr the table row to 'close'
  10425. * @returns {int} 0 on success, or 1 if failed (can't find the row)
  10426. * @dtopt API
  10427. * @deprecated Since v1.10
  10428. *
  10429. * @example
  10430. * $(document).ready(function() {
  10431. * var oTable;
  10432. *
  10433. * // 'open' an information row when a row is clicked on
  10434. * $('#example tbody tr').click( function () {
  10435. * if ( oTable.fnIsOpen(this) ) {
  10436. * oTable.fnClose( this );
  10437. * } else {
  10438. * oTable.fnOpen( this, "Temporary row opened", "info_row" );
  10439. * }
  10440. * } );
  10441. *
  10442. * oTable = $('#example').dataTable();
  10443. * } );
  10444. */
  10445. this.fnClose = function( nTr )
  10446. {
  10447. this.api( true ).row( nTr ).child.hide();
  10448. };
  10449. /**
  10450. * Remove a row for the table
  10451. * @param {mixed} target The index of the row from aoData to be deleted, or
  10452. * the TR element you want to delete
  10453. * @param {function|null} [callBack] Callback function
  10454. * @param {bool} [redraw=true] Redraw the table or not
  10455. * @returns {array} The row that was deleted
  10456. * @dtopt API
  10457. * @deprecated Since v1.10
  10458. *
  10459. * @example
  10460. * $(document).ready(function() {
  10461. * var oTable = $('#example').dataTable();
  10462. *
  10463. * // Immediately remove the first row
  10464. * oTable.fnDeleteRow( 0 );
  10465. * } );
  10466. */
  10467. this.fnDeleteRow = function( target, callback, redraw )
  10468. {
  10469. var api = this.api( true );
  10470. var rows = api.rows( target );
  10471. var settings = rows.settings()[0];
  10472. var data = settings.aoData[ rows[0][0] ];
  10473. rows.remove();
  10474. if ( callback ) {
  10475. callback.call( this, settings, data );
  10476. }
  10477. if ( redraw === undefined || redraw ) {
  10478. api.draw();
  10479. }
  10480. return data;
  10481. };
  10482. /**
  10483. * Restore the table to it's original state in the DOM by removing all of DataTables
  10484. * enhancements, alterations to the DOM structure of the table and event listeners.
  10485. * @param {boolean} [remove=false] Completely remove the table from the DOM
  10486. * @dtopt API
  10487. * @deprecated Since v1.10
  10488. *
  10489. * @example
  10490. * $(document).ready(function() {
  10491. * // This example is fairly pointless in reality, but shows how fnDestroy can be used
  10492. * var oTable = $('#example').dataTable();
  10493. * oTable.fnDestroy();
  10494. * } );
  10495. */
  10496. this.fnDestroy = function ( remove )
  10497. {
  10498. this.api( true ).destroy( remove );
  10499. };
  10500. /**
  10501. * Redraw the table
  10502. * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.
  10503. * @dtopt API
  10504. * @deprecated Since v1.10
  10505. *
  10506. * @example
  10507. * $(document).ready(function() {
  10508. * var oTable = $('#example').dataTable();
  10509. *
  10510. * // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
  10511. * oTable.fnDraw();
  10512. * } );
  10513. */
  10514. this.fnDraw = function( complete )
  10515. {
  10516. // Note that this isn't an exact match to the old call to _fnDraw - it takes
  10517. // into account the new data, but can hold position.
  10518. this.api( true ).draw( complete );
  10519. };
  10520. /**
  10521. * Filter the input based on data
  10522. * @param {string} sInput String to filter the table on
  10523. * @param {int|null} [iColumn] Column to limit filtering to
  10524. * @param {bool} [bRegex=false] Treat as regular expression or not
  10525. * @param {bool} [bSmart=true] Perform smart filtering or not
  10526. * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
  10527. * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
  10528. * @dtopt API
  10529. * @deprecated Since v1.10
  10530. *
  10531. * @example
  10532. * $(document).ready(function() {
  10533. * var oTable = $('#example').dataTable();
  10534. *
  10535. * // Sometime later - filter...
  10536. * oTable.fnFilter( 'test string' );
  10537. * } );
  10538. */
  10539. this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )
  10540. {
  10541. var api = this.api( true );
  10542. if ( iColumn === null || iColumn === undefined ) {
  10543. api.search( sInput, bRegex, bSmart, bCaseInsensitive );
  10544. }
  10545. else {
  10546. api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );
  10547. }
  10548. api.draw();
  10549. };
  10550. /**
  10551. * Get the data for the whole table, an individual row or an individual cell based on the
  10552. * provided parameters.
  10553. * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as
  10554. * a TR node then the data source for the whole row will be returned. If given as a
  10555. * TD/TH cell node then iCol will be automatically calculated and the data for the
  10556. * cell returned. If given as an integer, then this is treated as the aoData internal
  10557. * data index for the row (see fnGetPosition) and the data for that row used.
  10558. * @param {int} [col] Optional column index that you want the data of.
  10559. * @returns {array|object|string} If mRow is undefined, then the data for all rows is
  10560. * returned. If mRow is defined, just data for that row, and is iCol is
  10561. * defined, only data for the designated cell is returned.
  10562. * @dtopt API
  10563. * @deprecated Since v1.10
  10564. *
  10565. * @example
  10566. * // Row data
  10567. * $(document).ready(function() {
  10568. * oTable = $('#example').dataTable();
  10569. *
  10570. * oTable.$('tr').click( function () {
  10571. * var data = oTable.fnGetData( this );
  10572. * // ... do something with the array / object of data for the row
  10573. * } );
  10574. * } );
  10575. *
  10576. * @example
  10577. * // Individual cell data
  10578. * $(document).ready(function() {
  10579. * oTable = $('#example').dataTable();
  10580. *
  10581. * oTable.$('td').click( function () {
  10582. * var sData = oTable.fnGetData( this );
  10583. * alert( 'The cell clicked on had the value of '+sData );
  10584. * } );
  10585. * } );
  10586. */
  10587. this.fnGetData = function( src, col )
  10588. {
  10589. var api = this.api( true );
  10590. if ( src !== undefined ) {
  10591. var type = src.nodeName ? src.nodeName.toLowerCase() : '';
  10592. return col !== undefined || type == 'td' || type == 'th' ?
  10593. api.cell( src, col ).data() :
  10594. api.row( src ).data() || null;
  10595. }
  10596. return api.data().toArray();
  10597. };
  10598. /**
  10599. * Get an array of the TR nodes that are used in the table's body. Note that you will
  10600. * typically want to use the '$' API method in preference to this as it is more
  10601. * flexible.
  10602. * @param {int} [iRow] Optional row index for the TR element you want
  10603. * @returns {array|node} If iRow is undefined, returns an array of all TR elements
  10604. * in the table's body, or iRow is defined, just the TR element requested.
  10605. * @dtopt API
  10606. * @deprecated Since v1.10
  10607. *
  10608. * @example
  10609. * $(document).ready(function() {
  10610. * var oTable = $('#example').dataTable();
  10611. *
  10612. * // Get the nodes from the table
  10613. * var nNodes = oTable.fnGetNodes( );
  10614. * } );
  10615. */
  10616. this.fnGetNodes = function( iRow )
  10617. {
  10618. var api = this.api( true );
  10619. return iRow !== undefined ?
  10620. api.row( iRow ).node() :
  10621. api.rows().nodes().flatten().toArray();
  10622. };
  10623. /**
  10624. * Get the array indexes of a particular cell from it's DOM element
  10625. * and column index including hidden columns
  10626. * @param {node} node this can either be a TR, TD or TH in the table's body
  10627. * @returns {int} If nNode is given as a TR, then a single index is returned, or
  10628. * if given as a cell, an array of [row index, column index (visible),
  10629. * column index (all)] is given.
  10630. * @dtopt API
  10631. * @deprecated Since v1.10
  10632. *
  10633. * @example
  10634. * $(document).ready(function() {
  10635. * $('#example tbody td').click( function () {
  10636. * // Get the position of the current data from the node
  10637. * var aPos = oTable.fnGetPosition( this );
  10638. *
  10639. * // Get the data array for this row
  10640. * var aData = oTable.fnGetData( aPos[0] );
  10641. *
  10642. * // Update the data array and return the value
  10643. * aData[ aPos[1] ] = 'clicked';
  10644. * this.innerHTML = 'clicked';
  10645. * } );
  10646. *
  10647. * // Init DataTables
  10648. * oTable = $('#example').dataTable();
  10649. * } );
  10650. */
  10651. this.fnGetPosition = function( node )
  10652. {
  10653. var api = this.api( true );
  10654. var nodeName = node.nodeName.toUpperCase();
  10655. if ( nodeName == 'TR' ) {
  10656. return api.row( node ).index();
  10657. }
  10658. else if ( nodeName == 'TD' || nodeName == 'TH' ) {
  10659. var cell = api.cell( node ).index();
  10660. return [
  10661. cell.row,
  10662. cell.columnVisible,
  10663. cell.column
  10664. ];
  10665. }
  10666. return null;
  10667. };
  10668. /**
  10669. * Check to see if a row is 'open' or not.
  10670. * @param {node} nTr the table row to check
  10671. * @returns {boolean} true if the row is currently open, false otherwise
  10672. * @dtopt API
  10673. * @deprecated Since v1.10
  10674. *
  10675. * @example
  10676. * $(document).ready(function() {
  10677. * var oTable;
  10678. *
  10679. * // 'open' an information row when a row is clicked on
  10680. * $('#example tbody tr').click( function () {
  10681. * if ( oTable.fnIsOpen(this) ) {
  10682. * oTable.fnClose( this );
  10683. * } else {
  10684. * oTable.fnOpen( this, "Temporary row opened", "info_row" );
  10685. * }
  10686. * } );
  10687. *
  10688. * oTable = $('#example').dataTable();
  10689. * } );
  10690. */
  10691. this.fnIsOpen = function( nTr )
  10692. {
  10693. return this.api( true ).row( nTr ).child.isShown();
  10694. };
  10695. /**
  10696. * This function will place a new row directly after a row which is currently
  10697. * on display on the page, with the HTML contents that is passed into the
  10698. * function. This can be used, for example, to ask for confirmation that a
  10699. * particular record should be deleted.
  10700. * @param {node} nTr The table row to 'open'
  10701. * @param {string|node|jQuery} mHtml The HTML to put into the row
  10702. * @param {string} sClass Class to give the new TD cell
  10703. * @returns {node} The row opened. Note that if the table row passed in as the
  10704. * first parameter, is not found in the table, this method will silently
  10705. * return.
  10706. * @dtopt API
  10707. * @deprecated Since v1.10
  10708. *
  10709. * @example
  10710. * $(document).ready(function() {
  10711. * var oTable;
  10712. *
  10713. * // 'open' an information row when a row is clicked on
  10714. * $('#example tbody tr').click( function () {
  10715. * if ( oTable.fnIsOpen(this) ) {
  10716. * oTable.fnClose( this );
  10717. * } else {
  10718. * oTable.fnOpen( this, "Temporary row opened", "info_row" );
  10719. * }
  10720. * } );
  10721. *
  10722. * oTable = $('#example').dataTable();
  10723. * } );
  10724. */
  10725. this.fnOpen = function( nTr, mHtml, sClass )
  10726. {
  10727. return this.api( true )
  10728. .row( nTr )
  10729. .child( mHtml, sClass )
  10730. .show()
  10731. .child()[0];
  10732. };
  10733. /**
  10734. * Change the pagination - provides the internal logic for pagination in a simple API
  10735. * function. With this function you can have a DataTables table go to the next,
  10736. * previous, first or last pages.
  10737. * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
  10738. * or page number to jump to (integer), note that page 0 is the first page.
  10739. * @param {bool} [bRedraw=true] Redraw the table or not
  10740. * @dtopt API
  10741. * @deprecated Since v1.10
  10742. *
  10743. * @example
  10744. * $(document).ready(function() {
  10745. * var oTable = $('#example').dataTable();
  10746. * oTable.fnPageChange( 'next' );
  10747. * } );
  10748. */
  10749. this.fnPageChange = function ( mAction, bRedraw )
  10750. {
  10751. var api = this.api( true ).page( mAction );
  10752. if ( bRedraw === undefined || bRedraw ) {
  10753. api.draw(false);
  10754. }
  10755. };
  10756. /**
  10757. * Show a particular column
  10758. * @param {int} iCol The column whose display should be changed
  10759. * @param {bool} bShow Show (true) or hide (false) the column
  10760. * @param {bool} [bRedraw=true] Redraw the table or not
  10761. * @dtopt API
  10762. * @deprecated Since v1.10
  10763. *
  10764. * @example
  10765. * $(document).ready(function() {
  10766. * var oTable = $('#example').dataTable();
  10767. *
  10768. * // Hide the second column after initialisation
  10769. * oTable.fnSetColumnVis( 1, false );
  10770. * } );
  10771. */
  10772. this.fnSetColumnVis = function ( iCol, bShow, bRedraw )
  10773. {
  10774. var api = this.api( true ).column( iCol ).visible( bShow );
  10775. if ( bRedraw === undefined || bRedraw ) {
  10776. api.columns.adjust().draw();
  10777. }
  10778. };
  10779. /**
  10780. * Get the settings for a particular table for external manipulation
  10781. * @returns {object} DataTables settings object. See
  10782. * {@link DataTable.models.oSettings}
  10783. * @dtopt API
  10784. * @deprecated Since v1.10
  10785. *
  10786. * @example
  10787. * $(document).ready(function() {
  10788. * var oTable = $('#example').dataTable();
  10789. * var oSettings = oTable.fnSettings();
  10790. *
  10791. * // Show an example parameter from the settings
  10792. * alert( oSettings._iDisplayStart );
  10793. * } );
  10794. */
  10795. this.fnSettings = function()
  10796. {
  10797. return _fnSettingsFromNode( this[_ext.iApiIndex] );
  10798. };
  10799. /**
  10800. * Sort the table by a particular column
  10801. * @param {int} iCol the data index to sort on. Note that this will not match the
  10802. * 'display index' if you have hidden data entries
  10803. * @dtopt API
  10804. * @deprecated Since v1.10
  10805. *
  10806. * @example
  10807. * $(document).ready(function() {
  10808. * var oTable = $('#example').dataTable();
  10809. *
  10810. * // Sort immediately with columns 0 and 1
  10811. * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
  10812. * } );
  10813. */
  10814. this.fnSort = function( aaSort )
  10815. {
  10816. this.api( true ).order( aaSort ).draw();
  10817. };
  10818. /**
  10819. * Attach a sort listener to an element for a given column
  10820. * @param {node} nNode the element to attach the sort listener to
  10821. * @param {int} iColumn the column that a click on this node will sort on
  10822. * @param {function} [fnCallback] callback function when sort is run
  10823. * @dtopt API
  10824. * @deprecated Since v1.10
  10825. *
  10826. * @example
  10827. * $(document).ready(function() {
  10828. * var oTable = $('#example').dataTable();
  10829. *
  10830. * // Sort on column 1, when 'sorter' is clicked on
  10831. * oTable.fnSortListener( document.getElementById('sorter'), 1 );
  10832. * } );
  10833. */
  10834. this.fnSortListener = function( nNode, iColumn, fnCallback )
  10835. {
  10836. this.api( true ).order.listener( nNode, iColumn, fnCallback );
  10837. };
  10838. /**
  10839. * Update a table cell or row - this method will accept either a single value to
  10840. * update the cell with, an array of values with one element for each column or
  10841. * an object in the same format as the original data source. The function is
  10842. * self-referencing in order to make the multi column updates easier.
  10843. * @param {object|array|string} mData Data to update the cell/row with
  10844. * @param {node|int} mRow TR element you want to update or the aoData index
  10845. * @param {int} [iColumn] The column to update, give as null or undefined to
  10846. * update a whole row.
  10847. * @param {bool} [bRedraw=true] Redraw the table or not
  10848. * @param {bool} [bAction=true] Perform pre-draw actions or not
  10849. * @returns {int} 0 on success, 1 on error
  10850. * @dtopt API
  10851. * @deprecated Since v1.10
  10852. *
  10853. * @example
  10854. * $(document).ready(function() {
  10855. * var oTable = $('#example').dataTable();
  10856. * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
  10857. * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row
  10858. * } );
  10859. */
  10860. this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
  10861. {
  10862. var api = this.api( true );
  10863. if ( iColumn === undefined || iColumn === null ) {
  10864. api.row( mRow ).data( mData );
  10865. }
  10866. else {
  10867. api.cell( mRow, iColumn ).data( mData );
  10868. }
  10869. if ( bAction === undefined || bAction ) {
  10870. api.columns.adjust();
  10871. }
  10872. if ( bRedraw === undefined || bRedraw ) {
  10873. api.draw();
  10874. }
  10875. return 0;
  10876. };
  10877. /**
  10878. * Provide a common method for plug-ins to check the version of DataTables being used, in order
  10879. * to ensure compatibility.
  10880. * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
  10881. * formats "X" and "X.Y" are also acceptable.
  10882. * @returns {boolean} true if this version of DataTables is greater or equal to the required
  10883. * version, or false if this version of DataTales is not suitable
  10884. * @method
  10885. * @dtopt API
  10886. * @deprecated Since v1.10
  10887. *
  10888. * @example
  10889. * $(document).ready(function() {
  10890. * var oTable = $('#example').dataTable();
  10891. * alert( oTable.fnVersionCheck( '1.9.0' ) );
  10892. * } );
  10893. */
  10894. this.fnVersionCheck = _ext.fnVersionCheck;
  10895. var _that = this;
  10896. var emptyInit = options === undefined;
  10897. var len = this.length;
  10898. if ( emptyInit ) {
  10899. options = {};
  10900. }
  10901. this.oApi = this.internal = _ext.internal;
  10902. // Extend with old style plug-in API methods
  10903. for ( var fn in DataTable.ext.internal ) {
  10904. if ( fn ) {
  10905. this[fn] = _fnExternApiFunc(fn);
  10906. }
  10907. }
  10908. this.each(function() {
  10909. // For each initialisation we want to give it a clean initialisation
  10910. // object that can be bashed around
  10911. var o = {};
  10912. var oInit = len > 1 ? // optimisation for single table case
  10913. _fnExtend( o, options, true ) :
  10914. options;
  10915. /*global oInit,_that,emptyInit*/
  10916. var i=0, iLen, j, jLen, k, kLen;
  10917. var sId = this.getAttribute( 'id' );
  10918. var bInitHandedOff = false;
  10919. var defaults = DataTable.defaults;
  10920. var $this = $(this);
  10921. /* Sanity check */
  10922. if ( this.nodeName.toLowerCase() != 'table' )
  10923. {
  10924. _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );
  10925. return;
  10926. }
  10927. /* Backwards compatibility for the defaults */
  10928. _fnCompatOpts( defaults );
  10929. _fnCompatCols( defaults.column );
  10930. /* Convert the camel-case defaults to Hungarian */
  10931. _fnCamelToHungarian( defaults, defaults, true );
  10932. _fnCamelToHungarian( defaults.column, defaults.column, true );
  10933. /* Setting up the initialisation object */
  10934. _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) );
  10935. /* Check to see if we are re-initialising a table */
  10936. var allSettings = DataTable.settings;
  10937. for ( i=0, iLen=allSettings.length ; i<iLen ; i++ )
  10938. {
  10939. var s = allSettings[i];
  10940. /* Base check on table node */
  10941. if ( s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this) )
  10942. {
  10943. var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
  10944. var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
  10945. if ( emptyInit || bRetrieve )
  10946. {
  10947. return s.oInstance;
  10948. }
  10949. else if ( bDestroy )
  10950. {
  10951. s.oInstance.fnDestroy();
  10952. break;
  10953. }
  10954. else
  10955. {
  10956. _fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );
  10957. return;
  10958. }
  10959. }
  10960. /* If the element we are initialising has the same ID as a table which was previously
  10961. * initialised, but the table nodes don't match (from before) then we destroy the old
  10962. * instance by simply deleting it. This is under the assumption that the table has been
  10963. * destroyed by other methods. Anyone using non-id selectors will need to do this manually
  10964. */
  10965. if ( s.sTableId == this.id )
  10966. {
  10967. allSettings.splice( i, 1 );
  10968. break;
  10969. }
  10970. }
  10971. /* Ensure the table has an ID - required for accessibility */
  10972. if ( sId === null || sId === "" )
  10973. {
  10974. sId = "DataTables_Table_"+(DataTable.ext._unique++);
  10975. this.id = sId;
  10976. }
  10977. /* Create the settings object for this table and set some of the default parameters */
  10978. var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
  10979. "sDestroyWidth": $this[0].style.width,
  10980. "sInstance": sId,
  10981. "sTableId": sId
  10982. } );
  10983. oSettings.nTable = this;
  10984. oSettings.oApi = _that.internal;
  10985. oSettings.oInit = oInit;
  10986. allSettings.push( oSettings );
  10987. // Need to add the instance after the instance after the settings object has been added
  10988. // to the settings array, so we can self reference the table instance if more than one
  10989. oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();
  10990. // Backwards compatibility, before we apply all the defaults
  10991. _fnCompatOpts( oInit );
  10992. if ( oInit.oLanguage )
  10993. {
  10994. _fnLanguageCompat( oInit.oLanguage );
  10995. }
  10996. // If the length menu is given, but the init display length is not, use the length menu
  10997. if ( oInit.aLengthMenu && ! oInit.iDisplayLength )
  10998. {
  10999. oInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?
  11000. oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
  11001. }
  11002. // Apply the defaults and init options to make a single init object will all
  11003. // options defined from defaults and instance options.
  11004. oInit = _fnExtend( $.extend( true, {}, defaults ), oInit );
  11005. // Map the initialisation options onto the settings object
  11006. _fnMap( oSettings.oFeatures, oInit, [
  11007. "bPaginate",
  11008. "bLengthChange",
  11009. "bFilter",
  11010. "bSort",
  11011. "bSortMulti",
  11012. "bInfo",
  11013. "bProcessing",
  11014. "bAutoWidth",
  11015. "bSortClasses",
  11016. "bServerSide",
  11017. "bDeferRender"
  11018. ] );
  11019. _fnMap( oSettings, oInit, [
  11020. "asStripeClasses",
  11021. "ajax",
  11022. "fnServerData",
  11023. "fnFormatNumber",
  11024. "sServerMethod",
  11025. "aaSorting",
  11026. "aaSortingFixed",
  11027. "aLengthMenu",
  11028. "sPaginationType",
  11029. "sAjaxSource",
  11030. "sAjaxDataProp",
  11031. "iStateDuration",
  11032. "sDom",
  11033. "bSortCellsTop",
  11034. "iTabIndex",
  11035. "fnStateLoadCallback",
  11036. "fnStateSaveCallback",
  11037. "renderer",
  11038. "searchDelay",
  11039. "rowId",
  11040. [ "iCookieDuration", "iStateDuration" ], // backwards compat
  11041. [ "oSearch", "oPreviousSearch" ],
  11042. [ "aoSearchCols", "aoPreSearchCols" ],
  11043. [ "iDisplayLength", "_iDisplayLength" ],
  11044. [ "bJQueryUI", "bJUI" ]
  11045. ] );
  11046. _fnMap( oSettings.oScroll, oInit, [
  11047. [ "sScrollX", "sX" ],
  11048. [ "sScrollXInner", "sXInner" ],
  11049. [ "sScrollY", "sY" ],
  11050. [ "bScrollCollapse", "bCollapse" ]
  11051. ] );
  11052. _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
  11053. /* Callback functions which are array driven */
  11054. _fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' );
  11055. _fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' );
  11056. _fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' );
  11057. _fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' );
  11058. _fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' );
  11059. _fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' );
  11060. _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' );
  11061. _fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' );
  11062. _fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user' );
  11063. _fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' );
  11064. _fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' );
  11065. oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );
  11066. /* Browser support detection */
  11067. _fnBrowserDetect( oSettings );
  11068. var oClasses = oSettings.oClasses;
  11069. // @todo Remove in 1.11
  11070. if ( oInit.bJQueryUI )
  11071. {
  11072. /* Use the JUI classes object for display. You could clone the oStdClasses object if
  11073. * you want to have multiple tables with multiple independent classes
  11074. */
  11075. $.extend( oClasses, DataTable.ext.oJUIClasses, oInit.oClasses );
  11076. if ( oInit.sDom === defaults.sDom && defaults.sDom === "lfrtip" )
  11077. {
  11078. /* Set the DOM to use a layout suitable for jQuery UI's theming */
  11079. oSettings.sDom = '<"H"lfr>t<"F"ip>';
  11080. }
  11081. if ( ! oSettings.renderer ) {
  11082. oSettings.renderer = 'jqueryui';
  11083. }
  11084. else if ( $.isPlainObject( oSettings.renderer ) && ! oSettings.renderer.header ) {
  11085. oSettings.renderer.header = 'jqueryui';
  11086. }
  11087. }
  11088. else
  11089. {
  11090. $.extend( oClasses, DataTable.ext.classes, oInit.oClasses );
  11091. }
  11092. $this.addClass( oClasses.sTable );
  11093. if ( oSettings.iInitDisplayStart === undefined )
  11094. {
  11095. /* Display start point, taking into account the save saving */
  11096. oSettings.iInitDisplayStart = oInit.iDisplayStart;
  11097. oSettings._iDisplayStart = oInit.iDisplayStart;
  11098. }
  11099. if ( oInit.iDeferLoading !== null )
  11100. {
  11101. oSettings.bDeferLoading = true;
  11102. var tmp = $.isArray( oInit.iDeferLoading );
  11103. oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
  11104. oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
  11105. }
  11106. /* Language definitions */
  11107. var oLanguage = oSettings.oLanguage;
  11108. $.extend( true, oLanguage, oInit.oLanguage );
  11109. if ( oLanguage.sUrl )
  11110. {
  11111. /* Get the language definitions from a file - because this Ajax call makes the language
  11112. * get async to the remainder of this function we use bInitHandedOff to indicate that
  11113. * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
  11114. */
  11115. $.ajax( {
  11116. dataType: 'json',
  11117. url: oLanguage.sUrl,
  11118. success: function ( json ) {
  11119. _fnLanguageCompat( json );
  11120. _fnCamelToHungarian( defaults.oLanguage, json );
  11121. $.extend( true, oLanguage, json );
  11122. _fnInitialise( oSettings );
  11123. },
  11124. error: function () {
  11125. // Error occurred loading language file, continue on as best we can
  11126. _fnInitialise( oSettings );
  11127. }
  11128. } );
  11129. bInitHandedOff = true;
  11130. }
  11131. /*
  11132. * Stripes
  11133. */
  11134. if ( oInit.asStripeClasses === null )
  11135. {
  11136. oSettings.asStripeClasses =[
  11137. oClasses.sStripeOdd,
  11138. oClasses.sStripeEven
  11139. ];
  11140. }
  11141. /* Remove row stripe classes if they are already on the table row */
  11142. var stripeClasses = oSettings.asStripeClasses;
  11143. var rowOne = $this.children('tbody').find('tr').eq(0);
  11144. if ( $.inArray( true, $.map( stripeClasses, function(el, i) {
  11145. return rowOne.hasClass(el);
  11146. } ) ) !== -1 ) {
  11147. $('tbody tr', this).removeClass( stripeClasses.join(' ') );
  11148. oSettings.asDestroyStripes = stripeClasses.slice();
  11149. }
  11150. /*
  11151. * Columns
  11152. * See if we should load columns automatically or use defined ones
  11153. */
  11154. var anThs = [];
  11155. var aoColumnsInit;
  11156. var nThead = this.getElementsByTagName('thead');
  11157. if ( nThead.length !== 0 )
  11158. {
  11159. _fnDetectHeader( oSettings.aoHeader, nThead[0] );
  11160. anThs = _fnGetUniqueThs( oSettings );
  11161. }
  11162. /* If not given a column array, generate one with nulls */
  11163. if ( oInit.aoColumns === null )
  11164. {
  11165. aoColumnsInit = [];
  11166. for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
  11167. {
  11168. aoColumnsInit.push( null );
  11169. }
  11170. }
  11171. else
  11172. {
  11173. aoColumnsInit = oInit.aoColumns;
  11174. }
  11175. /* Add the columns */
  11176. for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
  11177. {
  11178. _fnAddColumn( oSettings, anThs ? anThs[i] : null );
  11179. }
  11180. /* Apply the column definitions */
  11181. _fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
  11182. _fnColumnOptions( oSettings, iCol, oDef );
  11183. } );
  11184. /* HTML5 attribute detection - build an mData object automatically if the
  11185. * attributes are found
  11186. */
  11187. if ( rowOne.length ) {
  11188. var a = function ( cell, name ) {
  11189. return cell.getAttribute( 'data-'+name ) !== null ? name : null;
  11190. };
  11191. $( rowOne[0] ).children('th, td').each( function (i, cell) {
  11192. var col = oSettings.aoColumns[i];
  11193. if ( col.mData === i ) {
  11194. var sort = a( cell, 'sort' ) || a( cell, 'order' );
  11195. var filter = a( cell, 'filter' ) || a( cell, 'search' );
  11196. if ( sort !== null || filter !== null ) {
  11197. col.mData = {
  11198. _: i+'.display',
  11199. sort: sort !== null ? i+'.@data-'+sort : undefined,
  11200. type: sort !== null ? i+'.@data-'+sort : undefined,
  11201. filter: filter !== null ? i+'.@data-'+filter : undefined
  11202. };
  11203. _fnColumnOptions( oSettings, i );
  11204. }
  11205. }
  11206. } );
  11207. }
  11208. var features = oSettings.oFeatures;
  11209. var loadedInit = function () {
  11210. /*
  11211. * Sorting
  11212. * @todo For modularisation (1.11) this needs to do into a sort start up handler
  11213. */
  11214. // If aaSorting is not defined, then we use the first indicator in asSorting
  11215. // in case that has been altered, so the default sort reflects that option
  11216. if ( oInit.aaSorting === undefined ) {
  11217. var sorting = oSettings.aaSorting;
  11218. for ( i=0, iLen=sorting.length ; i<iLen ; i++ ) {
  11219. sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
  11220. }
  11221. }
  11222. /* Do a first pass on the sorting classes (allows any size changes to be taken into
  11223. * account, and also will apply sorting disabled classes if disabled
  11224. */
  11225. _fnSortingClasses( oSettings );
  11226. if ( features.bSort ) {
  11227. _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
  11228. if ( oSettings.bSorted ) {
  11229. var aSort = _fnSortFlatten( oSettings );
  11230. var sortedColumns = {};
  11231. $.each( aSort, function (i, val) {
  11232. sortedColumns[ val.src ] = val.dir;
  11233. } );
  11234. _fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );
  11235. _fnSortAria( oSettings );
  11236. }
  11237. } );
  11238. }
  11239. _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
  11240. if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
  11241. _fnSortingClasses( oSettings );
  11242. }
  11243. }, 'sc' );
  11244. /*
  11245. * Final init
  11246. * Cache the header, body and footer as required, creating them if needed
  11247. */
  11248. // Work around for Webkit bug 83867 - store the caption-side before removing from doc
  11249. var captions = $this.children('caption').each( function () {
  11250. this._captionSide = $(this).css('caption-side');
  11251. } );
  11252. var thead = $this.children('thead');
  11253. if ( thead.length === 0 ) {
  11254. thead = $('<thead/>').appendTo($this);
  11255. }
  11256. oSettings.nTHead = thead[0];
  11257. var tbody = $this.children('tbody');
  11258. if ( tbody.length === 0 ) {
  11259. tbody = $('<tbody/>').appendTo($this);
  11260. }
  11261. oSettings.nTBody = tbody[0];
  11262. var tfoot = $this.children('tfoot');
  11263. if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) {
  11264. // If we are a scrolling table, and no footer has been given, then we need to create
  11265. // a tfoot element for the caption element to be appended to
  11266. tfoot = $('<tfoot/>').appendTo($this);
  11267. }
  11268. if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
  11269. $this.addClass( oClasses.sNoFooter );
  11270. }
  11271. else if ( tfoot.length > 0 ) {
  11272. oSettings.nTFoot = tfoot[0];
  11273. _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
  11274. }
  11275. /* Check if there is data passing into the constructor */
  11276. if ( oInit.aaData ) {
  11277. for ( i=0 ; i<oInit.aaData.length ; i++ ) {
  11278. _fnAddData( oSettings, oInit.aaData[ i ] );
  11279. }
  11280. }
  11281. else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' ) {
  11282. /* Grab the data from the page - only do this when deferred loading or no Ajax
  11283. * source since there is no point in reading the DOM data if we are then going
  11284. * to replace it with Ajax data
  11285. */
  11286. _fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
  11287. }
  11288. /* Copy the data index array */
  11289. oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
  11290. /* Initialisation complete - table can be drawn */
  11291. oSettings.bInitialised = true;
  11292. /* Check if we need to initialise the table (it might not have been handed off to the
  11293. * language processor)
  11294. */
  11295. if ( bInitHandedOff === false ) {
  11296. _fnInitialise( oSettings );
  11297. }
  11298. };
  11299. /* Must be done after everything which can be overridden by the state saving! */
  11300. if ( oInit.bStateSave )
  11301. {
  11302. features.bStateSave = true;
  11303. _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
  11304. _fnLoadState( oSettings, oInit, loadedInit );
  11305. }
  11306. else {
  11307. loadedInit();
  11308. }
  11309. } );
  11310. _that = null;
  11311. return this;
  11312. };
  11313. /*
  11314. * It is useful to have variables which are scoped locally so only the
  11315. * DataTables functions can access them and they don't leak into global space.
  11316. * At the same time these functions are often useful over multiple files in the
  11317. * core and API, so we list, or at least document, all variables which are used
  11318. * by DataTables as private variables here. This also ensures that there is no
  11319. * clashing of variable names and that they can easily referenced for reuse.
  11320. */
  11321. // Defined else where
  11322. // _selector_run
  11323. // _selector_opts
  11324. // _selector_first
  11325. // _selector_row_indexes
  11326. var _ext; // DataTable.ext
  11327. var _Api; // DataTable.Api
  11328. var _api_register; // DataTable.Api.register
  11329. var _api_registerPlural; // DataTable.Api.registerPlural
  11330. var _re_dic = {};
  11331. var _re_new_lines = /[\r\n]/g;
  11332. var _re_html = /<.*?>/g;
  11333. // This is not strict ISO8601 - Date.parse() is quite lax, although
  11334. // implementations differ between browsers.
  11335. var _re_date = /^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/;
  11336. // Escape regular expression special characters
  11337. var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' );
  11338. // http://en.wikipedia.org/wiki/Foreign_exchange_market
  11339. // - \u20BD - Russian ruble.
  11340. // - \u20a9 - South Korean Won
  11341. // - \u20BA - Turkish Lira
  11342. // - \u20B9 - Indian Rupee
  11343. // - R - Brazil (R$) and South Africa
  11344. // - fr - Swiss Franc
  11345. // - kr - Swedish krona, Norwegian krone and Danish krone
  11346. // - \u2009 is thin space and \u202F is narrow no-break space, both used in many
  11347. // standards as thousands separators.
  11348. var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi;
  11349. var _empty = function ( d ) {
  11350. return !d || d === true || d === '-' ? true : false;
  11351. };
  11352. var _intVal = function ( s ) {
  11353. var integer = parseInt( s, 10 );
  11354. return !isNaN(integer) && isFinite(s) ? integer : null;
  11355. };
  11356. // Convert from a formatted number with characters other than `.` as the
  11357. // decimal place, to a Javascript number
  11358. var _numToDecimal = function ( num, decimalPoint ) {
  11359. // Cache created regular expressions for speed as this function is called often
  11360. if ( ! _re_dic[ decimalPoint ] ) {
  11361. _re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );
  11362. }
  11363. return typeof num === 'string' && decimalPoint !== '.' ?
  11364. num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :
  11365. num;
  11366. };
  11367. var _isNumber = function ( d, decimalPoint, formatted ) {
  11368. var strType = typeof d === 'string';
  11369. // If empty return immediately so there must be a number if it is a
  11370. // formatted string (this stops the string "k", or "kr", etc being detected
  11371. // as a formatted number for currency
  11372. if ( _empty( d ) ) {
  11373. return true;
  11374. }
  11375. if ( decimalPoint && strType ) {
  11376. d = _numToDecimal( d, decimalPoint );
  11377. }
  11378. if ( formatted && strType ) {
  11379. d = d.replace( _re_formatted_numeric, '' );
  11380. }
  11381. return !isNaN( parseFloat(d) ) && isFinite( d );
  11382. };
  11383. // A string without HTML in it can be considered to be HTML still
  11384. var _isHtml = function ( d ) {
  11385. return _empty( d ) || typeof d === 'string';
  11386. };
  11387. var _htmlNumeric = function ( d, decimalPoint, formatted ) {
  11388. if ( _empty( d ) ) {
  11389. return true;
  11390. }
  11391. var html = _isHtml( d );
  11392. return ! html ?
  11393. null :
  11394. _isNumber( _stripHtml( d ), decimalPoint, formatted ) ?
  11395. true :
  11396. null;
  11397. };
  11398. var _pluck = function ( a, prop, prop2 ) {
  11399. var out = [];
  11400. var i=0, ien=a.length;
  11401. // Could have the test in the loop for slightly smaller code, but speed
  11402. // is essential here
  11403. if ( prop2 !== undefined ) {
  11404. for ( ; i<ien ; i++ ) {
  11405. if ( a[i] && a[i][ prop ] ) {
  11406. out.push( a[i][ prop ][ prop2 ] );
  11407. }
  11408. }
  11409. }
  11410. else {
  11411. for ( ; i<ien ; i++ ) {
  11412. if ( a[i] ) {
  11413. out.push( a[i][ prop ] );
  11414. }
  11415. }
  11416. }
  11417. return out;
  11418. };
  11419. // Basically the same as _pluck, but rather than looping over `a` we use `order`
  11420. // as the indexes to pick from `a`
  11421. var _pluck_order = function ( a, order, prop, prop2 )
  11422. {
  11423. var out = [];
  11424. var i=0, ien=order.length;
  11425. // Could have the test in the loop for slightly smaller code, but speed
  11426. // is essential here
  11427. if ( prop2 !== undefined ) {
  11428. for ( ; i<ien ; i++ ) {
  11429. if ( a[ order[i] ][ prop ] ) {
  11430. out.push( a[ order[i] ][ prop ][ prop2 ] );
  11431. }
  11432. }
  11433. }
  11434. else {
  11435. for ( ; i<ien ; i++ ) {
  11436. out.push( a[ order[i] ][ prop ] );
  11437. }
  11438. }
  11439. return out;
  11440. };
  11441. var _range = function ( len, start )
  11442. {
  11443. var out = [];
  11444. var end;
  11445. if ( start === undefined ) {
  11446. start = 0;
  11447. end = len;
  11448. }
  11449. else {
  11450. end = start;
  11451. start = len;
  11452. }
  11453. for ( var i=start ; i<end ; i++ ) {
  11454. out.push( i );
  11455. }
  11456. return out;
  11457. };
  11458. var _removeEmpty = function ( a )
  11459. {
  11460. var out = [];
  11461. for ( var i=0, ien=a.length ; i<ien ; i++ ) {
  11462. if ( a[i] ) { // careful - will remove all falsy values!
  11463. out.push( a[i] );
  11464. }
  11465. }
  11466. return out;
  11467. };
  11468. var _stripHtml = function ( d ) {
  11469. return d.replace( _re_html, '' );
  11470. };
  11471. /**
  11472. * Determine if all values in the array are unique. This means we can short
  11473. * cut the _unique method at the cost of a single loop. A sorted array is used
  11474. * to easily check the values.
  11475. *
  11476. * @param {array} src Source array
  11477. * @return {boolean} true if all unique, false otherwise
  11478. * @ignore
  11479. */
  11480. var _areAllUnique = function ( src ) {
  11481. if ( src.length < 2 ) {
  11482. return true;
  11483. }
  11484. var sorted = src.slice().sort();
  11485. var last = sorted[0];
  11486. for ( var i=1, ien=sorted.length ; i<ien ; i++ ) {
  11487. if ( sorted[i] === last ) {
  11488. return false;
  11489. }
  11490. last = sorted[i];
  11491. }
  11492. return true;
  11493. };
  11494. /**
  11495. * Find the unique elements in a source array.
  11496. *
  11497. * @param {array} src Source array
  11498. * @return {array} Array of unique items
  11499. * @ignore
  11500. */
  11501. var _unique = function ( src )
  11502. {
  11503. if ( _areAllUnique( src ) ) {
  11504. return src.slice();
  11505. }
  11506. // A faster unique method is to use object keys to identify used values,
  11507. // but this doesn't work with arrays or objects, which we must also
  11508. // consider. See jsperf.com/compare-array-unique-versions/4 for more
  11509. // information.
  11510. var
  11511. out = [],
  11512. val,
  11513. i, ien=src.length,
  11514. j, k=0;
  11515. again: for ( i=0 ; i<ien ; i++ ) {
  11516. val = src[i];
  11517. for ( j=0 ; j<k ; j++ ) {
  11518. if ( out[j] === val ) {
  11519. continue again;
  11520. }
  11521. }
  11522. out.push( val );
  11523. k++;
  11524. }
  11525. return out;
  11526. };
  11527. /**
  11528. * DataTables utility methods
  11529. *
  11530. * This namespace provides helper methods that DataTables uses internally to
  11531. * create a DataTable, but which are not exclusively used only for DataTables.
  11532. * These methods can be used by extension authors to save the duplication of
  11533. * code.
  11534. *
  11535. * @namespace
  11536. */
  11537. DataTable.util = {
  11538. /**
  11539. * Throttle the calls to a function. Arguments and context are maintained
  11540. * for the throttled function.
  11541. *
  11542. * @param {function} fn Function to be called
  11543. * @param {integer} freq Call frequency in mS
  11544. * @return {function} Wrapped function
  11545. */
  11546. throttle: function ( fn, freq ) {
  11547. var
  11548. frequency = freq !== undefined ? freq : 200,
  11549. last,
  11550. timer;
  11551. return function () {
  11552. var
  11553. that = this,
  11554. now = +new Date(),
  11555. args = arguments;
  11556. if ( last && now < last + frequency ) {
  11557. clearTimeout( timer );
  11558. timer = setTimeout( function () {
  11559. last = undefined;
  11560. fn.apply( that, args );
  11561. }, frequency );
  11562. }
  11563. else {
  11564. last = now;
  11565. fn.apply( that, args );
  11566. }
  11567. };
  11568. },
  11569. /**
  11570. * Escape a string such that it can be used in a regular expression
  11571. *
  11572. * @param {string} val string to escape
  11573. * @returns {string} escaped string
  11574. */
  11575. escapeRegex: function ( val ) {
  11576. return val.replace( _re_escape_regex, '\\$1' );
  11577. }
  11578. };
  11579. /**
  11580. * Create a mapping object that allows camel case parameters to be looked up
  11581. * for their Hungarian counterparts. The mapping is stored in a private
  11582. * parameter called `_hungarianMap` which can be accessed on the source object.
  11583. * @param {object} o
  11584. * @memberof DataTable#oApi
  11585. */
  11586. function _fnHungarianMap ( o )
  11587. {
  11588. var
  11589. hungarian = 'a aa ai ao as b fn i m o s ',
  11590. match,
  11591. newKey,
  11592. map = {};
  11593. $.each( o, function (key, val) {
  11594. match = key.match(/^([^A-Z]+?)([A-Z])/);
  11595. if ( match && hungarian.indexOf(match[1]+' ') !== -1 )
  11596. {
  11597. newKey = key.replace( match[0], match[2].toLowerCase() );
  11598. map[ newKey ] = key;
  11599. if ( match[1] === 'o' )
  11600. {
  11601. _fnHungarianMap( o[key] );
  11602. }
  11603. }
  11604. } );
  11605. o._hungarianMap = map;
  11606. }
  11607. /**
  11608. * Convert from camel case parameters to Hungarian, based on a Hungarian map
  11609. * created by _fnHungarianMap.
  11610. * @param {object} src The model object which holds all parameters that can be
  11611. * mapped.
  11612. * @param {object} user The object to convert from camel case to Hungarian.
  11613. * @param {boolean} force When set to `true`, properties which already have a
  11614. * Hungarian value in the `user` object will be overwritten. Otherwise they
  11615. * won't be.
  11616. * @memberof DataTable#oApi
  11617. */
  11618. function _fnCamelToHungarian ( src, user, force )
  11619. {
  11620. if ( ! src._hungarianMap ) {
  11621. _fnHungarianMap( src );
  11622. }
  11623. var hungarianKey;
  11624. $.each( user, function (key, val) {
  11625. hungarianKey = src._hungarianMap[ key ];
  11626. if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )
  11627. {
  11628. // For objects, we need to buzz down into the object to copy parameters
  11629. if ( hungarianKey.charAt(0) === 'o' )
  11630. {
  11631. // Copy the camelCase options over to the hungarian
  11632. if ( ! user[ hungarianKey ] ) {
  11633. user[ hungarianKey ] = {};
  11634. }
  11635. $.extend( true, user[hungarianKey], user[key] );
  11636. _fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );
  11637. }
  11638. else {
  11639. user[hungarianKey] = user[ key ];
  11640. }
  11641. }
  11642. } );
  11643. }
  11644. /**
  11645. * Language compatibility - when certain options are given, and others aren't, we
  11646. * need to duplicate the values over, in order to provide backwards compatibility
  11647. * with older language files.
  11648. * @param {object} oSettings dataTables settings object
  11649. * @memberof DataTable#oApi
  11650. */
  11651. function _fnLanguageCompat( lang )
  11652. {
  11653. var defaults = DataTable.defaults.oLanguage;
  11654. var zeroRecords = lang.sZeroRecords;
  11655. /* Backwards compatibility - if there is no sEmptyTable given, then use the same as
  11656. * sZeroRecords - assuming that is given.
  11657. */
  11658. if ( ! lang.sEmptyTable && zeroRecords &&
  11659. defaults.sEmptyTable === "No data available in table" )
  11660. {
  11661. _fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
  11662. }
  11663. /* Likewise with loading records */
  11664. if ( ! lang.sLoadingRecords && zeroRecords &&
  11665. defaults.sLoadingRecords === "Loading..." )
  11666. {
  11667. _fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
  11668. }
  11669. // Old parameter name of the thousands separator mapped onto the new
  11670. if ( lang.sInfoThousands ) {
  11671. lang.sThousands = lang.sInfoThousands;
  11672. }
  11673. var decimal = lang.sDecimal;
  11674. if ( decimal ) {
  11675. _addNumericSort( decimal );
  11676. }
  11677. }
  11678. /**
  11679. * Map one parameter onto another
  11680. * @param {object} o Object to map
  11681. * @param {*} knew The new parameter name
  11682. * @param {*} old The old parameter name
  11683. */
  11684. var _fnCompatMap = function ( o, knew, old ) {
  11685. if ( o[ knew ] !== undefined ) {
  11686. o[ old ] = o[ knew ];
  11687. }
  11688. };
  11689. /**
  11690. * Provide backwards compatibility for the main DT options. Note that the new
  11691. * options are mapped onto the old parameters, so this is an external interface
  11692. * change only.
  11693. * @param {object} init Object to map
  11694. */
  11695. function _fnCompatOpts ( init )
  11696. {
  11697. _fnCompatMap( init, 'ordering', 'bSort' );
  11698. _fnCompatMap( init, 'orderMulti', 'bSortMulti' );
  11699. _fnCompatMap( init, 'orderClasses', 'bSortClasses' );
  11700. _fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );
  11701. _fnCompatMap( init, 'order', 'aaSorting' );
  11702. _fnCompatMap( init, 'orderFixed', 'aaSortingFixed' );
  11703. _fnCompatMap( init, 'paging', 'bPaginate' );
  11704. _fnCompatMap( init, 'pagingType', 'sPaginationType' );
  11705. _fnCompatMap( init, 'pageLength', 'iDisplayLength' );
  11706. _fnCompatMap( init, 'searching', 'bFilter' );
  11707. // Boolean initialisation of x-scrolling
  11708. if ( typeof init.sScrollX === 'boolean' ) {
  11709. init.sScrollX = init.sScrollX ? '100%' : '';
  11710. }
  11711. if ( typeof init.scrollX === 'boolean' ) {
  11712. init.scrollX = init.scrollX ? '100%' : '';
  11713. }
  11714. // Column search objects are in an array, so it needs to be converted
  11715. // element by element
  11716. var searchCols = init.aoSearchCols;
  11717. if ( searchCols ) {
  11718. for ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {
  11719. if ( searchCols[i] ) {
  11720. _fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );
  11721. }
  11722. }
  11723. }
  11724. }
  11725. /**
  11726. * Provide backwards compatibility for column options. Note that the new options
  11727. * are mapped onto the old parameters, so this is an external interface change
  11728. * only.
  11729. * @param {object} init Object to map
  11730. */
  11731. function _fnCompatCols ( init )
  11732. {
  11733. _fnCompatMap( init, 'orderable', 'bSortable' );
  11734. _fnCompatMap( init, 'orderData', 'aDataSort' );
  11735. _fnCompatMap( init, 'orderSequence', 'asSorting' );
  11736. _fnCompatMap( init, 'orderDataType', 'sortDataType' );
  11737. // orderData can be given as an integer
  11738. var dataSort = init.aDataSort;
  11739. if ( typeof dataSort === 'number' && ! $.isArray( dataSort ) ) {
  11740. init.aDataSort = [ dataSort ];
  11741. }
  11742. }
  11743. /**
  11744. * Browser feature detection for capabilities, quirks
  11745. * @param {object} settings dataTables settings object
  11746. * @memberof DataTable#oApi
  11747. */
  11748. function _fnBrowserDetect( settings )
  11749. {
  11750. // We don't need to do this every time DataTables is constructed, the values
  11751. // calculated are specific to the browser and OS configuration which we
  11752. // don't expect to change between initialisations
  11753. if ( ! DataTable.__browser ) {
  11754. var browser = {};
  11755. DataTable.__browser = browser;
  11756. // Scrolling feature / quirks detection
  11757. var n = $('<div/>')
  11758. .css( {
  11759. position: 'fixed',
  11760. top: 0,
  11761. left: $(window).scrollLeft()*-1, // allow for scrolling
  11762. height: 1,
  11763. width: 1,
  11764. overflow: 'hidden'
  11765. } )
  11766. .append(
  11767. $('<div/>')
  11768. .css( {
  11769. position: 'absolute',
  11770. top: 1,
  11771. left: 1,
  11772. width: 100,
  11773. overflow: 'scroll'
  11774. } )
  11775. .append(
  11776. $('<div/>')
  11777. .css( {
  11778. width: '100%',
  11779. height: 10
  11780. } )
  11781. )
  11782. )
  11783. .appendTo( 'body' );
  11784. var outer = n.children();
  11785. var inner = outer.children();
  11786. // Numbers below, in order, are:
  11787. // inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth
  11788. //
  11789. // IE6 XP: 100 100 100 83
  11790. // IE7 Vista: 100 100 100 83
  11791. // IE 8+ Windows: 83 83 100 83
  11792. // Evergreen Windows: 83 83 100 83
  11793. // Evergreen Mac with scrollbars: 85 85 100 85
  11794. // Evergreen Mac without scrollbars: 100 100 100 100
  11795. // Get scrollbar width
  11796. browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;
  11797. // IE6/7 will oversize a width 100% element inside a scrolling element, to
  11798. // include the width of the scrollbar, while other browsers ensure the inner
  11799. // element is contained without forcing scrolling
  11800. browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;
  11801. // In rtl text layout, some browsers (most, but not all) will place the
  11802. // scrollbar on the left, rather than the right.
  11803. browser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;
  11804. // IE8- don't provide height and width for getBoundingClientRect
  11805. browser.bBounding = n[0].getBoundingClientRect().width ? true : false;
  11806. n.remove();
  11807. }
  11808. $.extend( settings.oBrowser, DataTable.__browser );
  11809. settings.oScroll.iBarWidth = DataTable.__browser.barWidth;
  11810. }
  11811. /**
  11812. * Array.prototype reduce[Right] method, used for browsers which don't support
  11813. * JS 1.6. Done this way to reduce code size, since we iterate either way
  11814. * @param {object} settings dataTables settings object
  11815. * @memberof DataTable#oApi
  11816. */
  11817. function _fnReduce ( that, fn, init, start, end, inc )
  11818. {
  11819. var
  11820. i = start,
  11821. value,
  11822. isSet = false;
  11823. if ( init !== undefined ) {
  11824. value = init;
  11825. isSet = true;
  11826. }
  11827. while ( i !== end ) {
  11828. if ( ! that.hasOwnProperty(i) ) {
  11829. continue;
  11830. }
  11831. value = isSet ?
  11832. fn( value, that[i], i, that ) :
  11833. that[i];
  11834. isSet = true;
  11835. i += inc;
  11836. }
  11837. return value;
  11838. }
  11839. /**
  11840. * Add a column to the list used for the table with default values
  11841. * @param {object} oSettings dataTables settings object
  11842. * @param {node} nTh The th element for this column
  11843. * @memberof DataTable#oApi
  11844. */
  11845. function _fnAddColumn( oSettings, nTh )
  11846. {
  11847. // Add column to aoColumns array
  11848. var oDefaults = DataTable.defaults.column;
  11849. var iCol = oSettings.aoColumns.length;
  11850. var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {
  11851. "nTh": nTh ? nTh : document.createElement('th'),
  11852. "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '',
  11853. "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
  11854. "mData": oDefaults.mData ? oDefaults.mData : iCol,
  11855. idx: iCol
  11856. } );
  11857. oSettings.aoColumns.push( oCol );
  11858. // Add search object for column specific search. Note that the `searchCols[ iCol ]`
  11859. // passed into extend can be undefined. This allows the user to give a default
  11860. // with only some of the parameters defined, and also not give a default
  11861. var searchCols = oSettings.aoPreSearchCols;
  11862. searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );
  11863. // Use the default column options function to initialise classes etc
  11864. _fnColumnOptions( oSettings, iCol, $(nTh).data() );
  11865. }
  11866. /**
  11867. * Apply options for a column
  11868. * @param {object} oSettings dataTables settings object
  11869. * @param {int} iCol column index to consider
  11870. * @param {object} oOptions object with sType, bVisible and bSearchable etc
  11871. * @memberof DataTable#oApi
  11872. */
  11873. function _fnColumnOptions( oSettings, iCol, oOptions )
  11874. {
  11875. var oCol = oSettings.aoColumns[ iCol ];
  11876. var oClasses = oSettings.oClasses;
  11877. var th = $(oCol.nTh);
  11878. // Try to get width information from the DOM. We can't get it from CSS
  11879. // as we'd need to parse the CSS stylesheet. `width` option can override
  11880. if ( ! oCol.sWidthOrig ) {
  11881. // Width attribute
  11882. oCol.sWidthOrig = th.attr('width') || null;
  11883. // Style attribute
  11884. var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/);
  11885. if ( t ) {
  11886. oCol.sWidthOrig = t[1];
  11887. }
  11888. }
  11889. /* User specified column options */
  11890. if ( oOptions !== undefined && oOptions !== null )
  11891. {
  11892. // Backwards compatibility
  11893. _fnCompatCols( oOptions );
  11894. // Map camel case parameters to their Hungarian counterparts
  11895. _fnCamelToHungarian( DataTable.defaults.column, oOptions );
  11896. /* Backwards compatibility for mDataProp */
  11897. if ( oOptions.mDataProp !== undefined && !oOptions.mData )
  11898. {
  11899. oOptions.mData = oOptions.mDataProp;
  11900. }
  11901. if ( oOptions.sType )
  11902. {
  11903. oCol._sManualType = oOptions.sType;
  11904. }
  11905. // `class` is a reserved word in Javascript, so we need to provide
  11906. // the ability to use a valid name for the camel case input
  11907. if ( oOptions.className && ! oOptions.sClass )
  11908. {
  11909. oOptions.sClass = oOptions.className;
  11910. }
  11911. $.extend( oCol, oOptions );
  11912. _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
  11913. /* iDataSort to be applied (backwards compatibility), but aDataSort will take
  11914. * priority if defined
  11915. */
  11916. if ( oOptions.iDataSort !== undefined )
  11917. {
  11918. oCol.aDataSort = [ oOptions.iDataSort ];
  11919. }
  11920. _fnMap( oCol, oOptions, "aDataSort" );
  11921. }
  11922. /* Cache the data get and set functions for speed */
  11923. var mDataSrc = oCol.mData;
  11924. var mData = _fnGetObjectDataFn( mDataSrc );
  11925. var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;
  11926. var attrTest = function( src ) {
  11927. return typeof src === 'string' && src.indexOf('@') !== -1;
  11928. };
  11929. oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (
  11930. attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)
  11931. );
  11932. oCol._setter = null;
  11933. oCol.fnGetData = function (rowData, type, meta) {
  11934. var innerData = mData( rowData, type, undefined, meta );
  11935. return mRender && type ?
  11936. mRender( innerData, type, rowData, meta ) :
  11937. innerData;
  11938. };
  11939. oCol.fnSetData = function ( rowData, val, meta ) {
  11940. return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );
  11941. };
  11942. // Indicate if DataTables should read DOM data as an object or array
  11943. // Used in _fnGetRowElements
  11944. if ( typeof mDataSrc !== 'number' ) {
  11945. oSettings._rowReadObject = true;
  11946. }
  11947. /* Feature sorting overrides column specific when off */
  11948. if ( !oSettings.oFeatures.bSort )
  11949. {
  11950. oCol.bSortable = false;
  11951. th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called
  11952. }
  11953. /* Check that the class assignment is correct for sorting */
  11954. var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
  11955. var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
  11956. if ( !oCol.bSortable || (!bAsc && !bDesc) )
  11957. {
  11958. oCol.sSortingClass = oClasses.sSortableNone;
  11959. oCol.sSortingClassJUI = "";
  11960. }
  11961. else if ( bAsc && !bDesc )
  11962. {
  11963. oCol.sSortingClass = oClasses.sSortableAsc;
  11964. oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
  11965. }
  11966. else if ( !bAsc && bDesc )
  11967. {
  11968. oCol.sSortingClass = oClasses.sSortableDesc;
  11969. oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
  11970. }
  11971. else
  11972. {
  11973. oCol.sSortingClass = oClasses.sSortable;
  11974. oCol.sSortingClassJUI = oClasses.sSortJUI;
  11975. }
  11976. }
  11977. /**
  11978. * Adjust the table column widths for new data. Note: you would probably want to
  11979. * do a redraw after calling this function!
  11980. * @param {object} settings dataTables settings object
  11981. * @memberof DataTable#oApi
  11982. */
  11983. function _fnAdjustColumnSizing ( settings )
  11984. {
  11985. /* Not interested in doing column width calculation if auto-width is disabled */
  11986. if ( settings.oFeatures.bAutoWidth !== false )
  11987. {
  11988. var columns = settings.aoColumns;
  11989. _fnCalculateColumnWidths( settings );
  11990. for ( var i=0 , iLen=columns.length ; i<iLen ; i++ )
  11991. {
  11992. columns[i].nTh.style.width = columns[i].sWidth;
  11993. }
  11994. }
  11995. var scroll = settings.oScroll;
  11996. if ( scroll.sY !== '' || scroll.sX !== '')
  11997. {
  11998. _fnScrollDraw( settings );
  11999. }
  12000. _fnCallbackFire( settings, null, 'column-sizing', [settings] );
  12001. }
  12002. /**
  12003. * Covert the index of a visible column to the index in the data array (take account
  12004. * of hidden columns)
  12005. * @param {object} oSettings dataTables settings object
  12006. * @param {int} iMatch Visible column index to lookup
  12007. * @returns {int} i the data index
  12008. * @memberof DataTable#oApi
  12009. */
  12010. function _fnVisibleToColumnIndex( oSettings, iMatch )
  12011. {
  12012. var aiVis = _fnGetColumns( oSettings, 'bVisible' );
  12013. return typeof aiVis[iMatch] === 'number' ?
  12014. aiVis[iMatch] :
  12015. null;
  12016. }
  12017. /**
  12018. * Covert the index of an index in the data array and convert it to the visible
  12019. * column index (take account of hidden columns)
  12020. * @param {int} iMatch Column index to lookup
  12021. * @param {object} oSettings dataTables settings object
  12022. * @returns {int} i the data index
  12023. * @memberof DataTable#oApi
  12024. */
  12025. function _fnColumnIndexToVisible( oSettings, iMatch )
  12026. {
  12027. var aiVis = _fnGetColumns( oSettings, 'bVisible' );
  12028. var iPos = $.inArray( iMatch, aiVis );
  12029. return iPos !== -1 ? iPos : null;
  12030. }
  12031. /**
  12032. * Get the number of visible columns
  12033. * @param {object} oSettings dataTables settings object
  12034. * @returns {int} i the number of visible columns
  12035. * @memberof DataTable#oApi
  12036. */
  12037. function _fnVisbleColumns( oSettings )
  12038. {
  12039. var vis = 0;
  12040. // No reduce in IE8, use a loop for now
  12041. $.each( oSettings.aoColumns, function ( i, col ) {
  12042. if ( col.bVisible && $(col.nTh).css('display') !== 'none' ) {
  12043. vis++;
  12044. }
  12045. } );
  12046. return vis;
  12047. }
  12048. /**
  12049. * Get an array of column indexes that match a given property
  12050. * @param {object} oSettings dataTables settings object
  12051. * @param {string} sParam Parameter in aoColumns to look for - typically
  12052. * bVisible or bSearchable
  12053. * @returns {array} Array of indexes with matched properties
  12054. * @memberof DataTable#oApi
  12055. */
  12056. function _fnGetColumns( oSettings, sParam )
  12057. {
  12058. var a = [];
  12059. $.map( oSettings.aoColumns, function(val, i) {
  12060. if ( val[sParam] ) {
  12061. a.push( i );
  12062. }
  12063. } );
  12064. return a;
  12065. }
  12066. /**
  12067. * Calculate the 'type' of a column
  12068. * @param {object} settings dataTables settings object
  12069. * @memberof DataTable#oApi
  12070. */
  12071. function _fnColumnTypes ( settings )
  12072. {
  12073. var columns = settings.aoColumns;
  12074. var data = settings.aoData;
  12075. var types = DataTable.ext.type.detect;
  12076. var i, ien, j, jen, k, ken;
  12077. var col, cell, detectedType, cache;
  12078. // For each column, spin over the
  12079. for ( i=0, ien=columns.length ; i<ien ; i++ ) {
  12080. col = columns[i];
  12081. cache = [];
  12082. if ( ! col.sType && col._sManualType ) {
  12083. col.sType = col._sManualType;
  12084. }
  12085. else if ( ! col.sType ) {
  12086. for ( j=0, jen=types.length ; j<jen ; j++ ) {
  12087. for ( k=0, ken=data.length ; k<ken ; k++ ) {
  12088. // Use a cache array so we only need to get the type data
  12089. // from the formatter once (when using multiple detectors)
  12090. if ( cache[k] === undefined ) {
  12091. cache[k] = _fnGetCellData( settings, k, i, 'type' );
  12092. }
  12093. detectedType = types[j]( cache[k], settings );
  12094. // If null, then this type can't apply to this column, so
  12095. // rather than testing all cells, break out. There is an
  12096. // exception for the last type which is `html`. We need to
  12097. // scan all rows since it is possible to mix string and HTML
  12098. // types
  12099. if ( ! detectedType && j !== types.length-1 ) {
  12100. break;
  12101. }
  12102. // Only a single match is needed for html type since it is
  12103. // bottom of the pile and very similar to string
  12104. if ( detectedType === 'html' ) {
  12105. break;
  12106. }
  12107. }
  12108. // Type is valid for all data points in the column - use this
  12109. // type
  12110. if ( detectedType ) {
  12111. col.sType = detectedType;
  12112. break;
  12113. }
  12114. }
  12115. // Fall back - if no type was detected, always use string
  12116. if ( ! col.sType ) {
  12117. col.sType = 'string';
  12118. }
  12119. }
  12120. }
  12121. }
  12122. /**
  12123. * Take the column definitions and static columns arrays and calculate how
  12124. * they relate to column indexes. The callback function will then apply the
  12125. * definition found for a column to a suitable configuration object.
  12126. * @param {object} oSettings dataTables settings object
  12127. * @param {array} aoColDefs The aoColumnDefs array that is to be applied
  12128. * @param {array} aoCols The aoColumns array that defines columns individually
  12129. * @param {function} fn Callback function - takes two parameters, the calculated
  12130. * column index and the definition for that column.
  12131. * @memberof DataTable#oApi
  12132. */
  12133. function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )
  12134. {
  12135. var i, iLen, j, jLen, k, kLen, def;
  12136. var columns = oSettings.aoColumns;
  12137. // Column definitions with aTargets
  12138. if ( aoColDefs )
  12139. {
  12140. /* Loop over the definitions array - loop in reverse so first instance has priority */
  12141. for ( i=aoColDefs.length-1 ; i>=0 ; i-- )
  12142. {
  12143. def = aoColDefs[i];
  12144. /* Each definition can target multiple columns, as it is an array */
  12145. var aTargets = def.targets !== undefined ?
  12146. def.targets :
  12147. def.aTargets;
  12148. if ( ! $.isArray( aTargets ) )
  12149. {
  12150. aTargets = [ aTargets ];
  12151. }
  12152. for ( j=0, jLen=aTargets.length ; j<jLen ; j++ )
  12153. {
  12154. if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )
  12155. {
  12156. /* Add columns that we don't yet know about */
  12157. while( columns.length <= aTargets[j] )
  12158. {
  12159. _fnAddColumn( oSettings );
  12160. }
  12161. /* Integer, basic index */
  12162. fn( aTargets[j], def );
  12163. }
  12164. else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
  12165. {
  12166. /* Negative integer, right to left column counting */
  12167. fn( columns.length+aTargets[j], def );
  12168. }
  12169. else if ( typeof aTargets[j] === 'string' )
  12170. {
  12171. /* Class name matching on TH element */
  12172. for ( k=0, kLen=columns.length ; k<kLen ; k++ )
  12173. {
  12174. if ( aTargets[j] == "_all" ||
  12175. $(columns[k].nTh).hasClass( aTargets[j] ) )
  12176. {
  12177. fn( k, def );
  12178. }
  12179. }
  12180. }
  12181. }
  12182. }
  12183. }
  12184. // Statically defined columns array
  12185. if ( aoCols )
  12186. {
  12187. for ( i=0, iLen=aoCols.length ; i<iLen ; i++ )
  12188. {
  12189. fn( i, aoCols[i] );
  12190. }
  12191. }
  12192. }
  12193. /**
  12194. * Add a data array to the table, creating DOM node etc. This is the parallel to
  12195. * _fnGatherData, but for adding rows from a Javascript source, rather than a
  12196. * DOM source.
  12197. * @param {object} oSettings dataTables settings object
  12198. * @param {array} aData data array to be added
  12199. * @param {node} [nTr] TR element to add to the table - optional. If not given,
  12200. * DataTables will create a row automatically
  12201. * @param {array} [anTds] Array of TD|TH elements for the row - must be given
  12202. * if nTr is.
  12203. * @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
  12204. * @memberof DataTable#oApi
  12205. */
  12206. function _fnAddData ( oSettings, aDataIn, nTr, anTds )
  12207. {
  12208. /* Create the object for storing information about this new row */
  12209. var iRow = oSettings.aoData.length;
  12210. var oData = $.extend( true, {}, DataTable.models.oRow, {
  12211. src: nTr ? 'dom' : 'data',
  12212. idx: iRow
  12213. } );
  12214. oData._aData = aDataIn;
  12215. oSettings.aoData.push( oData );
  12216. /* Create the cells */
  12217. var nTd, sThisType;
  12218. var columns = oSettings.aoColumns;
  12219. // Invalidate the column types as the new data needs to be revalidated
  12220. for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
  12221. {
  12222. columns[i].sType = null;
  12223. }
  12224. /* Add to the display array */
  12225. oSettings.aiDisplayMaster.push( iRow );
  12226. var id = oSettings.rowIdFn( aDataIn );
  12227. if ( id !== undefined ) {
  12228. oSettings.aIds[ id ] = oData;
  12229. }
  12230. /* Create the DOM information, or register it if already present */
  12231. if ( nTr || ! oSettings.oFeatures.bDeferRender )
  12232. {
  12233. _fnCreateTr( oSettings, iRow, nTr, anTds );
  12234. }
  12235. return iRow;
  12236. }
  12237. /**
  12238. * Add one or more TR elements to the table. Generally we'd expect to
  12239. * use this for reading data from a DOM sourced table, but it could be
  12240. * used for an TR element. Note that if a TR is given, it is used (i.e.
  12241. * it is not cloned).
  12242. * @param {object} settings dataTables settings object
  12243. * @param {array|node|jQuery} trs The TR element(s) to add to the table
  12244. * @returns {array} Array of indexes for the added rows
  12245. * @memberof DataTable#oApi
  12246. */
  12247. function _fnAddTr( settings, trs )
  12248. {
  12249. var row;
  12250. // Allow an individual node to be passed in
  12251. if ( ! (trs instanceof $) ) {
  12252. trs = $(trs);
  12253. }
  12254. return trs.map( function (i, el) {
  12255. row = _fnGetRowElements( settings, el );
  12256. return _fnAddData( settings, row.data, el, row.cells );
  12257. } );
  12258. }
  12259. /**
  12260. * Take a TR element and convert it to an index in aoData
  12261. * @param {object} oSettings dataTables settings object
  12262. * @param {node} n the TR element to find
  12263. * @returns {int} index if the node is found, null if not
  12264. * @memberof DataTable#oApi
  12265. */
  12266. function _fnNodeToDataIndex( oSettings, n )
  12267. {
  12268. return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;
  12269. }
  12270. /**
  12271. * Take a TD element and convert it into a column data index (not the visible index)
  12272. * @param {object} oSettings dataTables settings object
  12273. * @param {int} iRow The row number the TD/TH can be found in
  12274. * @param {node} n The TD/TH element to find
  12275. * @returns {int} index if the node is found, -1 if not
  12276. * @memberof DataTable#oApi
  12277. */
  12278. function _fnNodeToColumnIndex( oSettings, iRow, n )
  12279. {
  12280. return $.inArray( n, oSettings.aoData[ iRow ].anCells );
  12281. }
  12282. /**
  12283. * Get the data for a given cell from the internal cache, taking into account data mapping
  12284. * @param {object} settings dataTables settings object
  12285. * @param {int} rowIdx aoData row id
  12286. * @param {int} colIdx Column index
  12287. * @param {string} type data get type ('display', 'type' 'filter' 'sort')
  12288. * @returns {*} Cell data
  12289. * @memberof DataTable#oApi
  12290. */
  12291. function _fnGetCellData( settings, rowIdx, colIdx, type )
  12292. {
  12293. var draw = settings.iDraw;
  12294. var col = settings.aoColumns[colIdx];
  12295. var rowData = settings.aoData[rowIdx]._aData;
  12296. var defaultContent = col.sDefaultContent;
  12297. var cellData = col.fnGetData( rowData, type, {
  12298. settings: settings,
  12299. row: rowIdx,
  12300. col: colIdx
  12301. } );
  12302. if ( cellData === undefined ) {
  12303. if ( settings.iDrawError != draw && defaultContent === null ) {
  12304. _fnLog( settings, 0, "Requested unknown parameter "+
  12305. (typeof col.mData=='function' ? '{function}' : "'"+col.mData+"'")+
  12306. " for row "+rowIdx+", column "+colIdx, 4 );
  12307. settings.iDrawError = draw;
  12308. }
  12309. return defaultContent;
  12310. }
  12311. // When the data source is null and a specific data type is requested (i.e.
  12312. // not the original data), we can use default column data
  12313. if ( (cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined ) {
  12314. cellData = defaultContent;
  12315. }
  12316. else if ( typeof cellData === 'function' ) {
  12317. // If the data source is a function, then we run it and use the return,
  12318. // executing in the scope of the data object (for instances)
  12319. return cellData.call( rowData );
  12320. }
  12321. if ( cellData === null && type == 'display' ) {
  12322. return '';
  12323. }
  12324. return cellData;
  12325. }
  12326. /**
  12327. * Set the value for a specific cell, into the internal data cache
  12328. * @param {object} settings dataTables settings object
  12329. * @param {int} rowIdx aoData row id
  12330. * @param {int} colIdx Column index
  12331. * @param {*} val Value to set
  12332. * @memberof DataTable#oApi
  12333. */
  12334. function _fnSetCellData( settings, rowIdx, colIdx, val )
  12335. {
  12336. var col = settings.aoColumns[colIdx];
  12337. var rowData = settings.aoData[rowIdx]._aData;
  12338. col.fnSetData( rowData, val, {
  12339. settings: settings,
  12340. row: rowIdx,
  12341. col: colIdx
  12342. } );
  12343. }
  12344. // Private variable that is used to match action syntax in the data property object
  12345. var __reArray = /\[.*?\]$/;
  12346. var __reFn = /\(\)$/;
  12347. /**
  12348. * Split string on periods, taking into account escaped periods
  12349. * @param {string} str String to split
  12350. * @return {array} Split string
  12351. */
  12352. function _fnSplitObjNotation( str )
  12353. {
  12354. return $.map( str.match(/(\\.|[^\.])+/g) || [''], function ( s ) {
  12355. return s.replace(/\\\./g, '.');
  12356. } );
  12357. }
  12358. /**
  12359. * Return a function that can be used to get data from a source object, taking
  12360. * into account the ability to use nested objects as a source
  12361. * @param {string|int|function} mSource The data source for the object
  12362. * @returns {function} Data get function
  12363. * @memberof DataTable#oApi
  12364. */
  12365. function _fnGetObjectDataFn( mSource )
  12366. {
  12367. if ( $.isPlainObject( mSource ) )
  12368. {
  12369. /* Build an object of get functions, and wrap them in a single call */
  12370. var o = {};
  12371. $.each( mSource, function (key, val) {
  12372. if ( val ) {
  12373. o[key] = _fnGetObjectDataFn( val );
  12374. }
  12375. } );
  12376. return function (data, type, row, meta) {
  12377. var t = o[type] || o._;
  12378. return t !== undefined ?
  12379. t(data, type, row, meta) :
  12380. data;
  12381. };
  12382. }
  12383. else if ( mSource === null )
  12384. {
  12385. /* Give an empty string for rendering / sorting etc */
  12386. return function (data) { // type, row and meta also passed, but not used
  12387. return data;
  12388. };
  12389. }
  12390. else if ( typeof mSource === 'function' )
  12391. {
  12392. return function (data, type, row, meta) {
  12393. return mSource( data, type, row, meta );
  12394. };
  12395. }
  12396. else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
  12397. mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
  12398. {
  12399. /* If there is a . in the source string then the data source is in a
  12400. * nested object so we loop over the data for each level to get the next
  12401. * level down. On each loop we test for undefined, and if found immediately
  12402. * return. This allows entire objects to be missing and sDefaultContent to
  12403. * be used if defined, rather than throwing an error
  12404. */
  12405. var fetchData = function (data, type, src) {
  12406. var arrayNotation, funcNotation, out, innerSrc;
  12407. if ( src !== "" )
  12408. {
  12409. var a = _fnSplitObjNotation( src );
  12410. for ( var i=0, iLen=a.length ; i<iLen ; i++ )
  12411. {
  12412. // Check if we are dealing with special notation
  12413. arrayNotation = a[i].match(__reArray);
  12414. funcNotation = a[i].match(__reFn);
  12415. if ( arrayNotation )
  12416. {
  12417. // Array notation
  12418. a[i] = a[i].replace(__reArray, '');
  12419. // Condition allows simply [] to be passed in
  12420. if ( a[i] !== "" ) {
  12421. data = data[ a[i] ];
  12422. }
  12423. out = [];
  12424. // Get the remainder of the nested object to get
  12425. a.splice( 0, i+1 );
  12426. innerSrc = a.join('.');
  12427. // Traverse each entry in the array getting the properties requested
  12428. if ( $.isArray( data ) ) {
  12429. for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
  12430. out.push( fetchData( data[j], type, innerSrc ) );
  12431. }
  12432. }
  12433. // If a string is given in between the array notation indicators, that
  12434. // is used to join the strings together, otherwise an array is returned
  12435. var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
  12436. data = (join==="") ? out : out.join(join);
  12437. // The inner call to fetchData has already traversed through the remainder
  12438. // of the source requested, so we exit from the loop
  12439. break;
  12440. }
  12441. else if ( funcNotation )
  12442. {
  12443. // Function call
  12444. a[i] = a[i].replace(__reFn, '');
  12445. data = data[ a[i] ]();
  12446. continue;
  12447. }
  12448. if ( data === null || data[ a[i] ] === undefined )
  12449. {
  12450. return undefined;
  12451. }
  12452. data = data[ a[i] ];
  12453. }
  12454. }
  12455. return data;
  12456. };
  12457. return function (data, type) { // row and meta also passed, but not used
  12458. return fetchData( data, type, mSource );
  12459. };
  12460. }
  12461. else
  12462. {
  12463. /* Array or flat object mapping */
  12464. return function (data, type) { // row and meta also passed, but not used
  12465. return data[mSource];
  12466. };
  12467. }
  12468. }
  12469. /**
  12470. * Return a function that can be used to set data from a source object, taking
  12471. * into account the ability to use nested objects as a source
  12472. * @param {string|int|function} mSource The data source for the object
  12473. * @returns {function} Data set function
  12474. * @memberof DataTable#oApi
  12475. */
  12476. function _fnSetObjectDataFn( mSource )
  12477. {
  12478. if ( $.isPlainObject( mSource ) )
  12479. {
  12480. /* Unlike get, only the underscore (global) option is used for for
  12481. * setting data since we don't know the type here. This is why an object
  12482. * option is not documented for `mData` (which is read/write), but it is
  12483. * for `mRender` which is read only.
  12484. */
  12485. return _fnSetObjectDataFn( mSource._ );
  12486. }
  12487. else if ( mSource === null )
  12488. {
  12489. /* Nothing to do when the data source is null */
  12490. return function () {};
  12491. }
  12492. else if ( typeof mSource === 'function' )
  12493. {
  12494. return function (data, val, meta) {
  12495. mSource( data, 'set', val, meta );
  12496. };
  12497. }
  12498. else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
  12499. mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
  12500. {
  12501. /* Like the get, we need to get data from a nested object */
  12502. var setData = function (data, val, src) {
  12503. var a = _fnSplitObjNotation( src ), b;
  12504. var aLast = a[a.length-1];
  12505. var arrayNotation, funcNotation, o, innerSrc;
  12506. for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
  12507. {
  12508. // Check if we are dealing with an array notation request
  12509. arrayNotation = a[i].match(__reArray);
  12510. funcNotation = a[i].match(__reFn);
  12511. if ( arrayNotation )
  12512. {
  12513. a[i] = a[i].replace(__reArray, '');
  12514. data[ a[i] ] = [];
  12515. // Get the remainder of the nested object to set so we can recurse
  12516. b = a.slice();
  12517. b.splice( 0, i+1 );
  12518. innerSrc = b.join('.');
  12519. // Traverse each entry in the array setting the properties requested
  12520. if ( $.isArray( val ) )
  12521. {
  12522. for ( var j=0, jLen=val.length ; j<jLen ; j++ )
  12523. {
  12524. o = {};
  12525. setData( o, val[j], innerSrc );
  12526. data[ a[i] ].push( o );
  12527. }
  12528. }
  12529. else
  12530. {
  12531. // We've been asked to save data to an array, but it
  12532. // isn't array data to be saved. Best that can be done
  12533. // is to just save the value.
  12534. data[ a[i] ] = val;
  12535. }
  12536. // The inner call to setData has already traversed through the remainder
  12537. // of the source and has set the data, thus we can exit here
  12538. return;
  12539. }
  12540. else if ( funcNotation )
  12541. {
  12542. // Function call
  12543. a[i] = a[i].replace(__reFn, '');
  12544. data = data[ a[i] ]( val );
  12545. }
  12546. // If the nested object doesn't currently exist - since we are
  12547. // trying to set the value - create it
  12548. if ( data[ a[i] ] === null || data[ a[i] ] === undefined )
  12549. {
  12550. data[ a[i] ] = {};
  12551. }
  12552. data = data[ a[i] ];
  12553. }
  12554. // Last item in the input - i.e, the actual set
  12555. if ( aLast.match(__reFn ) )
  12556. {
  12557. // Function call
  12558. data = data[ aLast.replace(__reFn, '') ]( val );
  12559. }
  12560. else
  12561. {
  12562. // If array notation is used, we just want to strip it and use the property name
  12563. // and assign the value. If it isn't used, then we get the result we want anyway
  12564. data[ aLast.replace(__reArray, '') ] = val;
  12565. }
  12566. };
  12567. return function (data, val) { // meta is also passed in, but not used
  12568. return setData( data, val, mSource );
  12569. };
  12570. }
  12571. else
  12572. {
  12573. /* Array or flat object mapping */
  12574. return function (data, val) { // meta is also passed in, but not used
  12575. data[mSource] = val;
  12576. };
  12577. }
  12578. }
  12579. /**
  12580. * Return an array with the full table data
  12581. * @param {object} oSettings dataTables settings object
  12582. * @returns array {array} aData Master data array
  12583. * @memberof DataTable#oApi
  12584. */
  12585. function _fnGetDataMaster ( settings )
  12586. {
  12587. return _pluck( settings.aoData, '_aData' );
  12588. }
  12589. /**
  12590. * Nuke the table
  12591. * @param {object} oSettings dataTables settings object
  12592. * @memberof DataTable#oApi
  12593. */
  12594. function _fnClearTable( settings )
  12595. {
  12596. settings.aoData.length = 0;
  12597. settings.aiDisplayMaster.length = 0;
  12598. settings.aiDisplay.length = 0;
  12599. settings.aIds = {};
  12600. }
  12601. /**
  12602. * Take an array of integers (index array) and remove a target integer (value - not
  12603. * the key!)
  12604. * @param {array} a Index array to target
  12605. * @param {int} iTarget value to find
  12606. * @memberof DataTable#oApi
  12607. */
  12608. function _fnDeleteIndex( a, iTarget, splice )
  12609. {
  12610. var iTargetIndex = -1;
  12611. for ( var i=0, iLen=a.length ; i<iLen ; i++ )
  12612. {
  12613. if ( a[i] == iTarget )
  12614. {
  12615. iTargetIndex = i;
  12616. }
  12617. else if ( a[i] > iTarget )
  12618. {
  12619. a[i]--;
  12620. }
  12621. }
  12622. if ( iTargetIndex != -1 && splice === undefined )
  12623. {
  12624. a.splice( iTargetIndex, 1 );
  12625. }
  12626. }
  12627. /**
  12628. * Mark cached data as invalid such that a re-read of the data will occur when
  12629. * the cached data is next requested. Also update from the data source object.
  12630. *
  12631. * @param {object} settings DataTables settings object
  12632. * @param {int} rowIdx Row index to invalidate
  12633. * @param {string} [src] Source to invalidate from: undefined, 'auto', 'dom'
  12634. * or 'data'
  12635. * @param {int} [colIdx] Column index to invalidate. If undefined the whole
  12636. * row will be invalidated
  12637. * @memberof DataTable#oApi
  12638. *
  12639. * @todo For the modularisation of v1.11 this will need to become a callback, so
  12640. * the sort and filter methods can subscribe to it. That will required
  12641. * initialisation options for sorting, which is why it is not already baked in
  12642. */
  12643. function _fnInvalidate( settings, rowIdx, src, colIdx )
  12644. {
  12645. var row = settings.aoData[ rowIdx ];
  12646. var i, ien;
  12647. var cellWrite = function ( cell, col ) {
  12648. // This is very frustrating, but in IE if you just write directly
  12649. // to innerHTML, and elements that are overwritten are GC'ed,
  12650. // even if there is a reference to them elsewhere
  12651. while ( cell.childNodes.length ) {
  12652. cell.removeChild( cell.firstChild );
  12653. }
  12654. cell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );
  12655. };
  12656. // Are we reading last data from DOM or the data object?
  12657. if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {
  12658. // Read the data from the DOM
  12659. row._aData = _fnGetRowElements(
  12660. settings, row, colIdx, colIdx === undefined ? undefined : row._aData
  12661. )
  12662. .data;
  12663. }
  12664. else {
  12665. // Reading from data object, update the DOM
  12666. var cells = row.anCells;
  12667. if ( cells ) {
  12668. if ( colIdx !== undefined ) {
  12669. cellWrite( cells[colIdx], colIdx );
  12670. }
  12671. else {
  12672. for ( i=0, ien=cells.length ; i<ien ; i++ ) {
  12673. cellWrite( cells[i], i );
  12674. }
  12675. }
  12676. }
  12677. }
  12678. // For both row and cell invalidation, the cached data for sorting and
  12679. // filtering is nulled out
  12680. row._aSortData = null;
  12681. row._aFilterData = null;
  12682. // Invalidate the type for a specific column (if given) or all columns since
  12683. // the data might have changed
  12684. var cols = settings.aoColumns;
  12685. if ( colIdx !== undefined ) {
  12686. cols[ colIdx ].sType = null;
  12687. }
  12688. else {
  12689. for ( i=0, ien=cols.length ; i<ien ; i++ ) {
  12690. cols[i].sType = null;
  12691. }
  12692. // Update DataTables special `DT_*` attributes for the row
  12693. _fnRowAttributes( settings, row );
  12694. }
  12695. }
  12696. /**
  12697. * Build a data source object from an HTML row, reading the contents of the
  12698. * cells that are in the row.
  12699. *
  12700. * @param {object} settings DataTables settings object
  12701. * @param {node|object} TR element from which to read data or existing row
  12702. * object from which to re-read the data from the cells
  12703. * @param {int} [colIdx] Optional column index
  12704. * @param {array|object} [d] Data source object. If `colIdx` is given then this
  12705. * parameter should also be given and will be used to write the data into.
  12706. * Only the column in question will be written
  12707. * @returns {object} Object with two parameters: `data` the data read, in
  12708. * document order, and `cells` and array of nodes (they can be useful to the
  12709. * caller, so rather than needing a second traversal to get them, just return
  12710. * them from here).
  12711. * @memberof DataTable#oApi
  12712. */
  12713. function _fnGetRowElements( settings, row, colIdx, d )
  12714. {
  12715. var
  12716. tds = [],
  12717. td = row.firstChild,
  12718. name, col, o, i=0, contents,
  12719. columns = settings.aoColumns,
  12720. objectRead = settings._rowReadObject;
  12721. // Allow the data object to be passed in, or construct
  12722. d = d !== undefined ?
  12723. d :
  12724. objectRead ?
  12725. {} :
  12726. [];
  12727. var attr = function ( str, td ) {
  12728. if ( typeof str === 'string' ) {
  12729. var idx = str.indexOf('@');
  12730. if ( idx !== -1 ) {
  12731. var attr = str.substring( idx+1 );
  12732. var setter = _fnSetObjectDataFn( str );
  12733. setter( d, td.getAttribute( attr ) );
  12734. }
  12735. }
  12736. };
  12737. // Read data from a cell and store into the data object
  12738. var cellProcess = function ( cell ) {
  12739. if ( colIdx === undefined || colIdx === i ) {
  12740. col = columns[i];
  12741. contents = $.trim(cell.innerHTML);
  12742. if ( col && col._bAttrSrc ) {
  12743. var setter = _fnSetObjectDataFn( col.mData._ );
  12744. setter( d, contents );
  12745. attr( col.mData.sort, cell );
  12746. attr( col.mData.type, cell );
  12747. attr( col.mData.filter, cell );
  12748. }
  12749. else {
  12750. // Depending on the `data` option for the columns the data can
  12751. // be read to either an object or an array.
  12752. if ( objectRead ) {
  12753. if ( ! col._setter ) {
  12754. // Cache the setter function
  12755. col._setter = _fnSetObjectDataFn( col.mData );
  12756. }
  12757. col._setter( d, contents );
  12758. }
  12759. else {
  12760. d[i] = contents;
  12761. }
  12762. }
  12763. }
  12764. i++;
  12765. };
  12766. if ( td ) {
  12767. // `tr` element was passed in
  12768. while ( td ) {
  12769. name = td.nodeName.toUpperCase();
  12770. if ( name == "TD" || name == "TH" ) {
  12771. cellProcess( td );
  12772. tds.push( td );
  12773. }
  12774. td = td.nextSibling;
  12775. }
  12776. }
  12777. else {
  12778. // Existing row object passed in
  12779. tds = row.anCells;
  12780. for ( var j=0, jen=tds.length ; j<jen ; j++ ) {
  12781. cellProcess( tds[j] );
  12782. }
  12783. }
  12784. // Read the ID from the DOM if present
  12785. var rowNode = row.firstChild ? row : row.nTr;
  12786. if ( rowNode ) {
  12787. var id = rowNode.getAttribute( 'id' );
  12788. if ( id ) {
  12789. _fnSetObjectDataFn( settings.rowId )( d, id );
  12790. }
  12791. }
  12792. return {
  12793. data: d,
  12794. cells: tds
  12795. };
  12796. }
  12797. /**
  12798. * Create a new TR element (and it's TD children) for a row
  12799. * @param {object} oSettings dataTables settings object
  12800. * @param {int} iRow Row to consider
  12801. * @param {node} [nTrIn] TR element to add to the table - optional. If not given,
  12802. * DataTables will create a row automatically
  12803. * @param {array} [anTds] Array of TD|TH elements for the row - must be given
  12804. * if nTr is.
  12805. * @memberof DataTable#oApi
  12806. */
  12807. function _fnCreateTr ( oSettings, iRow, nTrIn, anTds )
  12808. {
  12809. var
  12810. row = oSettings.aoData[iRow],
  12811. rowData = row._aData,
  12812. cells = [],
  12813. nTr, nTd, oCol,
  12814. i, iLen;
  12815. if ( row.nTr === null )
  12816. {
  12817. nTr = nTrIn || document.createElement('tr');
  12818. row.nTr = nTr;
  12819. row.anCells = cells;
  12820. /* Use a private property on the node to allow reserve mapping from the node
  12821. * to the aoData array for fast look up
  12822. */
  12823. nTr._DT_RowIndex = iRow;
  12824. /* Special parameters can be given by the data source to be used on the row */
  12825. _fnRowAttributes( oSettings, row );
  12826. /* Process each column */
  12827. for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
  12828. {
  12829. oCol = oSettings.aoColumns[i];
  12830. nTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );
  12831. nTd._DT_CellIndex = {
  12832. row: iRow,
  12833. column: i
  12834. };
  12835. cells.push( nTd );
  12836. // Need to create the HTML if new, or if a rendering function is defined
  12837. if ( (!nTrIn || oCol.mRender || oCol.mData !== i) &&
  12838. (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i+'.display')
  12839. ) {
  12840. nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );
  12841. }
  12842. /* Add user defined class */
  12843. if ( oCol.sClass )
  12844. {
  12845. nTd.className += ' '+oCol.sClass;
  12846. }
  12847. // Visibility - add or remove as required
  12848. if ( oCol.bVisible && ! nTrIn )
  12849. {
  12850. nTr.appendChild( nTd );
  12851. }
  12852. else if ( ! oCol.bVisible && nTrIn )
  12853. {
  12854. nTd.parentNode.removeChild( nTd );
  12855. }
  12856. if ( oCol.fnCreatedCell )
  12857. {
  12858. oCol.fnCreatedCell.call( oSettings.oInstance,
  12859. nTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i
  12860. );
  12861. }
  12862. }
  12863. _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );
  12864. }
  12865. // Remove once webkit bug 131819 and Chromium bug 365619 have been resolved
  12866. // and deployed
  12867. row.nTr.setAttribute( 'role', 'row' );
  12868. }
  12869. /**
  12870. * Add attributes to a row based on the special `DT_*` parameters in a data
  12871. * source object.
  12872. * @param {object} settings DataTables settings object
  12873. * @param {object} DataTables row object for the row to be modified
  12874. * @memberof DataTable#oApi
  12875. */
  12876. function _fnRowAttributes( settings, row )
  12877. {
  12878. var tr = row.nTr;
  12879. var data = row._aData;
  12880. if ( tr ) {
  12881. var id = settings.rowIdFn( data );
  12882. if ( id ) {
  12883. tr.id = id;
  12884. }
  12885. if ( data.DT_RowClass ) {
  12886. // Remove any classes added by DT_RowClass before
  12887. var a = data.DT_RowClass.split(' ');
  12888. row.__rowc = row.__rowc ?
  12889. _unique( row.__rowc.concat( a ) ) :
  12890. a;
  12891. $(tr)
  12892. .removeClass( row.__rowc.join(' ') )
  12893. .addClass( data.DT_RowClass );
  12894. }
  12895. if ( data.DT_RowAttr ) {
  12896. $(tr).attr( data.DT_RowAttr );
  12897. }
  12898. if ( data.DT_RowData ) {
  12899. $(tr).data( data.DT_RowData );
  12900. }
  12901. }
  12902. }
  12903. /**
  12904. * Create the HTML header for the table
  12905. * @param {object} oSettings dataTables settings object
  12906. * @memberof DataTable#oApi
  12907. */
  12908. function _fnBuildHead( oSettings )
  12909. {
  12910. var i, ien, cell, row, column;
  12911. var thead = oSettings.nTHead;
  12912. var tfoot = oSettings.nTFoot;
  12913. var createHeader = $('th, td', thead).length === 0;
  12914. var classes = oSettings.oClasses;
  12915. var columns = oSettings.aoColumns;
  12916. if ( createHeader ) {
  12917. row = $('<tr/>').appendTo( thead );
  12918. }
  12919. for ( i=0, ien=columns.length ; i<ien ; i++ ) {
  12920. column = columns[i];
  12921. cell = $( column.nTh ).addClass( column.sClass );
  12922. if ( createHeader ) {
  12923. cell.appendTo( row );
  12924. }
  12925. // 1.11 move into sorting
  12926. if ( oSettings.oFeatures.bSort ) {
  12927. cell.addClass( column.sSortingClass );
  12928. if ( column.bSortable !== false ) {
  12929. cell
  12930. .attr( 'tabindex', oSettings.iTabIndex )
  12931. .attr( 'aria-controls', oSettings.sTableId );
  12932. _fnSortAttachListener( oSettings, column.nTh, i );
  12933. }
  12934. }
  12935. if ( column.sTitle != cell[0].innerHTML ) {
  12936. cell.html( column.sTitle );
  12937. }
  12938. _fnRenderer( oSettings, 'header' )(
  12939. oSettings, cell, column, classes
  12940. );
  12941. }
  12942. if ( createHeader ) {
  12943. _fnDetectHeader( oSettings.aoHeader, thead );
  12944. }
  12945. /* ARIA role for the rows */
  12946. $(thead).find('>tr').attr('role', 'row');
  12947. /* Deal with the footer - add classes if required */
  12948. $(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );
  12949. $(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );
  12950. // Cache the footer cells. Note that we only take the cells from the first
  12951. // row in the footer. If there is more than one row the user wants to
  12952. // interact with, they need to use the table().foot() method. Note also this
  12953. // allows cells to be used for multiple columns using colspan
  12954. if ( tfoot !== null ) {
  12955. var cells = oSettings.aoFooter[0];
  12956. for ( i=0, ien=cells.length ; i<ien ; i++ ) {
  12957. column = columns[i];
  12958. column.nTf = cells[i].cell;
  12959. if ( column.sClass ) {
  12960. $(column.nTf).addClass( column.sClass );
  12961. }
  12962. }
  12963. }
  12964. }
  12965. /**
  12966. * Draw the header (or footer) element based on the column visibility states. The
  12967. * methodology here is to use the layout array from _fnDetectHeader, modified for
  12968. * the instantaneous column visibility, to construct the new layout. The grid is
  12969. * traversed over cell at a time in a rows x columns grid fashion, although each
  12970. * cell insert can cover multiple elements in the grid - which is tracks using the
  12971. * aApplied array. Cell inserts in the grid will only occur where there isn't
  12972. * already a cell in that position.
  12973. * @param {object} oSettings dataTables settings object
  12974. * @param array {objects} aoSource Layout array from _fnDetectHeader
  12975. * @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
  12976. * @memberof DataTable#oApi
  12977. */
  12978. function _fnDrawHead( oSettings, aoSource, bIncludeHidden )
  12979. {
  12980. var i, iLen, j, jLen, k, kLen, n, nLocalTr;
  12981. var aoLocal = [];
  12982. var aApplied = [];
  12983. var iColumns = oSettings.aoColumns.length;
  12984. var iRowspan, iColspan;
  12985. if ( ! aoSource )
  12986. {
  12987. return;
  12988. }
  12989. if ( bIncludeHidden === undefined )
  12990. {
  12991. bIncludeHidden = false;
  12992. }
  12993. /* Make a copy of the master layout array, but without the visible columns in it */
  12994. for ( i=0, iLen=aoSource.length ; i<iLen ; i++ )
  12995. {
  12996. aoLocal[i] = aoSource[i].slice();
  12997. aoLocal[i].nTr = aoSource[i].nTr;
  12998. /* Remove any columns which are currently hidden */
  12999. for ( j=iColumns-1 ; j>=0 ; j-- )
  13000. {
  13001. if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )
  13002. {
  13003. aoLocal[i].splice( j, 1 );
  13004. }
  13005. }
  13006. /* Prep the applied array - it needs an element for each row */
  13007. aApplied.push( [] );
  13008. }
  13009. for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )
  13010. {
  13011. nLocalTr = aoLocal[i].nTr;
  13012. /* All cells are going to be replaced, so empty out the row */
  13013. if ( nLocalTr )
  13014. {
  13015. while( (n = nLocalTr.firstChild) )
  13016. {
  13017. nLocalTr.removeChild( n );
  13018. }
  13019. }
  13020. for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )
  13021. {
  13022. iRowspan = 1;
  13023. iColspan = 1;
  13024. /* Check to see if there is already a cell (row/colspan) covering our target
  13025. * insert point. If there is, then there is nothing to do.
  13026. */
  13027. if ( aApplied[i][j] === undefined )
  13028. {
  13029. nLocalTr.appendChild( aoLocal[i][j].cell );
  13030. aApplied[i][j] = 1;
  13031. /* Expand the cell to cover as many rows as needed */
  13032. while ( aoLocal[i+iRowspan] !== undefined &&
  13033. aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )
  13034. {
  13035. aApplied[i+iRowspan][j] = 1;
  13036. iRowspan++;
  13037. }
  13038. /* Expand the cell to cover as many columns as needed */
  13039. while ( aoLocal[i][j+iColspan] !== undefined &&
  13040. aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )
  13041. {
  13042. /* Must update the applied array over the rows for the columns */
  13043. for ( k=0 ; k<iRowspan ; k++ )
  13044. {
  13045. aApplied[i+k][j+iColspan] = 1;
  13046. }
  13047. iColspan++;
  13048. }
  13049. /* Do the actual expansion in the DOM */
  13050. $(aoLocal[i][j].cell)
  13051. .attr('rowspan', iRowspan)
  13052. .attr('colspan', iColspan);
  13053. }
  13054. }
  13055. }
  13056. }
  13057. /**
  13058. * Insert the required TR nodes into the table for display
  13059. * @param {object} oSettings dataTables settings object
  13060. * @memberof DataTable#oApi
  13061. */
  13062. function _fnDraw( oSettings )
  13063. {
  13064. /* Provide a pre-callback function which can be used to cancel the draw is false is returned */
  13065. var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );
  13066. if ( $.inArray( false, aPreDraw ) !== -1 )
  13067. {
  13068. _fnProcessingDisplay( oSettings, false );
  13069. return;
  13070. }
  13071. var i, iLen, n;
  13072. var anRows = [];
  13073. var iRowCount = 0;
  13074. var asStripeClasses = oSettings.asStripeClasses;
  13075. var iStripes = asStripeClasses.length;
  13076. var iOpenRows = oSettings.aoOpenRows.length;
  13077. var oLang = oSettings.oLanguage;
  13078. var iInitDisplayStart = oSettings.iInitDisplayStart;
  13079. var bServerSide = _fnDataSource( oSettings ) == 'ssp';
  13080. var aiDisplay = oSettings.aiDisplay;
  13081. oSettings.bDrawing = true;
  13082. /* Check and see if we have an initial draw position from state saving */
  13083. if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )
  13084. {
  13085. oSettings._iDisplayStart = bServerSide ?
  13086. iInitDisplayStart :
  13087. iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
  13088. 0 :
  13089. iInitDisplayStart;
  13090. oSettings.iInitDisplayStart = -1;
  13091. }
  13092. var iDisplayStart = oSettings._iDisplayStart;
  13093. var iDisplayEnd = oSettings.fnDisplayEnd();
  13094. /* Server-side processing draw intercept */
  13095. if ( oSettings.bDeferLoading )
  13096. {
  13097. oSettings.bDeferLoading = false;
  13098. oSettings.iDraw++;
  13099. _fnProcessingDisplay( oSettings, false );
  13100. }
  13101. else if ( !bServerSide )
  13102. {
  13103. oSettings.iDraw++;
  13104. }
  13105. else if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )
  13106. {
  13107. return;
  13108. }
  13109. if ( aiDisplay.length !== 0 )
  13110. {
  13111. var iStart = bServerSide ? 0 : iDisplayStart;
  13112. var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
  13113. for ( var j=iStart ; j<iEnd ; j++ )
  13114. {
  13115. var iDataIndex = aiDisplay[j];
  13116. var aoData = oSettings.aoData[ iDataIndex ];
  13117. if ( aoData.nTr === null )
  13118. {
  13119. _fnCreateTr( oSettings, iDataIndex );
  13120. }
  13121. var nRow = aoData.nTr;
  13122. /* Remove the old striping classes and then add the new one */
  13123. if ( iStripes !== 0 )
  13124. {
  13125. var sStripe = asStripeClasses[ iRowCount % iStripes ];
  13126. if ( aoData._sRowStripe != sStripe )
  13127. {
  13128. $(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );
  13129. aoData._sRowStripe = sStripe;
  13130. }
  13131. }
  13132. // Row callback functions - might want to manipulate the row
  13133. // iRowCount and j are not currently documented. Are they at all
  13134. // useful?
  13135. _fnCallbackFire( oSettings, 'aoRowCallback', null,
  13136. [nRow, aoData._aData, iRowCount, j] );
  13137. anRows.push( nRow );
  13138. iRowCount++;
  13139. }
  13140. }
  13141. else
  13142. {
  13143. /* Table is empty - create a row with an empty message in it */
  13144. var sZero = oLang.sZeroRecords;
  13145. if ( oSettings.iDraw == 1 && _fnDataSource( oSettings ) == 'ajax' )
  13146. {
  13147. sZero = oLang.sLoadingRecords;
  13148. }
  13149. else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
  13150. {
  13151. sZero = oLang.sEmptyTable;
  13152. }
  13153. anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )
  13154. .append( $('<td />', {
  13155. 'valign': 'top',
  13156. 'colSpan': _fnVisbleColumns( oSettings ),
  13157. 'class': oSettings.oClasses.sRowEmpty
  13158. } ).html( sZero ) )[0];
  13159. }
  13160. /* Header and footer callbacks */
  13161. _fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],
  13162. _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
  13163. _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
  13164. _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
  13165. var body = $(oSettings.nTBody);
  13166. body.children().detach();
  13167. body.append( $(anRows) );
  13168. /* Call all required callback functions for the end of a draw */
  13169. _fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
  13170. /* Draw is complete, sorting and filtering must be as well */
  13171. oSettings.bSorted = false;
  13172. oSettings.bFiltered = false;
  13173. oSettings.bDrawing = false;
  13174. }
  13175. /**
  13176. * Redraw the table - taking account of the various features which are enabled
  13177. * @param {object} oSettings dataTables settings object
  13178. * @param {boolean} [holdPosition] Keep the current paging position. By default
  13179. * the paging is reset to the first page
  13180. * @memberof DataTable#oApi
  13181. */
  13182. function _fnReDraw( settings, holdPosition )
  13183. {
  13184. var
  13185. features = settings.oFeatures,
  13186. sort = features.bSort,
  13187. filter = features.bFilter;
  13188. if ( sort ) {
  13189. _fnSort( settings );
  13190. }
  13191. if ( filter ) {
  13192. _fnFilterComplete( settings, settings.oPreviousSearch );
  13193. }
  13194. else {
  13195. // No filtering, so we want to just use the display master
  13196. settings.aiDisplay = settings.aiDisplayMaster.slice();
  13197. }
  13198. if ( holdPosition !== true ) {
  13199. settings._iDisplayStart = 0;
  13200. }
  13201. // Let any modules know about the draw hold position state (used by
  13202. // scrolling internally)
  13203. settings._drawHold = holdPosition;
  13204. _fnDraw( settings );
  13205. settings._drawHold = false;
  13206. }
  13207. /**
  13208. * Add the options to the page HTML for the table
  13209. * @param {object} oSettings dataTables settings object
  13210. * @memberof DataTable#oApi
  13211. */
  13212. function _fnAddOptionsHtml ( oSettings )
  13213. {
  13214. var classes = oSettings.oClasses;
  13215. var table = $(oSettings.nTable);
  13216. var holding = $('<div/>').insertBefore( table ); // Holding element for speed
  13217. var features = oSettings.oFeatures;
  13218. // All DataTables are wrapped in a div
  13219. var insert = $('<div/>', {
  13220. id: oSettings.sTableId+'_wrapper',
  13221. 'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)
  13222. } );
  13223. oSettings.nHolding = holding[0];
  13224. oSettings.nTableWrapper = insert[0];
  13225. oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
  13226. /* Loop over the user set positioning and place the elements as needed */
  13227. var aDom = oSettings.sDom.split('');
  13228. var featureNode, cOption, nNewNode, cNext, sAttr, j;
  13229. for ( var i=0 ; i<aDom.length ; i++ )
  13230. {
  13231. featureNode = null;
  13232. cOption = aDom[i];
  13233. if ( cOption == '<' )
  13234. {
  13235. /* New container div */
  13236. nNewNode = $('<div/>')[0];
  13237. /* Check to see if we should append an id and/or a class name to the container */
  13238. cNext = aDom[i+1];
  13239. if ( cNext == "'" || cNext == '"' )
  13240. {
  13241. sAttr = "";
  13242. j = 2;
  13243. while ( aDom[i+j] != cNext )
  13244. {
  13245. sAttr += aDom[i+j];
  13246. j++;
  13247. }
  13248. /* Replace jQuery UI constants @todo depreciated */
  13249. if ( sAttr == "H" )
  13250. {
  13251. sAttr = classes.sJUIHeader;
  13252. }
  13253. else if ( sAttr == "F" )
  13254. {
  13255. sAttr = classes.sJUIFooter;
  13256. }
  13257. /* The attribute can be in the format of "#id.class", "#id" or "class" This logic
  13258. * breaks the string into parts and applies them as needed
  13259. */
  13260. if ( sAttr.indexOf('.') != -1 )
  13261. {
  13262. var aSplit = sAttr.split('.');
  13263. nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
  13264. nNewNode.className = aSplit[1];
  13265. }
  13266. else if ( sAttr.charAt(0) == "#" )
  13267. {
  13268. nNewNode.id = sAttr.substr(1, sAttr.length-1);
  13269. }
  13270. else
  13271. {
  13272. nNewNode.className = sAttr;
  13273. }
  13274. i += j; /* Move along the position array */
  13275. }
  13276. insert.append( nNewNode );
  13277. insert = $(nNewNode);
  13278. }
  13279. else if ( cOption == '>' )
  13280. {
  13281. /* End container div */
  13282. insert = insert.parent();
  13283. }
  13284. // @todo Move options into their own plugins?
  13285. else if ( cOption == 'l' && features.bPaginate && features.bLengthChange )
  13286. {
  13287. /* Length */
  13288. featureNode = _fnFeatureHtmlLength( oSettings );
  13289. }
  13290. else if ( cOption == 'f' && features.bFilter )
  13291. {
  13292. /* Filter */
  13293. featureNode = _fnFeatureHtmlFilter( oSettings );
  13294. }
  13295. else if ( cOption == 'r' && features.bProcessing )
  13296. {
  13297. /* pRocessing */
  13298. featureNode = _fnFeatureHtmlProcessing( oSettings );
  13299. }
  13300. else if ( cOption == 't' )
  13301. {
  13302. /* Table */
  13303. featureNode = _fnFeatureHtmlTable( oSettings );
  13304. }
  13305. else if ( cOption == 'i' && features.bInfo )
  13306. {
  13307. /* Info */
  13308. featureNode = _fnFeatureHtmlInfo( oSettings );
  13309. }
  13310. else if ( cOption == 'p' && features.bPaginate )
  13311. {
  13312. /* Pagination */
  13313. featureNode = _fnFeatureHtmlPaginate( oSettings );
  13314. }
  13315. else if ( DataTable.ext.feature.length !== 0 )
  13316. {
  13317. /* Plug-in features */
  13318. var aoFeatures = DataTable.ext.feature;
  13319. for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )
  13320. {
  13321. if ( cOption == aoFeatures[k].cFeature )
  13322. {
  13323. featureNode = aoFeatures[k].fnInit( oSettings );
  13324. break;
  13325. }
  13326. }
  13327. }
  13328. /* Add to the 2D features array */
  13329. if ( featureNode )
  13330. {
  13331. var aanFeatures = oSettings.aanFeatures;
  13332. if ( ! aanFeatures[cOption] )
  13333. {
  13334. aanFeatures[cOption] = [];
  13335. }
  13336. aanFeatures[cOption].push( featureNode );
  13337. insert.append( featureNode );
  13338. }
  13339. }
  13340. /* Built our DOM structure - replace the holding div with what we want */
  13341. holding.replaceWith( insert );
  13342. oSettings.nHolding = null;
  13343. }
  13344. /**
  13345. * Use the DOM source to create up an array of header cells. The idea here is to
  13346. * create a layout grid (array) of rows x columns, which contains a reference
  13347. * to the cell that that point in the grid (regardless of col/rowspan), such that
  13348. * any column / row could be removed and the new grid constructed
  13349. * @param array {object} aLayout Array to store the calculated layout in
  13350. * @param {node} nThead The header/footer element for the table
  13351. * @memberof DataTable#oApi
  13352. */
  13353. function _fnDetectHeader ( aLayout, nThead )
  13354. {
  13355. var nTrs = $(nThead).children('tr');
  13356. var nTr, nCell;
  13357. var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
  13358. var bUnique;
  13359. var fnShiftCol = function ( a, i, j ) {
  13360. var k = a[i];
  13361. while ( k[j] ) {
  13362. j++;
  13363. }
  13364. return j;
  13365. };
  13366. aLayout.splice( 0, aLayout.length );
  13367. /* We know how many rows there are in the layout - so prep it */
  13368. for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
  13369. {
  13370. aLayout.push( [] );
  13371. }
  13372. /* Calculate a layout array */
  13373. for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
  13374. {
  13375. nTr = nTrs[i];
  13376. iColumn = 0;
  13377. /* For every cell in the row... */
  13378. nCell = nTr.firstChild;
  13379. while ( nCell ) {
  13380. if ( nCell.nodeName.toUpperCase() == "TD" ||
  13381. nCell.nodeName.toUpperCase() == "TH" )
  13382. {
  13383. /* Get the col and rowspan attributes from the DOM and sanitise them */
  13384. iColspan = nCell.getAttribute('colspan') * 1;
  13385. iRowspan = nCell.getAttribute('rowspan') * 1;
  13386. iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;
  13387. iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;
  13388. /* There might be colspan cells already in this row, so shift our target
  13389. * accordingly
  13390. */
  13391. iColShifted = fnShiftCol( aLayout, i, iColumn );
  13392. /* Cache calculation for unique columns */
  13393. bUnique = iColspan === 1 ? true : false;
  13394. /* If there is col / rowspan, copy the information into the layout grid */
  13395. for ( l=0 ; l<iColspan ; l++ )
  13396. {
  13397. for ( k=0 ; k<iRowspan ; k++ )
  13398. {
  13399. aLayout[i+k][iColShifted+l] = {
  13400. "cell": nCell,
  13401. "unique": bUnique
  13402. };
  13403. aLayout[i+k].nTr = nTr;
  13404. }
  13405. }
  13406. }
  13407. nCell = nCell.nextSibling;
  13408. }
  13409. }
  13410. }
  13411. /**
  13412. * Get an array of unique th elements, one for each column
  13413. * @param {object} oSettings dataTables settings object
  13414. * @param {node} nHeader automatically detect the layout from this node - optional
  13415. * @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
  13416. * @returns array {node} aReturn list of unique th's
  13417. * @memberof DataTable#oApi
  13418. */
  13419. function _fnGetUniqueThs ( oSettings, nHeader, aLayout )
  13420. {
  13421. var aReturn = [];
  13422. if ( !aLayout )
  13423. {
  13424. aLayout = oSettings.aoHeader;
  13425. if ( nHeader )
  13426. {
  13427. aLayout = [];
  13428. _fnDetectHeader( aLayout, nHeader );
  13429. }
  13430. }
  13431. for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )
  13432. {
  13433. for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )
  13434. {
  13435. if ( aLayout[i][j].unique &&
  13436. (!aReturn[j] || !oSettings.bSortCellsTop) )
  13437. {
  13438. aReturn[j] = aLayout[i][j].cell;
  13439. }
  13440. }
  13441. }
  13442. return aReturn;
  13443. }
  13444. /**
  13445. * Create an Ajax call based on the table's settings, taking into account that
  13446. * parameters can have multiple forms, and backwards compatibility.
  13447. *
  13448. * @param {object} oSettings dataTables settings object
  13449. * @param {array} data Data to send to the server, required by
  13450. * DataTables - may be augmented by developer callbacks
  13451. * @param {function} fn Callback function to run when data is obtained
  13452. */
  13453. function _fnBuildAjax( oSettings, data, fn )
  13454. {
  13455. // Compatibility with 1.9-, allow fnServerData and event to manipulate
  13456. _fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );
  13457. // Convert to object based for 1.10+ if using the old array scheme which can
  13458. // come from server-side processing or serverParams
  13459. if ( data && $.isArray(data) ) {
  13460. var tmp = {};
  13461. var rbracket = /(.*?)\[\]$/;
  13462. $.each( data, function (key, val) {
  13463. var match = val.name.match(rbracket);
  13464. if ( match ) {
  13465. // Support for arrays
  13466. var name = match[0];
  13467. if ( ! tmp[ name ] ) {
  13468. tmp[ name ] = [];
  13469. }
  13470. tmp[ name ].push( val.value );
  13471. }
  13472. else {
  13473. tmp[val.name] = val.value;
  13474. }
  13475. } );
  13476. data = tmp;
  13477. }
  13478. var ajaxData;
  13479. var ajax = oSettings.ajax;
  13480. var instance = oSettings.oInstance;
  13481. var callback = function ( json ) {
  13482. _fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );
  13483. fn( json );
  13484. };
  13485. if ( $.isPlainObject( ajax ) && ajax.data )
  13486. {
  13487. ajaxData = ajax.data;
  13488. var newData = $.isFunction( ajaxData ) ?
  13489. ajaxData( data, oSettings ) : // fn can manipulate data or return
  13490. ajaxData; // an object object or array to merge
  13491. // If the function returned something, use that alone
  13492. data = $.isFunction( ajaxData ) && newData ?
  13493. newData :
  13494. $.extend( true, data, newData );
  13495. // Remove the data property as we've resolved it already and don't want
  13496. // jQuery to do it again (it is restored at the end of the function)
  13497. delete ajax.data;
  13498. }
  13499. var baseAjax = {
  13500. "data": data,
  13501. "success": function (json) {
  13502. var error = json.error || json.sError;
  13503. if ( error ) {
  13504. _fnLog( oSettings, 0, error );
  13505. }
  13506. oSettings.json = json;
  13507. callback( json );
  13508. },
  13509. "dataType": "json",
  13510. "cache": false,
  13511. "type": oSettings.sServerMethod,
  13512. "error": function (xhr, error, thrown) {
  13513. var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );
  13514. if ( $.inArray( true, ret ) === -1 ) {
  13515. if ( error == "parsererror" ) {
  13516. _fnLog( oSettings, 0, 'Invalid JSON response', 1 );
  13517. }
  13518. else if ( xhr.readyState === 4 ) {
  13519. _fnLog( oSettings, 0, 'Ajax error', 7 );
  13520. }
  13521. }
  13522. _fnProcessingDisplay( oSettings, false );
  13523. }
  13524. };
  13525. // Store the data submitted for the API
  13526. oSettings.oAjaxData = data;
  13527. // Allow plug-ins and external processes to modify the data
  13528. _fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );
  13529. if ( oSettings.fnServerData )
  13530. {
  13531. // DataTables 1.9- compatibility
  13532. oSettings.fnServerData.call( instance,
  13533. oSettings.sAjaxSource,
  13534. $.map( data, function (val, key) { // Need to convert back to 1.9 trad format
  13535. return { name: key, value: val };
  13536. } ),
  13537. callback,
  13538. oSettings
  13539. );
  13540. }
  13541. else if ( oSettings.sAjaxSource || typeof ajax === 'string' )
  13542. {
  13543. // DataTables 1.9- compatibility
  13544. oSettings.jqXHR = $.ajax( $.extend( baseAjax, {
  13545. url: ajax || oSettings.sAjaxSource
  13546. } ) );
  13547. }
  13548. else if ( $.isFunction( ajax ) )
  13549. {
  13550. // Is a function - let the caller define what needs to be done
  13551. oSettings.jqXHR = ajax.call( instance, data, callback, oSettings );
  13552. }
  13553. else
  13554. {
  13555. // Object to extend the base settings
  13556. oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );
  13557. // Restore for next time around
  13558. ajax.data = ajaxData;
  13559. }
  13560. }
  13561. /**
  13562. * Update the table using an Ajax call
  13563. * @param {object} settings dataTables settings object
  13564. * @returns {boolean} Block the table drawing or not
  13565. * @memberof DataTable#oApi
  13566. */
  13567. function _fnAjaxUpdate( settings )
  13568. {
  13569. if ( settings.bAjaxDataGet ) {
  13570. settings.iDraw++;
  13571. _fnProcessingDisplay( settings, true );
  13572. _fnBuildAjax(
  13573. settings,
  13574. _fnAjaxParameters( settings ),
  13575. function(json) {
  13576. _fnAjaxUpdateDraw( settings, json );
  13577. }
  13578. );
  13579. return false;
  13580. }
  13581. return true;
  13582. }
  13583. /**
  13584. * Build up the parameters in an object needed for a server-side processing
  13585. * request. Note that this is basically done twice, is different ways - a modern
  13586. * method which is used by default in DataTables 1.10 which uses objects and
  13587. * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if
  13588. * the sAjaxSource option is used in the initialisation, or the legacyAjax
  13589. * option is set.
  13590. * @param {object} oSettings dataTables settings object
  13591. * @returns {bool} block the table drawing or not
  13592. * @memberof DataTable#oApi
  13593. */
  13594. function _fnAjaxParameters( settings )
  13595. {
  13596. var
  13597. columns = settings.aoColumns,
  13598. columnCount = columns.length,
  13599. features = settings.oFeatures,
  13600. preSearch = settings.oPreviousSearch,
  13601. preColSearch = settings.aoPreSearchCols,
  13602. i, data = [], dataProp, column, columnSearch,
  13603. sort = _fnSortFlatten( settings ),
  13604. displayStart = settings._iDisplayStart,
  13605. displayLength = features.bPaginate !== false ?
  13606. settings._iDisplayLength :
  13607. -1;
  13608. var param = function ( name, value ) {
  13609. data.push( { 'name': name, 'value': value } );
  13610. };
  13611. // DataTables 1.9- compatible method
  13612. param( 'sEcho', settings.iDraw );
  13613. param( 'iColumns', columnCount );
  13614. param( 'sColumns', _pluck( columns, 'sName' ).join(',') );
  13615. param( 'iDisplayStart', displayStart );
  13616. param( 'iDisplayLength', displayLength );
  13617. // DataTables 1.10+ method
  13618. var d = {
  13619. draw: settings.iDraw,
  13620. columns: [],
  13621. order: [],
  13622. start: displayStart,
  13623. length: displayLength,
  13624. search: {
  13625. value: preSearch.sSearch,
  13626. regex: preSearch.bRegex
  13627. }
  13628. };
  13629. for ( i=0 ; i<columnCount ; i++ ) {
  13630. column = columns[i];
  13631. columnSearch = preColSearch[i];
  13632. dataProp = typeof column.mData=="function" ? 'function' : column.mData ;
  13633. d.columns.push( {
  13634. data: dataProp,
  13635. name: column.sName,
  13636. searchable: column.bSearchable,
  13637. orderable: column.bSortable,
  13638. search: {
  13639. value: columnSearch.sSearch,
  13640. regex: columnSearch.bRegex
  13641. }
  13642. } );
  13643. param( "mDataProp_"+i, dataProp );
  13644. if ( features.bFilter ) {
  13645. param( 'sSearch_'+i, columnSearch.sSearch );
  13646. param( 'bRegex_'+i, columnSearch.bRegex );
  13647. param( 'bSearchable_'+i, column.bSearchable );
  13648. }
  13649. if ( features.bSort ) {
  13650. param( 'bSortable_'+i, column.bSortable );
  13651. }
  13652. }
  13653. if ( features.bFilter ) {
  13654. param( 'sSearch', preSearch.sSearch );
  13655. param( 'bRegex', preSearch.bRegex );
  13656. }
  13657. if ( features.bSort ) {
  13658. $.each( sort, function ( i, val ) {
  13659. d.order.push( { column: val.col, dir: val.dir } );
  13660. param( 'iSortCol_'+i, val.col );
  13661. param( 'sSortDir_'+i, val.dir );
  13662. } );
  13663. param( 'iSortingCols', sort.length );
  13664. }
  13665. // If the legacy.ajax parameter is null, then we automatically decide which
  13666. // form to use, based on sAjaxSource
  13667. var legacy = DataTable.ext.legacy.ajax;
  13668. if ( legacy === null ) {
  13669. return settings.sAjaxSource ? data : d;
  13670. }
  13671. // Otherwise, if legacy has been specified then we use that to decide on the
  13672. // form
  13673. return legacy ? data : d;
  13674. }
  13675. /**
  13676. * Data the data from the server (nuking the old) and redraw the table
  13677. * @param {object} oSettings dataTables settings object
  13678. * @param {object} json json data return from the server.
  13679. * @param {string} json.sEcho Tracking flag for DataTables to match requests
  13680. * @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
  13681. * @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
  13682. * @param {array} json.aaData The data to display on this page
  13683. * @param {string} [json.sColumns] Column ordering (sName, comma separated)
  13684. * @memberof DataTable#oApi
  13685. */
  13686. function _fnAjaxUpdateDraw ( settings, json )
  13687. {
  13688. // v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
  13689. // Support both
  13690. var compat = function ( old, modern ) {
  13691. return json[old] !== undefined ? json[old] : json[modern];
  13692. };
  13693. var data = _fnAjaxDataSrc( settings, json );
  13694. var draw = compat( 'sEcho', 'draw' );
  13695. var recordsTotal = compat( 'iTotalRecords', 'recordsTotal' );
  13696. var recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );
  13697. if ( draw ) {
  13698. // Protect against out of sequence returns
  13699. if ( draw*1 < settings.iDraw ) {
  13700. return;
  13701. }
  13702. settings.iDraw = draw * 1;
  13703. }
  13704. _fnClearTable( settings );
  13705. settings._iRecordsTotal = parseInt(recordsTotal, 10);
  13706. settings._iRecordsDisplay = parseInt(recordsFiltered, 10);
  13707. for ( var i=0, ien=data.length ; i<ien ; i++ ) {
  13708. _fnAddData( settings, data[i] );
  13709. }
  13710. settings.aiDisplay = settings.aiDisplayMaster.slice();
  13711. settings.bAjaxDataGet = false;
  13712. _fnDraw( settings );
  13713. if ( ! settings._bInitComplete ) {
  13714. _fnInitComplete( settings, json );
  13715. }
  13716. settings.bAjaxDataGet = true;
  13717. _fnProcessingDisplay( settings, false );
  13718. }
  13719. /**
  13720. * Get the data from the JSON data source to use for drawing a table. Using
  13721. * `_fnGetObjectDataFn` allows the data to be sourced from a property of the
  13722. * source object, or from a processing function.
  13723. * @param {object} oSettings dataTables settings object
  13724. * @param {object} json Data source object / array from the server
  13725. * @return {array} Array of data to use
  13726. */
  13727. function _fnAjaxDataSrc ( oSettings, json )
  13728. {
  13729. var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?
  13730. oSettings.ajax.dataSrc :
  13731. oSettings.sAjaxDataProp; // Compatibility with 1.9-.
  13732. // Compatibility with 1.9-. In order to read from aaData, check if the
  13733. // default has been changed, if not, check for aaData
  13734. if ( dataSrc === 'data' ) {
  13735. return json.aaData || json[dataSrc];
  13736. }
  13737. return dataSrc !== "" ?
  13738. _fnGetObjectDataFn( dataSrc )( json ) :
  13739. json;
  13740. }
  13741. /**
  13742. * Generate the node required for filtering text
  13743. * @returns {node} Filter control element
  13744. * @param {object} oSettings dataTables settings object
  13745. * @memberof DataTable#oApi
  13746. */
  13747. function _fnFeatureHtmlFilter ( settings )
  13748. {
  13749. var classes = settings.oClasses;
  13750. var tableId = settings.sTableId;
  13751. var language = settings.oLanguage;
  13752. var previousSearch = settings.oPreviousSearch;
  13753. var features = settings.aanFeatures;
  13754. var input = '<input type="search" class="'+classes.sFilterInput+'"/>';
  13755. var str = language.sSearch;
  13756. str = str.match(/_INPUT_/) ?
  13757. str.replace('_INPUT_', input) :
  13758. str+input;
  13759. var filter = $('<div/>', {
  13760. 'id': ! features.f ? tableId+'_filter' : null,
  13761. 'class': classes.sFilter
  13762. } )
  13763. .append( $('<label/>' ).append( str ) );
  13764. var searchFn = function() {
  13765. /* Update all other filter input elements for the new display */
  13766. var n = features.f;
  13767. var val = !this.value ? "" : this.value; // mental IE8 fix :-(
  13768. /* Now do the filter */
  13769. if ( val != previousSearch.sSearch ) {
  13770. _fnFilterComplete( settings, {
  13771. "sSearch": val,
  13772. "bRegex": previousSearch.bRegex,
  13773. "bSmart": previousSearch.bSmart ,
  13774. "bCaseInsensitive": previousSearch.bCaseInsensitive
  13775. } );
  13776. // Need to redraw, without resorting
  13777. settings._iDisplayStart = 0;
  13778. _fnDraw( settings );
  13779. }
  13780. };
  13781. var searchDelay = settings.searchDelay !== null ?
  13782. settings.searchDelay :
  13783. _fnDataSource( settings ) === 'ssp' ?
  13784. 400 :
  13785. 0;
  13786. var jqFilter = $('input', filter)
  13787. .val( previousSearch.sSearch )
  13788. .attr( 'placeholder', language.sSearchPlaceholder )
  13789. .on(
  13790. 'keyup.DT search.DT input.DT paste.DT cut.DT',
  13791. searchDelay ?
  13792. _fnThrottle( searchFn, searchDelay ) :
  13793. searchFn
  13794. )
  13795. .on( 'keypress.DT', function(e) {
  13796. /* Prevent form submission */
  13797. if ( e.keyCode == 13 ) {
  13798. return false;
  13799. }
  13800. } )
  13801. .attr('aria-controls', tableId);
  13802. // Update the input elements whenever the table is filtered
  13803. $(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {
  13804. if ( settings === s ) {
  13805. // IE9 throws an 'unknown error' if document.activeElement is used
  13806. // inside an iframe or frame...
  13807. try {
  13808. if ( jqFilter[0] !== document.activeElement ) {
  13809. jqFilter.val( previousSearch.sSearch );
  13810. }
  13811. }
  13812. catch ( e ) {}
  13813. }
  13814. } );
  13815. return filter[0];
  13816. }
  13817. /**
  13818. * Filter the table using both the global filter and column based filtering
  13819. * @param {object} oSettings dataTables settings object
  13820. * @param {object} oSearch search information
  13821. * @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
  13822. * @memberof DataTable#oApi
  13823. */
  13824. function _fnFilterComplete ( oSettings, oInput, iForce )
  13825. {
  13826. var oPrevSearch = oSettings.oPreviousSearch;
  13827. var aoPrevSearch = oSettings.aoPreSearchCols;
  13828. var fnSaveFilter = function ( oFilter ) {
  13829. /* Save the filtering values */
  13830. oPrevSearch.sSearch = oFilter.sSearch;
  13831. oPrevSearch.bRegex = oFilter.bRegex;
  13832. oPrevSearch.bSmart = oFilter.bSmart;
  13833. oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
  13834. };
  13835. var fnRegex = function ( o ) {
  13836. // Backwards compatibility with the bEscapeRegex option
  13837. return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
  13838. };
  13839. // Resolve any column types that are unknown due to addition or invalidation
  13840. // @todo As per sort - can this be moved into an event handler?
  13841. _fnColumnTypes( oSettings );
  13842. /* In server-side processing all filtering is done by the server, so no point hanging around here */
  13843. if ( _fnDataSource( oSettings ) != 'ssp' )
  13844. {
  13845. /* Global filter */
  13846. _fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );
  13847. fnSaveFilter( oInput );
  13848. /* Now do the individual column filter */
  13849. for ( var i=0 ; i<aoPrevSearch.length ; i++ )
  13850. {
  13851. _fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
  13852. aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );
  13853. }
  13854. /* Custom filtering */
  13855. _fnFilterCustom( oSettings );
  13856. }
  13857. else
  13858. {
  13859. fnSaveFilter( oInput );
  13860. }
  13861. /* Tell the draw function we have been filtering */
  13862. oSettings.bFiltered = true;
  13863. _fnCallbackFire( oSettings, null, 'search', [oSettings] );
  13864. }
  13865. /**
  13866. * Apply custom filtering functions
  13867. * @param {object} oSettings dataTables settings object
  13868. * @memberof DataTable#oApi
  13869. */
  13870. function _fnFilterCustom( settings )
  13871. {
  13872. var filters = DataTable.ext.search;
  13873. var displayRows = settings.aiDisplay;
  13874. var row, rowIdx;
  13875. for ( var i=0, ien=filters.length ; i<ien ; i++ ) {
  13876. var rows = [];
  13877. // Loop over each row and see if it should be included
  13878. for ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {
  13879. rowIdx = displayRows[ j ];
  13880. row = settings.aoData[ rowIdx ];
  13881. if ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {
  13882. rows.push( rowIdx );
  13883. }
  13884. }
  13885. // So the array reference doesn't break set the results into the
  13886. // existing array
  13887. displayRows.length = 0;
  13888. $.merge( displayRows, rows );
  13889. }
  13890. }
  13891. /**
  13892. * Filter the table on a per-column basis
  13893. * @param {object} oSettings dataTables settings object
  13894. * @param {string} sInput string to filter on
  13895. * @param {int} iColumn column to filter
  13896. * @param {bool} bRegex treat search string as a regular expression or not
  13897. * @param {bool} bSmart use smart filtering or not
  13898. * @param {bool} bCaseInsensitive Do case insenstive matching or not
  13899. * @memberof DataTable#oApi
  13900. */
  13901. function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )
  13902. {
  13903. if ( searchStr === '' ) {
  13904. return;
  13905. }
  13906. var data;
  13907. var out = [];
  13908. var display = settings.aiDisplay;
  13909. var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );
  13910. for ( var i=0 ; i<display.length ; i++ ) {
  13911. data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
  13912. if ( rpSearch.test( data ) ) {
  13913. out.push( display[i] );
  13914. }
  13915. }
  13916. settings.aiDisplay = out;
  13917. }
  13918. /**
  13919. * Filter the data table based on user input and draw the table
  13920. * @param {object} settings dataTables settings object
  13921. * @param {string} input string to filter on
  13922. * @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
  13923. * @param {bool} regex treat as a regular expression or not
  13924. * @param {bool} smart perform smart filtering or not
  13925. * @param {bool} caseInsensitive Do case insenstive matching or not
  13926. * @memberof DataTable#oApi
  13927. */
  13928. function _fnFilter( settings, input, force, regex, smart, caseInsensitive )
  13929. {
  13930. var rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );
  13931. var prevSearch = settings.oPreviousSearch.sSearch;
  13932. var displayMaster = settings.aiDisplayMaster;
  13933. var display, invalidated, i;
  13934. var filtered = [];
  13935. // Need to take account of custom filtering functions - always filter
  13936. if ( DataTable.ext.search.length !== 0 ) {
  13937. force = true;
  13938. }
  13939. // Check if any of the rows were invalidated
  13940. invalidated = _fnFilterData( settings );
  13941. // If the input is blank - we just want the full data set
  13942. if ( input.length <= 0 ) {
  13943. settings.aiDisplay = displayMaster.slice();
  13944. }
  13945. else {
  13946. // New search - start from the master array
  13947. if ( invalidated ||
  13948. force ||
  13949. prevSearch.length > input.length ||
  13950. input.indexOf(prevSearch) !== 0 ||
  13951. settings.bSorted // On resort, the display master needs to be
  13952. // re-filtered since indexes will have changed
  13953. ) {
  13954. settings.aiDisplay = displayMaster.slice();
  13955. }
  13956. // Search the display array
  13957. display = settings.aiDisplay;
  13958. for ( i=0 ; i<display.length ; i++ ) {
  13959. if ( rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {
  13960. filtered.push( display[i] );
  13961. }
  13962. }
  13963. settings.aiDisplay = filtered;
  13964. }
  13965. }
  13966. /**
  13967. * Build a regular expression object suitable for searching a table
  13968. * @param {string} sSearch string to search for
  13969. * @param {bool} bRegex treat as a regular expression or not
  13970. * @param {bool} bSmart perform smart filtering or not
  13971. * @param {bool} bCaseInsensitive Do case insensitive matching or not
  13972. * @returns {RegExp} constructed object
  13973. * @memberof DataTable#oApi
  13974. */
  13975. function _fnFilterCreateSearch( search, regex, smart, caseInsensitive )
  13976. {
  13977. search = regex ?
  13978. search :
  13979. _fnEscapeRegex( search );
  13980. if ( smart ) {
  13981. /* For smart filtering we want to allow the search to work regardless of
  13982. * word order. We also want double quoted text to be preserved, so word
  13983. * order is important - a la google. So this is what we want to
  13984. * generate:
  13985. *
  13986. * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
  13987. */
  13988. var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || [''], function ( word ) {
  13989. if ( word.charAt(0) === '"' ) {
  13990. var m = word.match( /^"(.*)"$/ );
  13991. word = m ? m[1] : word;
  13992. }
  13993. return word.replace('"', '');
  13994. } );
  13995. search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';
  13996. }
  13997. return new RegExp( search, caseInsensitive ? 'i' : '' );
  13998. }
  13999. /**
  14000. * Escape a string such that it can be used in a regular expression
  14001. * @param {string} sVal string to escape
  14002. * @returns {string} escaped string
  14003. * @memberof DataTable#oApi
  14004. */
  14005. var _fnEscapeRegex = DataTable.util.escapeRegex;
  14006. var __filter_div = $('<div>')[0];
  14007. var __filter_div_textContent = __filter_div.textContent !== undefined;
  14008. // Update the filtering data for each row if needed (by invalidation or first run)
  14009. function _fnFilterData ( settings )
  14010. {
  14011. var columns = settings.aoColumns;
  14012. var column;
  14013. var i, j, ien, jen, filterData, cellData, row;
  14014. var fomatters = DataTable.ext.type.search;
  14015. var wasInvalidated = false;
  14016. for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
  14017. row = settings.aoData[i];
  14018. if ( ! row._aFilterData ) {
  14019. filterData = [];
  14020. for ( j=0, jen=columns.length ; j<jen ; j++ ) {
  14021. column = columns[j];
  14022. if ( column.bSearchable ) {
  14023. cellData = _fnGetCellData( settings, i, j, 'filter' );
  14024. if ( fomatters[ column.sType ] ) {
  14025. cellData = fomatters[ column.sType ]( cellData );
  14026. }
  14027. // Search in DataTables 1.10 is string based. In 1.11 this
  14028. // should be altered to also allow strict type checking.
  14029. if ( cellData === null ) {
  14030. cellData = '';
  14031. }
  14032. if ( typeof cellData !== 'string' && cellData.toString ) {
  14033. cellData = cellData.toString();
  14034. }
  14035. }
  14036. else {
  14037. cellData = '';
  14038. }
  14039. // If it looks like there is an HTML entity in the string,
  14040. // attempt to decode it so sorting works as expected. Note that
  14041. // we could use a single line of jQuery to do this, but the DOM
  14042. // method used here is much faster http://jsperf.com/html-decode
  14043. if ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {
  14044. __filter_div.innerHTML = cellData;
  14045. cellData = __filter_div_textContent ?
  14046. __filter_div.textContent :
  14047. __filter_div.innerText;
  14048. }
  14049. if ( cellData.replace ) {
  14050. cellData = cellData.replace(/[\r\n]/g, '');
  14051. }
  14052. filterData.push( cellData );
  14053. }
  14054. row._aFilterData = filterData;
  14055. row._sFilterRow = filterData.join(' ');
  14056. wasInvalidated = true;
  14057. }
  14058. }
  14059. return wasInvalidated;
  14060. }
  14061. /**
  14062. * Convert from the internal Hungarian notation to camelCase for external
  14063. * interaction
  14064. * @param {object} obj Object to convert
  14065. * @returns {object} Inverted object
  14066. * @memberof DataTable#oApi
  14067. */
  14068. function _fnSearchToCamel ( obj )
  14069. {
  14070. return {
  14071. search: obj.sSearch,
  14072. smart: obj.bSmart,
  14073. regex: obj.bRegex,
  14074. caseInsensitive: obj.bCaseInsensitive
  14075. };
  14076. }
  14077. /**
  14078. * Convert from camelCase notation to the internal Hungarian. We could use the
  14079. * Hungarian convert function here, but this is cleaner
  14080. * @param {object} obj Object to convert
  14081. * @returns {object} Inverted object
  14082. * @memberof DataTable#oApi
  14083. */
  14084. function _fnSearchToHung ( obj )
  14085. {
  14086. return {
  14087. sSearch: obj.search,
  14088. bSmart: obj.smart,
  14089. bRegex: obj.regex,
  14090. bCaseInsensitive: obj.caseInsensitive
  14091. };
  14092. }
  14093. /**
  14094. * Generate the node required for the info display
  14095. * @param {object} oSettings dataTables settings object
  14096. * @returns {node} Information element
  14097. * @memberof DataTable#oApi
  14098. */
  14099. function _fnFeatureHtmlInfo ( settings )
  14100. {
  14101. var
  14102. tid = settings.sTableId,
  14103. nodes = settings.aanFeatures.i,
  14104. n = $('<div/>', {
  14105. 'class': settings.oClasses.sInfo,
  14106. 'id': ! nodes ? tid+'_info' : null
  14107. } );
  14108. if ( ! nodes ) {
  14109. // Update display on each draw
  14110. settings.aoDrawCallback.push( {
  14111. "fn": _fnUpdateInfo,
  14112. "sName": "information"
  14113. } );
  14114. n
  14115. .attr( 'role', 'status' )
  14116. .attr( 'aria-live', 'polite' );
  14117. // Table is described by our info div
  14118. $(settings.nTable).attr( 'aria-describedby', tid+'_info' );
  14119. }
  14120. return n[0];
  14121. }
  14122. /**
  14123. * Update the information elements in the display
  14124. * @param {object} settings dataTables settings object
  14125. * @memberof DataTable#oApi
  14126. */
  14127. function _fnUpdateInfo ( settings )
  14128. {
  14129. /* Show information about the table */
  14130. var nodes = settings.aanFeatures.i;
  14131. if ( nodes.length === 0 ) {
  14132. return;
  14133. }
  14134. var
  14135. lang = settings.oLanguage,
  14136. start = settings._iDisplayStart+1,
  14137. end = settings.fnDisplayEnd(),
  14138. max = settings.fnRecordsTotal(),
  14139. total = settings.fnRecordsDisplay(),
  14140. out = total ?
  14141. lang.sInfo :
  14142. lang.sInfoEmpty;
  14143. if ( total !== max ) {
  14144. /* Record set after filtering */
  14145. out += ' ' + lang.sInfoFiltered;
  14146. }
  14147. // Convert the macros
  14148. out += lang.sInfoPostFix;
  14149. out = _fnInfoMacros( settings, out );
  14150. var callback = lang.fnInfoCallback;
  14151. if ( callback !== null ) {
  14152. out = callback.call( settings.oInstance,
  14153. settings, start, end, max, total, out
  14154. );
  14155. }
  14156. $(nodes).html( out );
  14157. }
  14158. function _fnInfoMacros ( settings, str )
  14159. {
  14160. // When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
  14161. // internally
  14162. var
  14163. formatter = settings.fnFormatNumber,
  14164. start = settings._iDisplayStart+1,
  14165. len = settings._iDisplayLength,
  14166. vis = settings.fnRecordsDisplay(),
  14167. all = len === -1;
  14168. return str.
  14169. replace(/_START_/g, formatter.call( settings, start ) ).
  14170. replace(/_END_/g, formatter.call( settings, settings.fnDisplayEnd() ) ).
  14171. replace(/_MAX_/g, formatter.call( settings, settings.fnRecordsTotal() ) ).
  14172. replace(/_TOTAL_/g, formatter.call( settings, vis ) ).
  14173. replace(/_PAGE_/g, formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).
  14174. replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );
  14175. }
  14176. /**
  14177. * Draw the table for the first time, adding all required features
  14178. * @param {object} settings dataTables settings object
  14179. * @memberof DataTable#oApi
  14180. */
  14181. function _fnInitialise ( settings )
  14182. {
  14183. var i, iLen, iAjaxStart=settings.iInitDisplayStart;
  14184. var columns = settings.aoColumns, column;
  14185. var features = settings.oFeatures;
  14186. var deferLoading = settings.bDeferLoading; // value modified by the draw
  14187. /* Ensure that the table data is fully initialised */
  14188. if ( ! settings.bInitialised ) {
  14189. setTimeout( function(){ _fnInitialise( settings ); }, 200 );
  14190. return;
  14191. }
  14192. /* Show the display HTML options */
  14193. _fnAddOptionsHtml( settings );
  14194. /* Build and draw the header / footer for the table */
  14195. _fnBuildHead( settings );
  14196. _fnDrawHead( settings, settings.aoHeader );
  14197. _fnDrawHead( settings, settings.aoFooter );
  14198. /* Okay to show that something is going on now */
  14199. _fnProcessingDisplay( settings, true );
  14200. /* Calculate sizes for columns */
  14201. if ( features.bAutoWidth ) {
  14202. _fnCalculateColumnWidths( settings );
  14203. }
  14204. for ( i=0, iLen=columns.length ; i<iLen ; i++ ) {
  14205. column = columns[i];
  14206. if ( column.sWidth ) {
  14207. column.nTh.style.width = _fnStringToCss( column.sWidth );
  14208. }
  14209. }
  14210. _fnCallbackFire( settings, null, 'preInit', [settings] );
  14211. // If there is default sorting required - let's do it. The sort function
  14212. // will do the drawing for us. Otherwise we draw the table regardless of the
  14213. // Ajax source - this allows the table to look initialised for Ajax sourcing
  14214. // data (show 'loading' message possibly)
  14215. _fnReDraw( settings );
  14216. // Server-side processing init complete is done by _fnAjaxUpdateDraw
  14217. var dataSrc = _fnDataSource( settings );
  14218. if ( dataSrc != 'ssp' || deferLoading ) {
  14219. // if there is an ajax source load the data
  14220. if ( dataSrc == 'ajax' ) {
  14221. _fnBuildAjax( settings, [], function(json) {
  14222. var aData = _fnAjaxDataSrc( settings, json );
  14223. // Got the data - add it to the table
  14224. for ( i=0 ; i<aData.length ; i++ ) {
  14225. _fnAddData( settings, aData[i] );
  14226. }
  14227. // Reset the init display for cookie saving. We've already done
  14228. // a filter, and therefore cleared it before. So we need to make
  14229. // it appear 'fresh'
  14230. settings.iInitDisplayStart = iAjaxStart;
  14231. _fnReDraw( settings );
  14232. _fnProcessingDisplay( settings, false );
  14233. _fnInitComplete( settings, json );
  14234. }, settings );
  14235. }
  14236. else {
  14237. _fnProcessingDisplay( settings, false );
  14238. _fnInitComplete( settings );
  14239. }
  14240. }
  14241. }
  14242. /**
  14243. * Draw the table for the first time, adding all required features
  14244. * @param {object} oSettings dataTables settings object
  14245. * @param {object} [json] JSON from the server that completed the table, if using Ajax source
  14246. * with client-side processing (optional)
  14247. * @memberof DataTable#oApi
  14248. */
  14249. function _fnInitComplete ( settings, json )
  14250. {
  14251. settings._bInitComplete = true;
  14252. // When data was added after the initialisation (data or Ajax) we need to
  14253. // calculate the column sizing
  14254. if ( json || settings.oInit.aaData ) {
  14255. _fnAdjustColumnSizing( settings );
  14256. }
  14257. _fnCallbackFire( settings, null, 'plugin-init', [settings, json] );
  14258. _fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );
  14259. }
  14260. function _fnLengthChange ( settings, val )
  14261. {
  14262. var len = parseInt( val, 10 );
  14263. settings._iDisplayLength = len;
  14264. _fnLengthOverflow( settings );
  14265. // Fire length change event
  14266. _fnCallbackFire( settings, null, 'length', [settings, len] );
  14267. }
  14268. /**
  14269. * Generate the node required for user display length changing
  14270. * @param {object} settings dataTables settings object
  14271. * @returns {node} Display length feature node
  14272. * @memberof DataTable#oApi
  14273. */
  14274. function _fnFeatureHtmlLength ( settings )
  14275. {
  14276. var
  14277. classes = settings.oClasses,
  14278. tableId = settings.sTableId,
  14279. menu = settings.aLengthMenu,
  14280. d2 = $.isArray( menu[0] ),
  14281. lengths = d2 ? menu[0] : menu,
  14282. language = d2 ? menu[1] : menu;
  14283. var select = $('<select/>', {
  14284. 'name': tableId+'_length',
  14285. 'aria-controls': tableId,
  14286. 'class': classes.sLengthSelect
  14287. } );
  14288. for ( var i=0, ien=lengths.length ; i<ien ; i++ ) {
  14289. select[0][ i ] = new Option( language[i], lengths[i] );
  14290. }
  14291. var div = $('<div><label/></div>').addClass( classes.sLength );
  14292. if ( ! settings.aanFeatures.l ) {
  14293. div[0].id = tableId+'_length';
  14294. }
  14295. div.children().append(
  14296. settings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )
  14297. );
  14298. // Can't use `select` variable as user might provide their own and the
  14299. // reference is broken by the use of outerHTML
  14300. $('select', div)
  14301. .val( settings._iDisplayLength )
  14302. .on( 'change.DT', function(e) {
  14303. _fnLengthChange( settings, $(this).val() );
  14304. _fnDraw( settings );
  14305. } );
  14306. // Update node value whenever anything changes the table's length
  14307. $(settings.nTable).on( 'length.dt.DT', function (e, s, len) {
  14308. if ( settings === s ) {
  14309. $('select', div).val( len );
  14310. }
  14311. } );
  14312. return div[0];
  14313. }
  14314. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  14315. * Note that most of the paging logic is done in
  14316. * DataTable.ext.pager
  14317. */
  14318. /**
  14319. * Generate the node required for default pagination
  14320. * @param {object} oSettings dataTables settings object
  14321. * @returns {node} Pagination feature node
  14322. * @memberof DataTable#oApi
  14323. */
  14324. function _fnFeatureHtmlPaginate ( settings )
  14325. {
  14326. var
  14327. type = settings.sPaginationType,
  14328. plugin = DataTable.ext.pager[ type ],
  14329. modern = typeof plugin === 'function',
  14330. redraw = function( settings ) {
  14331. _fnDraw( settings );
  14332. },
  14333. node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],
  14334. features = settings.aanFeatures;
  14335. if ( ! modern ) {
  14336. plugin.fnInit( settings, node, redraw );
  14337. }
  14338. /* Add a draw callback for the pagination on first instance, to update the paging display */
  14339. if ( ! features.p )
  14340. {
  14341. node.id = settings.sTableId+'_paginate';
  14342. settings.aoDrawCallback.push( {
  14343. "fn": function( settings ) {
  14344. if ( modern ) {
  14345. var
  14346. start = settings._iDisplayStart,
  14347. len = settings._iDisplayLength,
  14348. visRecords = settings.fnRecordsDisplay(),
  14349. all = len === -1,
  14350. page = all ? 0 : Math.ceil( start / len ),
  14351. pages = all ? 1 : Math.ceil( visRecords / len ),
  14352. buttons = plugin(page, pages),
  14353. i, ien;
  14354. for ( i=0, ien=features.p.length ; i<ien ; i++ ) {
  14355. _fnRenderer( settings, 'pageButton' )(
  14356. settings, features.p[i], i, buttons, page, pages
  14357. );
  14358. }
  14359. }
  14360. else {
  14361. plugin.fnUpdate( settings, redraw );
  14362. }
  14363. },
  14364. "sName": "pagination"
  14365. } );
  14366. }
  14367. return node;
  14368. }
  14369. /**
  14370. * Alter the display settings to change the page
  14371. * @param {object} settings DataTables settings object
  14372. * @param {string|int} action Paging action to take: "first", "previous",
  14373. * "next" or "last" or page number to jump to (integer)
  14374. * @param [bool] redraw Automatically draw the update or not
  14375. * @returns {bool} true page has changed, false - no change
  14376. * @memberof DataTable#oApi
  14377. */
  14378. function _fnPageChange ( settings, action, redraw )
  14379. {
  14380. var
  14381. start = settings._iDisplayStart,
  14382. len = settings._iDisplayLength,
  14383. records = settings.fnRecordsDisplay();
  14384. if ( records === 0 || len === -1 )
  14385. {
  14386. start = 0;
  14387. }
  14388. else if ( typeof action === "number" )
  14389. {
  14390. start = action * len;
  14391. if ( start > records )
  14392. {
  14393. start = 0;
  14394. }
  14395. }
  14396. else if ( action == "first" )
  14397. {
  14398. start = 0;
  14399. }
  14400. else if ( action == "previous" )
  14401. {
  14402. start = len >= 0 ?
  14403. start - len :
  14404. 0;
  14405. if ( start < 0 )
  14406. {
  14407. start = 0;
  14408. }
  14409. }
  14410. else if ( action == "next" )
  14411. {
  14412. if ( start + len < records )
  14413. {
  14414. start += len;
  14415. }
  14416. }
  14417. else if ( action == "last" )
  14418. {
  14419. start = Math.floor( (records-1) / len) * len;
  14420. }
  14421. else
  14422. {
  14423. _fnLog( settings, 0, "Unknown paging action: "+action, 5 );
  14424. }
  14425. var changed = settings._iDisplayStart !== start;
  14426. settings._iDisplayStart = start;
  14427. if ( changed ) {
  14428. _fnCallbackFire( settings, null, 'page', [settings] );
  14429. if ( redraw ) {
  14430. _fnDraw( settings );
  14431. }
  14432. }
  14433. return changed;
  14434. }
  14435. /**
  14436. * Generate the node required for the processing node
  14437. * @param {object} settings dataTables settings object
  14438. * @returns {node} Processing element
  14439. * @memberof DataTable#oApi
  14440. */
  14441. function _fnFeatureHtmlProcessing ( settings )
  14442. {
  14443. return $('<div/>', {
  14444. 'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,
  14445. 'class': settings.oClasses.sProcessing
  14446. } )
  14447. .html( settings.oLanguage.sProcessing )
  14448. .insertBefore( settings.nTable )[0];
  14449. }
  14450. /**
  14451. * Display or hide the processing indicator
  14452. * @param {object} settings dataTables settings object
  14453. * @param {bool} show Show the processing indicator (true) or not (false)
  14454. * @memberof DataTable#oApi
  14455. */
  14456. function _fnProcessingDisplay ( settings, show )
  14457. {
  14458. if ( settings.oFeatures.bProcessing ) {
  14459. $(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );
  14460. }
  14461. _fnCallbackFire( settings, null, 'processing', [settings, show] );
  14462. }
  14463. /**
  14464. * Add any control elements for the table - specifically scrolling
  14465. * @param {object} settings dataTables settings object
  14466. * @returns {node} Node to add to the DOM
  14467. * @memberof DataTable#oApi
  14468. */
  14469. function _fnFeatureHtmlTable ( settings )
  14470. {
  14471. var table = $(settings.nTable);
  14472. // Add the ARIA grid role to the table
  14473. table.attr( 'role', 'grid' );
  14474. // Scrolling from here on in
  14475. var scroll = settings.oScroll;
  14476. if ( scroll.sX === '' && scroll.sY === '' ) {
  14477. return settings.nTable;
  14478. }
  14479. var scrollX = scroll.sX;
  14480. var scrollY = scroll.sY;
  14481. var classes = settings.oClasses;
  14482. var caption = table.children('caption');
  14483. var captionSide = caption.length ? caption[0]._captionSide : null;
  14484. var headerClone = $( table[0].cloneNode(false) );
  14485. var footerClone = $( table[0].cloneNode(false) );
  14486. var footer = table.children('tfoot');
  14487. var _div = '<div/>';
  14488. var size = function ( s ) {
  14489. return !s ? null : _fnStringToCss( s );
  14490. };
  14491. if ( ! footer.length ) {
  14492. footer = null;
  14493. }
  14494. /*
  14495. * The HTML structure that we want to generate in this function is:
  14496. * div - scroller
  14497. * div - scroll head
  14498. * div - scroll head inner
  14499. * table - scroll head table
  14500. * thead - thead
  14501. * div - scroll body
  14502. * table - table (master table)
  14503. * thead - thead clone for sizing
  14504. * tbody - tbody
  14505. * div - scroll foot
  14506. * div - scroll foot inner
  14507. * table - scroll foot table
  14508. * tfoot - tfoot
  14509. */
  14510. var scroller = $( _div, { 'class': classes.sScrollWrapper } )
  14511. .append(
  14512. $(_div, { 'class': classes.sScrollHead } )
  14513. .css( {
  14514. overflow: 'hidden',
  14515. position: 'relative',
  14516. border: 0,
  14517. width: scrollX ? size(scrollX) : '100%'
  14518. } )
  14519. .append(
  14520. $(_div, { 'class': classes.sScrollHeadInner } )
  14521. .css( {
  14522. 'box-sizing': 'content-box',
  14523. width: scroll.sXInner || '100%'
  14524. } )
  14525. .append(
  14526. headerClone
  14527. .removeAttr('id')
  14528. .css( 'margin-left', 0 )
  14529. .append( captionSide === 'top' ? caption : null )
  14530. .append(
  14531. table.children('thead')
  14532. )
  14533. )
  14534. )
  14535. )
  14536. .append(
  14537. $(_div, { 'class': classes.sScrollBody } )
  14538. .css( {
  14539. position: 'relative',
  14540. overflow: 'auto',
  14541. width: size( scrollX )
  14542. } )
  14543. .append( table )
  14544. );
  14545. if ( footer ) {
  14546. scroller.append(
  14547. $(_div, { 'class': classes.sScrollFoot } )
  14548. .css( {
  14549. overflow: 'hidden',
  14550. border: 0,
  14551. width: scrollX ? size(scrollX) : '100%'
  14552. } )
  14553. .append(
  14554. $(_div, { 'class': classes.sScrollFootInner } )
  14555. .append(
  14556. footerClone
  14557. .removeAttr('id')
  14558. .css( 'margin-left', 0 )
  14559. .append( captionSide === 'bottom' ? caption : null )
  14560. .append(
  14561. table.children('tfoot')
  14562. )
  14563. )
  14564. )
  14565. );
  14566. }
  14567. var children = scroller.children();
  14568. var scrollHead = children[0];
  14569. var scrollBody = children[1];
  14570. var scrollFoot = footer ? children[2] : null;
  14571. // When the body is scrolled, then we also want to scroll the headers
  14572. if ( scrollX ) {
  14573. $(scrollBody).on( 'scroll.DT', function (e) {
  14574. var scrollLeft = this.scrollLeft;
  14575. scrollHead.scrollLeft = scrollLeft;
  14576. if ( footer ) {
  14577. scrollFoot.scrollLeft = scrollLeft;
  14578. }
  14579. } );
  14580. }
  14581. $(scrollBody).css(
  14582. scrollY && scroll.bCollapse ? 'max-height' : 'height',
  14583. scrollY
  14584. );
  14585. settings.nScrollHead = scrollHead;
  14586. settings.nScrollBody = scrollBody;
  14587. settings.nScrollFoot = scrollFoot;
  14588. // On redraw - align columns
  14589. settings.aoDrawCallback.push( {
  14590. "fn": _fnScrollDraw,
  14591. "sName": "scrolling"
  14592. } );
  14593. return scroller[0];
  14594. }
  14595. /**
  14596. * Update the header, footer and body tables for resizing - i.e. column
  14597. * alignment.
  14598. *
  14599. * Welcome to the most horrible function DataTables. The process that this
  14600. * function follows is basically:
  14601. * 1. Re-create the table inside the scrolling div
  14602. * 2. Take live measurements from the DOM
  14603. * 3. Apply the measurements to align the columns
  14604. * 4. Clean up
  14605. *
  14606. * @param {object} settings dataTables settings object
  14607. * @memberof DataTable#oApi
  14608. */
  14609. function _fnScrollDraw ( settings )
  14610. {
  14611. // Given that this is such a monster function, a lot of variables are use
  14612. // to try and keep the minimised size as small as possible
  14613. var
  14614. scroll = settings.oScroll,
  14615. scrollX = scroll.sX,
  14616. scrollXInner = scroll.sXInner,
  14617. scrollY = scroll.sY,
  14618. barWidth = scroll.iBarWidth,
  14619. divHeader = $(settings.nScrollHead),
  14620. divHeaderStyle = divHeader[0].style,
  14621. divHeaderInner = divHeader.children('div'),
  14622. divHeaderInnerStyle = divHeaderInner[0].style,
  14623. divHeaderTable = divHeaderInner.children('table'),
  14624. divBodyEl = settings.nScrollBody,
  14625. divBody = $(divBodyEl),
  14626. divBodyStyle = divBodyEl.style,
  14627. divFooter = $(settings.nScrollFoot),
  14628. divFooterInner = divFooter.children('div'),
  14629. divFooterTable = divFooterInner.children('table'),
  14630. header = $(settings.nTHead),
  14631. table = $(settings.nTable),
  14632. tableEl = table[0],
  14633. tableStyle = tableEl.style,
  14634. footer = settings.nTFoot ? $(settings.nTFoot) : null,
  14635. browser = settings.oBrowser,
  14636. ie67 = browser.bScrollOversize,
  14637. dtHeaderCells = _pluck( settings.aoColumns, 'nTh' ),
  14638. headerTrgEls, footerTrgEls,
  14639. headerSrcEls, footerSrcEls,
  14640. headerCopy, footerCopy,
  14641. headerWidths=[], footerWidths=[],
  14642. headerContent=[], footerContent=[],
  14643. idx, correction, sanityWidth,
  14644. zeroOut = function(nSizer) {
  14645. var style = nSizer.style;
  14646. style.paddingTop = "0";
  14647. style.paddingBottom = "0";
  14648. style.borderTopWidth = "0";
  14649. style.borderBottomWidth = "0";
  14650. style.height = 0;
  14651. };
  14652. // If the scrollbar visibility has changed from the last draw, we need to
  14653. // adjust the column sizes as the table width will have changed to account
  14654. // for the scrollbar
  14655. var scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;
  14656. if ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) {
  14657. settings.scrollBarVis = scrollBarVis;
  14658. _fnAdjustColumnSizing( settings );
  14659. return; // adjust column sizing will call this function again
  14660. }
  14661. else {
  14662. settings.scrollBarVis = scrollBarVis;
  14663. }
  14664. /*
  14665. * 1. Re-create the table inside the scrolling div
  14666. */
  14667. // Remove the old minimised thead and tfoot elements in the inner table
  14668. table.children('thead, tfoot').remove();
  14669. if ( footer ) {
  14670. footerCopy = footer.clone().prependTo( table );
  14671. footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
  14672. footerSrcEls = footerCopy.find('tr');
  14673. }
  14674. // Clone the current header and footer elements and then place it into the inner table
  14675. headerCopy = header.clone().prependTo( table );
  14676. headerTrgEls = header.find('tr'); // original header is in its own table
  14677. headerSrcEls = headerCopy.find('tr');
  14678. headerCopy.find('th, td').removeAttr('tabindex');
  14679. /*
  14680. * 2. Take live measurements from the DOM - do not alter the DOM itself!
  14681. */
  14682. // Remove old sizing and apply the calculated column widths
  14683. // Get the unique column headers in the newly created (cloned) header. We want to apply the
  14684. // calculated sizes to this header
  14685. if ( ! scrollX )
  14686. {
  14687. divBodyStyle.width = '100%';
  14688. divHeader[0].style.width = '100%';
  14689. }
  14690. $.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {
  14691. idx = _fnVisibleToColumnIndex( settings, i );
  14692. el.style.width = settings.aoColumns[idx].sWidth;
  14693. } );
  14694. if ( footer ) {
  14695. _fnApplyToChildren( function(n) {
  14696. n.style.width = "";
  14697. }, footerSrcEls );
  14698. }
  14699. // Size the table as a whole
  14700. sanityWidth = table.outerWidth();
  14701. if ( scrollX === "" ) {
  14702. // No x scrolling
  14703. tableStyle.width = "100%";
  14704. // IE7 will make the width of the table when 100% include the scrollbar
  14705. // - which is shouldn't. When there is a scrollbar we need to take this
  14706. // into account.
  14707. if ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
  14708. divBody.css('overflow-y') == "scroll")
  14709. ) {
  14710. tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);
  14711. }
  14712. // Recalculate the sanity width
  14713. sanityWidth = table.outerWidth();
  14714. }
  14715. else if ( scrollXInner !== "" ) {
  14716. // legacy x scroll inner has been given - use it
  14717. tableStyle.width = _fnStringToCss(scrollXInner);
  14718. // Recalculate the sanity width
  14719. sanityWidth = table.outerWidth();
  14720. }
  14721. // Hidden header should have zero height, so remove padding and borders. Then
  14722. // set the width based on the real headers
  14723. // Apply all styles in one pass
  14724. _fnApplyToChildren( zeroOut, headerSrcEls );
  14725. // Read all widths in next pass
  14726. _fnApplyToChildren( function(nSizer) {
  14727. headerContent.push( nSizer.innerHTML );
  14728. headerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
  14729. }, headerSrcEls );
  14730. // Apply all widths in final pass
  14731. _fnApplyToChildren( function(nToSize, i) {
  14732. // Only apply widths to the DataTables detected header cells - this
  14733. // prevents complex headers from having contradictory sizes applied
  14734. if ( $.inArray( nToSize, dtHeaderCells ) !== -1 ) {
  14735. nToSize.style.width = headerWidths[i];
  14736. }
  14737. }, headerTrgEls );
  14738. $(headerSrcEls).height(0);
  14739. /* Same again with the footer if we have one */
  14740. if ( footer )
  14741. {
  14742. _fnApplyToChildren( zeroOut, footerSrcEls );
  14743. _fnApplyToChildren( function(nSizer) {
  14744. footerContent.push( nSizer.innerHTML );
  14745. footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
  14746. }, footerSrcEls );
  14747. _fnApplyToChildren( function(nToSize, i) {
  14748. nToSize.style.width = footerWidths[i];
  14749. }, footerTrgEls );
  14750. $(footerSrcEls).height(0);
  14751. }
  14752. /*
  14753. * 3. Apply the measurements
  14754. */
  14755. // "Hide" the header and footer that we used for the sizing. We need to keep
  14756. // the content of the cell so that the width applied to the header and body
  14757. // both match, but we want to hide it completely. We want to also fix their
  14758. // width to what they currently are
  14759. _fnApplyToChildren( function(nSizer, i) {
  14760. nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+headerContent[i]+'</div>';
  14761. nSizer.style.width = headerWidths[i];
  14762. }, headerSrcEls );
  14763. if ( footer )
  14764. {
  14765. _fnApplyToChildren( function(nSizer, i) {
  14766. nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+footerContent[i]+'</div>';
  14767. nSizer.style.width = footerWidths[i];
  14768. }, footerSrcEls );
  14769. }
  14770. // Sanity check that the table is of a sensible width. If not then we are going to get
  14771. // misalignment - try to prevent this by not allowing the table to shrink below its min width
  14772. if ( table.outerWidth() < sanityWidth )
  14773. {
  14774. // The min width depends upon if we have a vertical scrollbar visible or not */
  14775. correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
  14776. divBody.css('overflow-y') == "scroll")) ?
  14777. sanityWidth+barWidth :
  14778. sanityWidth;
  14779. // IE6/7 are a law unto themselves...
  14780. if ( ie67 && (divBodyEl.scrollHeight >
  14781. divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")
  14782. ) {
  14783. tableStyle.width = _fnStringToCss( correction-barWidth );
  14784. }
  14785. // And give the user a warning that we've stopped the table getting too small
  14786. if ( scrollX === "" || scrollXInner !== "" ) {
  14787. _fnLog( settings, 1, 'Possible column misalignment', 6 );
  14788. }
  14789. }
  14790. else
  14791. {
  14792. correction = '100%';
  14793. }
  14794. // Apply to the container elements
  14795. divBodyStyle.width = _fnStringToCss( correction );
  14796. divHeaderStyle.width = _fnStringToCss( correction );
  14797. if ( footer ) {
  14798. settings.nScrollFoot.style.width = _fnStringToCss( correction );
  14799. }
  14800. /*
  14801. * 4. Clean up
  14802. */
  14803. if ( ! scrollY ) {
  14804. /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
  14805. * the scrollbar height from the visible display, rather than adding it on. We need to
  14806. * set the height in order to sort this. Don't want to do it in any other browsers.
  14807. */
  14808. if ( ie67 ) {
  14809. divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );
  14810. }
  14811. }
  14812. /* Finally set the width's of the header and footer tables */
  14813. var iOuterWidth = table.outerWidth();
  14814. divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );
  14815. divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );
  14816. // Figure out if there are scrollbar present - if so then we need a the header and footer to
  14817. // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
  14818. var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
  14819. var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );
  14820. divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px";
  14821. if ( footer ) {
  14822. divFooterTable[0].style.width = _fnStringToCss( iOuterWidth );
  14823. divFooterInner[0].style.width = _fnStringToCss( iOuterWidth );
  14824. divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px";
  14825. }
  14826. // Correct DOM ordering for colgroup - comes before the thead
  14827. table.children('colgroup').insertBefore( table.children('thead') );
  14828. /* Adjust the position of the header in case we loose the y-scrollbar */
  14829. divBody.scroll();
  14830. // If sorting or filtering has occurred, jump the scrolling back to the top
  14831. // only if we aren't holding the position
  14832. if ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {
  14833. divBodyEl.scrollTop = 0;
  14834. }
  14835. }
  14836. /**
  14837. * Apply a given function to the display child nodes of an element array (typically
  14838. * TD children of TR rows
  14839. * @param {function} fn Method to apply to the objects
  14840. * @param array {nodes} an1 List of elements to look through for display children
  14841. * @param array {nodes} an2 Another list (identical structure to the first) - optional
  14842. * @memberof DataTable#oApi
  14843. */
  14844. function _fnApplyToChildren( fn, an1, an2 )
  14845. {
  14846. var index=0, i=0, iLen=an1.length;
  14847. var nNode1, nNode2;
  14848. while ( i < iLen ) {
  14849. nNode1 = an1[i].firstChild;
  14850. nNode2 = an2 ? an2[i].firstChild : null;
  14851. while ( nNode1 ) {
  14852. if ( nNode1.nodeType === 1 ) {
  14853. if ( an2 ) {
  14854. fn( nNode1, nNode2, index );
  14855. }
  14856. else {
  14857. fn( nNode1, index );
  14858. }
  14859. index++;
  14860. }
  14861. nNode1 = nNode1.nextSibling;
  14862. nNode2 = an2 ? nNode2.nextSibling : null;
  14863. }
  14864. i++;
  14865. }
  14866. }
  14867. var __re_html_remove = /<.*?>/g;
  14868. /**
  14869. * Calculate the width of columns for the table
  14870. * @param {object} oSettings dataTables settings object
  14871. * @memberof DataTable#oApi
  14872. */
  14873. function _fnCalculateColumnWidths ( oSettings )
  14874. {
  14875. var
  14876. table = oSettings.nTable,
  14877. columns = oSettings.aoColumns,
  14878. scroll = oSettings.oScroll,
  14879. scrollY = scroll.sY,
  14880. scrollX = scroll.sX,
  14881. scrollXInner = scroll.sXInner,
  14882. columnCount = columns.length,
  14883. visibleColumns = _fnGetColumns( oSettings, 'bVisible' ),
  14884. headerCells = $('th', oSettings.nTHead),
  14885. tableWidthAttr = table.getAttribute('width'), // from DOM element
  14886. tableContainer = table.parentNode,
  14887. userInputs = false,
  14888. i, column, columnIdx, width, outerWidth,
  14889. browser = oSettings.oBrowser,
  14890. ie67 = browser.bScrollOversize;
  14891. var styleWidth = table.style.width;
  14892. if ( styleWidth && styleWidth.indexOf('%') !== -1 ) {
  14893. tableWidthAttr = styleWidth;
  14894. }
  14895. /* Convert any user input sizes into pixel sizes */
  14896. for ( i=0 ; i<visibleColumns.length ; i++ ) {
  14897. column = columns[ visibleColumns[i] ];
  14898. if ( column.sWidth !== null ) {
  14899. column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );
  14900. userInputs = true;
  14901. }
  14902. }
  14903. /* If the number of columns in the DOM equals the number that we have to
  14904. * process in DataTables, then we can use the offsets that are created by
  14905. * the web- browser. No custom sizes can be set in order for this to happen,
  14906. * nor scrolling used
  14907. */
  14908. if ( ie67 || ! userInputs && ! scrollX && ! scrollY &&
  14909. columnCount == _fnVisbleColumns( oSettings ) &&
  14910. columnCount == headerCells.length
  14911. ) {
  14912. for ( i=0 ; i<columnCount ; i++ ) {
  14913. var colIdx = _fnVisibleToColumnIndex( oSettings, i );
  14914. if ( colIdx !== null ) {
  14915. columns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() );
  14916. }
  14917. }
  14918. }
  14919. else
  14920. {
  14921. // Otherwise construct a single row, worst case, table with the widest
  14922. // node in the data, assign any user defined widths, then insert it into
  14923. // the DOM and allow the browser to do all the hard work of calculating
  14924. // table widths
  14925. var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table
  14926. .css( 'visibility', 'hidden' )
  14927. .removeAttr( 'id' );
  14928. // Clean up the table body
  14929. tmpTable.find('tbody tr').remove();
  14930. var tr = $('<tr/>').appendTo( tmpTable.find('tbody') );
  14931. // Clone the table header and footer - we can't use the header / footer
  14932. // from the cloned table, since if scrolling is active, the table's
  14933. // real header and footer are contained in different table tags
  14934. tmpTable.find('thead, tfoot').remove();
  14935. tmpTable
  14936. .append( $(oSettings.nTHead).clone() )
  14937. .append( $(oSettings.nTFoot).clone() );
  14938. // Remove any assigned widths from the footer (from scrolling)
  14939. tmpTable.find('tfoot th, tfoot td').css('width', '');
  14940. // Apply custom sizing to the cloned header
  14941. headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );
  14942. for ( i=0 ; i<visibleColumns.length ; i++ ) {
  14943. column = columns[ visibleColumns[i] ];
  14944. headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
  14945. _fnStringToCss( column.sWidthOrig ) :
  14946. '';
  14947. // For scrollX we need to force the column width otherwise the
  14948. // browser will collapse it. If this width is smaller than the
  14949. // width the column requires, then it will have no effect
  14950. if ( column.sWidthOrig && scrollX ) {
  14951. $( headerCells[i] ).append( $('<div/>').css( {
  14952. width: column.sWidthOrig,
  14953. margin: 0,
  14954. padding: 0,
  14955. border: 0,
  14956. height: 1
  14957. } ) );
  14958. }
  14959. }
  14960. // Find the widest cell for each column and put it into the table
  14961. if ( oSettings.aoData.length ) {
  14962. for ( i=0 ; i<visibleColumns.length ; i++ ) {
  14963. columnIdx = visibleColumns[i];
  14964. column = columns[ columnIdx ];
  14965. $( _fnGetWidestNode( oSettings, columnIdx ) )
  14966. .clone( false )
  14967. .append( column.sContentPadding )
  14968. .appendTo( tr );
  14969. }
  14970. }
  14971. // Tidy the temporary table - remove name attributes so there aren't
  14972. // duplicated in the dom (radio elements for example)
  14973. $('[name]', tmpTable).removeAttr('name');
  14974. // Table has been built, attach to the document so we can work with it.
  14975. // A holding element is used, positioned at the top of the container
  14976. // with minimal height, so it has no effect on if the container scrolls
  14977. // or not. Otherwise it might trigger scrolling when it actually isn't
  14978. // needed
  14979. var holder = $('<div/>').css( scrollX || scrollY ?
  14980. {
  14981. position: 'absolute',
  14982. top: 0,
  14983. left: 0,
  14984. height: 1,
  14985. right: 0,
  14986. overflow: 'hidden'
  14987. } :
  14988. {}
  14989. )
  14990. .append( tmpTable )
  14991. .appendTo( tableContainer );
  14992. // When scrolling (X or Y) we want to set the width of the table as
  14993. // appropriate. However, when not scrolling leave the table width as it
  14994. // is. This results in slightly different, but I think correct behaviour
  14995. if ( scrollX && scrollXInner ) {
  14996. tmpTable.width( scrollXInner );
  14997. }
  14998. else if ( scrollX ) {
  14999. tmpTable.css( 'width', 'auto' );
  15000. tmpTable.removeAttr('width');
  15001. // If there is no width attribute or style, then allow the table to
  15002. // collapse
  15003. if ( tmpTable.width() < tableContainer.clientWidth && tableWidthAttr ) {
  15004. tmpTable.width( tableContainer.clientWidth );
  15005. }
  15006. }
  15007. else if ( scrollY ) {
  15008. tmpTable.width( tableContainer.clientWidth );
  15009. }
  15010. else if ( tableWidthAttr ) {
  15011. tmpTable.width( tableWidthAttr );
  15012. }
  15013. // Get the width of each column in the constructed table - we need to
  15014. // know the inner width (so it can be assigned to the other table's
  15015. // cells) and the outer width so we can calculate the full width of the
  15016. // table. This is safe since DataTables requires a unique cell for each
  15017. // column, but if ever a header can span multiple columns, this will
  15018. // need to be modified.
  15019. var total = 0;
  15020. for ( i=0 ; i<visibleColumns.length ; i++ ) {
  15021. var cell = $(headerCells[i]);
  15022. var border = cell.outerWidth() - cell.width();
  15023. // Use getBounding... where possible (not IE8-) because it can give
  15024. // sub-pixel accuracy, which we then want to round up!
  15025. var bounding = browser.bBounding ?
  15026. Math.ceil( headerCells[i].getBoundingClientRect().width ) :
  15027. cell.outerWidth();
  15028. // Total is tracked to remove any sub-pixel errors as the outerWidth
  15029. // of the table might not equal the total given here (IE!).
  15030. total += bounding;
  15031. // Width for each column to use
  15032. columns[ visibleColumns[i] ].sWidth = _fnStringToCss( bounding - border );
  15033. }
  15034. table.style.width = _fnStringToCss( total );
  15035. // Finished with the table - ditch it
  15036. holder.remove();
  15037. }
  15038. // If there is a width attr, we want to attach an event listener which
  15039. // allows the table sizing to automatically adjust when the window is
  15040. // resized. Use the width attr rather than CSS, since we can't know if the
  15041. // CSS is a relative value or absolute - DOM read is always px.
  15042. if ( tableWidthAttr ) {
  15043. table.style.width = _fnStringToCss( tableWidthAttr );
  15044. }
  15045. if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {
  15046. var bindResize = function () {
  15047. $(window).on('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
  15048. _fnAdjustColumnSizing( oSettings );
  15049. } ) );
  15050. };
  15051. // IE6/7 will crash if we bind a resize event handler on page load.
  15052. // To be removed in 1.11 which drops IE6/7 support
  15053. if ( ie67 ) {
  15054. setTimeout( bindResize, 1000 );
  15055. }
  15056. else {
  15057. bindResize();
  15058. }
  15059. oSettings._reszEvt = true;
  15060. }
  15061. }
  15062. /**
  15063. * Throttle the calls to a function. Arguments and context are maintained for
  15064. * the throttled function
  15065. * @param {function} fn Function to be called
  15066. * @param {int} [freq=200] call frequency in mS
  15067. * @returns {function} wrapped function
  15068. * @memberof DataTable#oApi
  15069. */
  15070. var _fnThrottle = DataTable.util.throttle;
  15071. /**
  15072. * Convert a CSS unit width to pixels (e.g. 2em)
  15073. * @param {string} width width to be converted
  15074. * @param {node} parent parent to get the with for (required for relative widths) - optional
  15075. * @returns {int} width in pixels
  15076. * @memberof DataTable#oApi
  15077. */
  15078. function _fnConvertToWidth ( width, parent )
  15079. {
  15080. if ( ! width ) {
  15081. return 0;
  15082. }
  15083. var n = $('<div/>')
  15084. .css( 'width', _fnStringToCss( width ) )
  15085. .appendTo( parent || document.body );
  15086. var val = n[0].offsetWidth;
  15087. n.remove();
  15088. return val;
  15089. }
  15090. /**
  15091. * Get the widest node
  15092. * @param {object} settings dataTables settings object
  15093. * @param {int} colIdx column of interest
  15094. * @returns {node} widest table node
  15095. * @memberof DataTable#oApi
  15096. */
  15097. function _fnGetWidestNode( settings, colIdx )
  15098. {
  15099. var idx = _fnGetMaxLenString( settings, colIdx );
  15100. if ( idx < 0 ) {
  15101. return null;
  15102. }
  15103. var data = settings.aoData[ idx ];
  15104. return ! data.nTr ? // Might not have been created when deferred rendering
  15105. $('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :
  15106. data.anCells[ colIdx ];
  15107. }
  15108. /**
  15109. * Get the maximum strlen for each data column
  15110. * @param {object} settings dataTables settings object
  15111. * @param {int} colIdx column of interest
  15112. * @returns {string} max string length for each column
  15113. * @memberof DataTable#oApi
  15114. */
  15115. function _fnGetMaxLenString( settings, colIdx )
  15116. {
  15117. var s, max=-1, maxIdx = -1;
  15118. for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
  15119. s = _fnGetCellData( settings, i, colIdx, 'display' )+'';
  15120. s = s.replace( __re_html_remove, '' );
  15121. s = s.replace( /&nbsp;/g, ' ' );
  15122. if ( s.length > max ) {
  15123. max = s.length;
  15124. maxIdx = i;
  15125. }
  15126. }
  15127. return maxIdx;
  15128. }
  15129. /**
  15130. * Append a CSS unit (only if required) to a string
  15131. * @param {string} value to css-ify
  15132. * @returns {string} value with css unit
  15133. * @memberof DataTable#oApi
  15134. */
  15135. function _fnStringToCss( s )
  15136. {
  15137. if ( s === null ) {
  15138. return '0px';
  15139. }
  15140. if ( typeof s == 'number' ) {
  15141. return s < 0 ?
  15142. '0px' :
  15143. s+'px';
  15144. }
  15145. // Check it has a unit character already
  15146. return s.match(/\d$/) ?
  15147. s+'px' :
  15148. s;
  15149. }
  15150. function _fnSortFlatten ( settings )
  15151. {
  15152. var
  15153. i, iLen, k, kLen,
  15154. aSort = [],
  15155. aiOrig = [],
  15156. aoColumns = settings.aoColumns,
  15157. aDataSort, iCol, sType, srcCol,
  15158. fixed = settings.aaSortingFixed,
  15159. fixedObj = $.isPlainObject( fixed ),
  15160. nestedSort = [],
  15161. add = function ( a ) {
  15162. if ( a.length && ! $.isArray( a[0] ) ) {
  15163. // 1D array
  15164. nestedSort.push( a );
  15165. }
  15166. else {
  15167. // 2D array
  15168. $.merge( nestedSort, a );
  15169. }
  15170. };
  15171. // Build the sort array, with pre-fix and post-fix options if they have been
  15172. // specified
  15173. if ( $.isArray( fixed ) ) {
  15174. add( fixed );
  15175. }
  15176. if ( fixedObj && fixed.pre ) {
  15177. add( fixed.pre );
  15178. }
  15179. add( settings.aaSorting );
  15180. if (fixedObj && fixed.post ) {
  15181. add( fixed.post );
  15182. }
  15183. for ( i=0 ; i<nestedSort.length ; i++ )
  15184. {
  15185. srcCol = nestedSort[i][0];
  15186. aDataSort = aoColumns[ srcCol ].aDataSort;
  15187. for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
  15188. {
  15189. iCol = aDataSort[k];
  15190. sType = aoColumns[ iCol ].sType || 'string';
  15191. if ( nestedSort[i]._idx === undefined ) {
  15192. nestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );
  15193. }
  15194. aSort.push( {
  15195. src: srcCol,
  15196. col: iCol,
  15197. dir: nestedSort[i][1],
  15198. index: nestedSort[i]._idx,
  15199. type: sType,
  15200. formatter: DataTable.ext.type.order[ sType+"-pre" ]
  15201. } );
  15202. }
  15203. }
  15204. return aSort;
  15205. }
  15206. /**
  15207. * Change the order of the table
  15208. * @param {object} oSettings dataTables settings object
  15209. * @memberof DataTable#oApi
  15210. * @todo This really needs split up!
  15211. */
  15212. function _fnSort ( oSettings )
  15213. {
  15214. var
  15215. i, ien, iLen, j, jLen, k, kLen,
  15216. sDataType, nTh,
  15217. aiOrig = [],
  15218. oExtSort = DataTable.ext.type.order,
  15219. aoData = oSettings.aoData,
  15220. aoColumns = oSettings.aoColumns,
  15221. aDataSort, data, iCol, sType, oSort,
  15222. formatters = 0,
  15223. sortCol,
  15224. displayMaster = oSettings.aiDisplayMaster,
  15225. aSort;
  15226. // Resolve any column types that are unknown due to addition or invalidation
  15227. // @todo Can this be moved into a 'data-ready' handler which is called when
  15228. // data is going to be used in the table?
  15229. _fnColumnTypes( oSettings );
  15230. aSort = _fnSortFlatten( oSettings );
  15231. for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
  15232. sortCol = aSort[i];
  15233. // Track if we can use the fast sort algorithm
  15234. if ( sortCol.formatter ) {
  15235. formatters++;
  15236. }
  15237. // Load the data needed for the sort, for each cell
  15238. _fnSortData( oSettings, sortCol.col );
  15239. }
  15240. /* No sorting required if server-side or no sorting array */
  15241. if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )
  15242. {
  15243. // Create a value - key array of the current row positions such that we can use their
  15244. // current position during the sort, if values match, in order to perform stable sorting
  15245. for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {
  15246. aiOrig[ displayMaster[i] ] = i;
  15247. }
  15248. /* Do the sort - here we want multi-column sorting based on a given data source (column)
  15249. * and sorting function (from oSort) in a certain direction. It's reasonably complex to
  15250. * follow on it's own, but this is what we want (example two column sorting):
  15251. * fnLocalSorting = function(a,b){
  15252. * var iTest;
  15253. * iTest = oSort['string-asc']('data11', 'data12');
  15254. * if (iTest !== 0)
  15255. * return iTest;
  15256. * iTest = oSort['numeric-desc']('data21', 'data22');
  15257. * if (iTest !== 0)
  15258. * return iTest;
  15259. * return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
  15260. * }
  15261. * Basically we have a test for each sorting column, if the data in that column is equal,
  15262. * test the next column. If all columns match, then we use a numeric sort on the row
  15263. * positions in the original data array to provide a stable sort.
  15264. *
  15265. * Note - I know it seems excessive to have two sorting methods, but the first is around
  15266. * 15% faster, so the second is only maintained for backwards compatibility with sorting
  15267. * methods which do not have a pre-sort formatting function.
  15268. */
  15269. if ( formatters === aSort.length ) {
  15270. // All sort types have formatting functions
  15271. displayMaster.sort( function ( a, b ) {
  15272. var
  15273. x, y, k, test, sort,
  15274. len=aSort.length,
  15275. dataA = aoData[a]._aSortData,
  15276. dataB = aoData[b]._aSortData;
  15277. for ( k=0 ; k<len ; k++ ) {
  15278. sort = aSort[k];
  15279. x = dataA[ sort.col ];
  15280. y = dataB[ sort.col ];
  15281. test = x<y ? -1 : x>y ? 1 : 0;
  15282. if ( test !== 0 ) {
  15283. return sort.dir === 'asc' ? test : -test;
  15284. }
  15285. }
  15286. x = aiOrig[a];
  15287. y = aiOrig[b];
  15288. return x<y ? -1 : x>y ? 1 : 0;
  15289. } );
  15290. }
  15291. else {
  15292. // Depreciated - remove in 1.11 (providing a plug-in option)
  15293. // Not all sort types have formatting methods, so we have to call their sorting
  15294. // methods.
  15295. displayMaster.sort( function ( a, b ) {
  15296. var
  15297. x, y, k, l, test, sort, fn,
  15298. len=aSort.length,
  15299. dataA = aoData[a]._aSortData,
  15300. dataB = aoData[b]._aSortData;
  15301. for ( k=0 ; k<len ; k++ ) {
  15302. sort = aSort[k];
  15303. x = dataA[ sort.col ];
  15304. y = dataB[ sort.col ];
  15305. fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ];
  15306. test = fn( x, y );
  15307. if ( test !== 0 ) {
  15308. return test;
  15309. }
  15310. }
  15311. x = aiOrig[a];
  15312. y = aiOrig[b];
  15313. return x<y ? -1 : x>y ? 1 : 0;
  15314. } );
  15315. }
  15316. }
  15317. /* Tell the draw function that we have sorted the data */
  15318. oSettings.bSorted = true;
  15319. }
  15320. function _fnSortAria ( settings )
  15321. {
  15322. var label;
  15323. var nextSort;
  15324. var columns = settings.aoColumns;
  15325. var aSort = _fnSortFlatten( settings );
  15326. var oAria = settings.oLanguage.oAria;
  15327. // ARIA attributes - need to loop all columns, to update all (removing old
  15328. // attributes as needed)
  15329. for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
  15330. {
  15331. var col = columns[i];
  15332. var asSorting = col.asSorting;
  15333. var sTitle = col.sTitle.replace( /<.*?>/g, "" );
  15334. var th = col.nTh;
  15335. // IE7 is throwing an error when setting these properties with jQuery's
  15336. // attr() and removeAttr() methods...
  15337. th.removeAttribute('aria-sort');
  15338. /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
  15339. if ( col.bSortable ) {
  15340. if ( aSort.length > 0 && aSort[0].col == i ) {
  15341. th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" );
  15342. nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];
  15343. }
  15344. else {
  15345. nextSort = asSorting[0];
  15346. }
  15347. label = sTitle + ( nextSort === "asc" ?
  15348. oAria.sSortAscending :
  15349. oAria.sSortDescending
  15350. );
  15351. }
  15352. else {
  15353. label = sTitle;
  15354. }
  15355. th.setAttribute('aria-label', label);
  15356. }
  15357. }
  15358. /**
  15359. * Function to run on user sort request
  15360. * @param {object} settings dataTables settings object
  15361. * @param {node} attachTo node to attach the handler to
  15362. * @param {int} colIdx column sorting index
  15363. * @param {boolean} [append=false] Append the requested sort to the existing
  15364. * sort if true (i.e. multi-column sort)
  15365. * @param {function} [callback] callback function
  15366. * @memberof DataTable#oApi
  15367. */
  15368. function _fnSortListener ( settings, colIdx, append, callback )
  15369. {
  15370. var col = settings.aoColumns[ colIdx ];
  15371. var sorting = settings.aaSorting;
  15372. var asSorting = col.asSorting;
  15373. var nextSortIdx;
  15374. var next = function ( a, overflow ) {
  15375. var idx = a._idx;
  15376. if ( idx === undefined ) {
  15377. idx = $.inArray( a[1], asSorting );
  15378. }
  15379. return idx+1 < asSorting.length ?
  15380. idx+1 :
  15381. overflow ?
  15382. null :
  15383. 0;
  15384. };
  15385. // Convert to 2D array if needed
  15386. if ( typeof sorting[0] === 'number' ) {
  15387. sorting = settings.aaSorting = [ sorting ];
  15388. }
  15389. // If appending the sort then we are multi-column sorting
  15390. if ( append && settings.oFeatures.bSortMulti ) {
  15391. // Are we already doing some kind of sort on this column?
  15392. var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );
  15393. if ( sortIdx !== -1 ) {
  15394. // Yes, modify the sort
  15395. nextSortIdx = next( sorting[sortIdx], true );
  15396. if ( nextSortIdx === null && sorting.length === 1 ) {
  15397. nextSortIdx = 0; // can't remove sorting completely
  15398. }
  15399. if ( nextSortIdx === null ) {
  15400. sorting.splice( sortIdx, 1 );
  15401. }
  15402. else {
  15403. sorting[sortIdx][1] = asSorting[ nextSortIdx ];
  15404. sorting[sortIdx]._idx = nextSortIdx;
  15405. }
  15406. }
  15407. else {
  15408. // No sort on this column yet
  15409. sorting.push( [ colIdx, asSorting[0], 0 ] );
  15410. sorting[sorting.length-1]._idx = 0;
  15411. }
  15412. }
  15413. else if ( sorting.length && sorting[0][0] == colIdx ) {
  15414. // Single column - already sorting on this column, modify the sort
  15415. nextSortIdx = next( sorting[0] );
  15416. sorting.length = 1;
  15417. sorting[0][1] = asSorting[ nextSortIdx ];
  15418. sorting[0]._idx = nextSortIdx;
  15419. }
  15420. else {
  15421. // Single column - sort only on this column
  15422. sorting.length = 0;
  15423. sorting.push( [ colIdx, asSorting[0] ] );
  15424. sorting[0]._idx = 0;
  15425. }
  15426. // Run the sort by calling a full redraw
  15427. _fnReDraw( settings );
  15428. // callback used for async user interaction
  15429. if ( typeof callback == 'function' ) {
  15430. callback( settings );
  15431. }
  15432. }
  15433. /**
  15434. * Attach a sort handler (click) to a node
  15435. * @param {object} settings dataTables settings object
  15436. * @param {node} attachTo node to attach the handler to
  15437. * @param {int} colIdx column sorting index
  15438. * @param {function} [callback] callback function
  15439. * @memberof DataTable#oApi
  15440. */
  15441. function _fnSortAttachListener ( settings, attachTo, colIdx, callback )
  15442. {
  15443. var col = settings.aoColumns[ colIdx ];
  15444. _fnBindAction( attachTo, {}, function (e) {
  15445. /* If the column is not sortable - don't to anything */
  15446. if ( col.bSortable === false ) {
  15447. return;
  15448. }
  15449. // If processing is enabled use a timeout to allow the processing
  15450. // display to be shown - otherwise to it synchronously
  15451. if ( settings.oFeatures.bProcessing ) {
  15452. _fnProcessingDisplay( settings, true );
  15453. setTimeout( function() {
  15454. _fnSortListener( settings, colIdx, e.shiftKey, callback );
  15455. // In server-side processing, the draw callback will remove the
  15456. // processing display
  15457. if ( _fnDataSource( settings ) !== 'ssp' ) {
  15458. _fnProcessingDisplay( settings, false );
  15459. }
  15460. }, 0 );
  15461. }
  15462. else {
  15463. _fnSortListener( settings, colIdx, e.shiftKey, callback );
  15464. }
  15465. } );
  15466. }
  15467. /**
  15468. * Set the sorting classes on table's body, Note: it is safe to call this function
  15469. * when bSort and bSortClasses are false
  15470. * @param {object} oSettings dataTables settings object
  15471. * @memberof DataTable#oApi
  15472. */
  15473. function _fnSortingClasses( settings )
  15474. {
  15475. var oldSort = settings.aLastSort;
  15476. var sortClass = settings.oClasses.sSortColumn;
  15477. var sort = _fnSortFlatten( settings );
  15478. var features = settings.oFeatures;
  15479. var i, ien, colIdx;
  15480. if ( features.bSort && features.bSortClasses ) {
  15481. // Remove old sorting classes
  15482. for ( i=0, ien=oldSort.length ; i<ien ; i++ ) {
  15483. colIdx = oldSort[i].src;
  15484. // Remove column sorting
  15485. $( _pluck( settings.aoData, 'anCells', colIdx ) )
  15486. .removeClass( sortClass + (i<2 ? i+1 : 3) );
  15487. }
  15488. // Add new column sorting
  15489. for ( i=0, ien=sort.length ; i<ien ; i++ ) {
  15490. colIdx = sort[i].src;
  15491. $( _pluck( settings.aoData, 'anCells', colIdx ) )
  15492. .addClass( sortClass + (i<2 ? i+1 : 3) );
  15493. }
  15494. }
  15495. settings.aLastSort = sort;
  15496. }
  15497. // Get the data to sort a column, be it from cache, fresh (populating the
  15498. // cache), or from a sort formatter
  15499. function _fnSortData( settings, idx )
  15500. {
  15501. // Custom sorting function - provided by the sort data type
  15502. var column = settings.aoColumns[ idx ];
  15503. var customSort = DataTable.ext.order[ column.sSortDataType ];
  15504. var customData;
  15505. if ( customSort ) {
  15506. customData = customSort.call( settings.oInstance, settings, idx,
  15507. _fnColumnIndexToVisible( settings, idx )
  15508. );
  15509. }
  15510. // Use / populate cache
  15511. var row, cellData;
  15512. var formatter = DataTable.ext.type.order[ column.sType+"-pre" ];
  15513. for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
  15514. row = settings.aoData[i];
  15515. if ( ! row._aSortData ) {
  15516. row._aSortData = [];
  15517. }
  15518. if ( ! row._aSortData[idx] || customSort ) {
  15519. cellData = customSort ?
  15520. customData[i] : // If there was a custom sort function, use data from there
  15521. _fnGetCellData( settings, i, idx, 'sort' );
  15522. row._aSortData[ idx ] = formatter ?
  15523. formatter( cellData ) :
  15524. cellData;
  15525. }
  15526. }
  15527. }
  15528. /**
  15529. * Save the state of a table
  15530. * @param {object} oSettings dataTables settings object
  15531. * @memberof DataTable#oApi
  15532. */
  15533. function _fnSaveState ( settings )
  15534. {
  15535. if ( !settings.oFeatures.bStateSave || settings.bDestroying )
  15536. {
  15537. return;
  15538. }
  15539. /* Store the interesting variables */
  15540. var state = {
  15541. time: +new Date(),
  15542. start: settings._iDisplayStart,
  15543. length: settings._iDisplayLength,
  15544. order: $.extend( true, [], settings.aaSorting ),
  15545. search: _fnSearchToCamel( settings.oPreviousSearch ),
  15546. columns: $.map( settings.aoColumns, function ( col, i ) {
  15547. return {
  15548. visible: col.bVisible,
  15549. search: _fnSearchToCamel( settings.aoPreSearchCols[i] )
  15550. };
  15551. } )
  15552. };
  15553. _fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] );
  15554. settings.oSavedState = state;
  15555. settings.fnStateSaveCallback.call( settings.oInstance, settings, state );
  15556. }
  15557. /**
  15558. * Attempt to load a saved table state
  15559. * @param {object} oSettings dataTables settings object
  15560. * @param {object} oInit DataTables init object so we can override settings
  15561. * @param {function} callback Callback to execute when the state has been loaded
  15562. * @memberof DataTable#oApi
  15563. */
  15564. function _fnLoadState ( settings, oInit, callback )
  15565. {
  15566. var i, ien;
  15567. var columns = settings.aoColumns;
  15568. var loaded = function ( s ) {
  15569. if ( ! s || ! s.time ) {
  15570. callback();
  15571. return;
  15572. }
  15573. // Allow custom and plug-in manipulation functions to alter the saved data set and
  15574. // cancelling of loading by returning false
  15575. var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, s] );
  15576. if ( $.inArray( false, abStateLoad ) !== -1 ) {
  15577. callback();
  15578. return;
  15579. }
  15580. // Reject old data
  15581. var duration = settings.iStateDuration;
  15582. if ( duration > 0 && s.time < +new Date() - (duration*1000) ) {
  15583. callback();
  15584. return;
  15585. }
  15586. // Number of columns have changed - all bets are off, no restore of settings
  15587. if ( s.columns && columns.length !== s.columns.length ) {
  15588. callback();
  15589. return;
  15590. }
  15591. // Store the saved state so it might be accessed at any time
  15592. settings.oLoadedState = $.extend( true, {}, s );
  15593. // Restore key features - todo - for 1.11 this needs to be done by
  15594. // subscribed events
  15595. if ( s.start !== undefined ) {
  15596. settings._iDisplayStart = s.start;
  15597. settings.iInitDisplayStart = s.start;
  15598. }
  15599. if ( s.length !== undefined ) {
  15600. settings._iDisplayLength = s.length;
  15601. }
  15602. // Order
  15603. if ( s.order !== undefined ) {
  15604. settings.aaSorting = [];
  15605. $.each( s.order, function ( i, col ) {
  15606. settings.aaSorting.push( col[0] >= columns.length ?
  15607. [ 0, col[1] ] :
  15608. col
  15609. );
  15610. } );
  15611. }
  15612. // Search
  15613. if ( s.search !== undefined ) {
  15614. $.extend( settings.oPreviousSearch, _fnSearchToHung( s.search ) );
  15615. }
  15616. // Columns
  15617. //
  15618. if ( s.columns ) {
  15619. for ( i=0, ien=s.columns.length ; i<ien ; i++ ) {
  15620. var col = s.columns[i];
  15621. // Visibility
  15622. if ( col.visible !== undefined ) {
  15623. columns[i].bVisible = col.visible;
  15624. }
  15625. // Search
  15626. if ( col.search !== undefined ) {
  15627. $.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );
  15628. }
  15629. }
  15630. }
  15631. _fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, s] );
  15632. callback();
  15633. }
  15634. if ( ! settings.oFeatures.bStateSave ) {
  15635. callback();
  15636. return;
  15637. }
  15638. var state = settings.fnStateLoadCallback.call( settings.oInstance, settings, loaded );
  15639. if ( state !== undefined ) {
  15640. loaded( state );
  15641. }
  15642. // otherwise, wait for the loaded callback to be executed
  15643. }
  15644. /**
  15645. * Return the settings object for a particular table
  15646. * @param {node} table table we are using as a dataTable
  15647. * @returns {object} Settings object - or null if not found
  15648. * @memberof DataTable#oApi
  15649. */
  15650. function _fnSettingsFromNode ( table )
  15651. {
  15652. var settings = DataTable.settings;
  15653. var idx = $.inArray( table, _pluck( settings, 'nTable' ) );
  15654. return idx !== -1 ?
  15655. settings[ idx ] :
  15656. null;
  15657. }
  15658. /**
  15659. * Log an error message
  15660. * @param {object} settings dataTables settings object
  15661. * @param {int} level log error messages, or display them to the user
  15662. * @param {string} msg error message
  15663. * @param {int} tn Technical note id to get more information about the error.
  15664. * @memberof DataTable#oApi
  15665. */
  15666. function _fnLog( settings, level, msg, tn )
  15667. {
  15668. msg = 'DataTables warning: '+
  15669. (settings ? 'table id='+settings.sTableId+' - ' : '')+msg;
  15670. if ( tn ) {
  15671. msg += '. For more information about this error, please see '+
  15672. 'http://datatables.net/tn/'+tn;
  15673. }
  15674. if ( ! level ) {
  15675. // Backwards compatibility pre 1.10
  15676. var ext = DataTable.ext;
  15677. var type = ext.sErrMode || ext.errMode;
  15678. if ( settings ) {
  15679. _fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );
  15680. }
  15681. if ( type == 'alert' ) {
  15682. alert( msg );
  15683. }
  15684. else if ( type == 'throw' ) {
  15685. throw new Error(msg);
  15686. }
  15687. else if ( typeof type == 'function' ) {
  15688. type( settings, tn, msg );
  15689. }
  15690. }
  15691. else if ( window.console && console.log ) {
  15692. console.log( msg );
  15693. }
  15694. }
  15695. /**
  15696. * See if a property is defined on one object, if so assign it to the other object
  15697. * @param {object} ret target object
  15698. * @param {object} src source object
  15699. * @param {string} name property
  15700. * @param {string} [mappedName] name to map too - optional, name used if not given
  15701. * @memberof DataTable#oApi
  15702. */
  15703. function _fnMap( ret, src, name, mappedName )
  15704. {
  15705. if ( $.isArray( name ) ) {
  15706. $.each( name, function (i, val) {
  15707. if ( $.isArray( val ) ) {
  15708. _fnMap( ret, src, val[0], val[1] );
  15709. }
  15710. else {
  15711. _fnMap( ret, src, val );
  15712. }
  15713. } );
  15714. return;
  15715. }
  15716. if ( mappedName === undefined ) {
  15717. mappedName = name;
  15718. }
  15719. if ( src[name] !== undefined ) {
  15720. ret[mappedName] = src[name];
  15721. }
  15722. }
  15723. /**
  15724. * Extend objects - very similar to jQuery.extend, but deep copy objects, and
  15725. * shallow copy arrays. The reason we need to do this, is that we don't want to
  15726. * deep copy array init values (such as aaSorting) since the dev wouldn't be
  15727. * able to override them, but we do want to deep copy arrays.
  15728. * @param {object} out Object to extend
  15729. * @param {object} extender Object from which the properties will be applied to
  15730. * out
  15731. * @param {boolean} breakRefs If true, then arrays will be sliced to take an
  15732. * independent copy with the exception of the `data` or `aaData` parameters
  15733. * if they are present. This is so you can pass in a collection to
  15734. * DataTables and have that used as your data source without breaking the
  15735. * references
  15736. * @returns {object} out Reference, just for convenience - out === the return.
  15737. * @memberof DataTable#oApi
  15738. * @todo This doesn't take account of arrays inside the deep copied objects.
  15739. */
  15740. function _fnExtend( out, extender, breakRefs )
  15741. {
  15742. var val;
  15743. for ( var prop in extender ) {
  15744. if ( extender.hasOwnProperty(prop) ) {
  15745. val = extender[prop];
  15746. if ( $.isPlainObject( val ) ) {
  15747. if ( ! $.isPlainObject( out[prop] ) ) {
  15748. out[prop] = {};
  15749. }
  15750. $.extend( true, out[prop], val );
  15751. }
  15752. else if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {
  15753. out[prop] = val.slice();
  15754. }
  15755. else {
  15756. out[prop] = val;
  15757. }
  15758. }
  15759. }
  15760. return out;
  15761. }
  15762. /**
  15763. * Bind an event handers to allow a click or return key to activate the callback.
  15764. * This is good for accessibility since a return on the keyboard will have the
  15765. * same effect as a click, if the element has focus.
  15766. * @param {element} n Element to bind the action to
  15767. * @param {object} oData Data object to pass to the triggered function
  15768. * @param {function} fn Callback function for when the event is triggered
  15769. * @memberof DataTable#oApi
  15770. */
  15771. function _fnBindAction( n, oData, fn )
  15772. {
  15773. $(n)
  15774. .on( 'click.DT', oData, function (e) {
  15775. n.blur(); // Remove focus outline for mouse users
  15776. fn(e);
  15777. } )
  15778. .on( 'keypress.DT', oData, function (e){
  15779. if ( e.which === 13 ) {
  15780. e.preventDefault();
  15781. fn(e);
  15782. }
  15783. } )
  15784. .on( 'selectstart.DT', function () {
  15785. /* Take the brutal approach to cancelling text selection */
  15786. return false;
  15787. } );
  15788. }
  15789. /**
  15790. * Register a callback function. Easily allows a callback function to be added to
  15791. * an array store of callback functions that can then all be called together.
  15792. * @param {object} oSettings dataTables settings object
  15793. * @param {string} sStore Name of the array storage for the callbacks in oSettings
  15794. * @param {function} fn Function to be called back
  15795. * @param {string} sName Identifying name for the callback (i.e. a label)
  15796. * @memberof DataTable#oApi
  15797. */
  15798. function _fnCallbackReg( oSettings, sStore, fn, sName )
  15799. {
  15800. if ( fn )
  15801. {
  15802. oSettings[sStore].push( {
  15803. "fn": fn,
  15804. "sName": sName
  15805. } );
  15806. }
  15807. }
  15808. /**
  15809. * Fire callback functions and trigger events. Note that the loop over the
  15810. * callback array store is done backwards! Further note that you do not want to
  15811. * fire off triggers in time sensitive applications (for example cell creation)
  15812. * as its slow.
  15813. * @param {object} settings dataTables settings object
  15814. * @param {string} callbackArr Name of the array storage for the callbacks in
  15815. * oSettings
  15816. * @param {string} eventName Name of the jQuery custom event to trigger. If
  15817. * null no trigger is fired
  15818. * @param {array} args Array of arguments to pass to the callback function /
  15819. * trigger
  15820. * @memberof DataTable#oApi
  15821. */
  15822. function _fnCallbackFire( settings, callbackArr, eventName, args )
  15823. {
  15824. var ret = [];
  15825. if ( callbackArr ) {
  15826. ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {
  15827. return val.fn.apply( settings.oInstance, args );
  15828. } );
  15829. }
  15830. if ( eventName !== null ) {
  15831. var e = $.Event( eventName+'.dt' );
  15832. $(settings.nTable).trigger( e, args );
  15833. ret.push( e.result );
  15834. }
  15835. return ret;
  15836. }
  15837. function _fnLengthOverflow ( settings )
  15838. {
  15839. var
  15840. start = settings._iDisplayStart,
  15841. end = settings.fnDisplayEnd(),
  15842. len = settings._iDisplayLength;
  15843. /* If we have space to show extra rows (backing up from the end point - then do so */
  15844. if ( start >= end )
  15845. {
  15846. start = end - len;
  15847. }
  15848. // Keep the start record on the current page
  15849. start -= (start % len);
  15850. if ( len === -1 || start < 0 )
  15851. {
  15852. start = 0;
  15853. }
  15854. settings._iDisplayStart = start;
  15855. }
  15856. function _fnRenderer( settings, type )
  15857. {
  15858. var renderer = settings.renderer;
  15859. var host = DataTable.ext.renderer[type];
  15860. if ( $.isPlainObject( renderer ) && renderer[type] ) {
  15861. // Specific renderer for this type. If available use it, otherwise use
  15862. // the default.
  15863. return host[renderer[type]] || host._;
  15864. }
  15865. else if ( typeof renderer === 'string' ) {
  15866. // Common renderer - if there is one available for this type use it,
  15867. // otherwise use the default
  15868. return host[renderer] || host._;
  15869. }
  15870. // Use the default
  15871. return host._;
  15872. }
  15873. /**
  15874. * Detect the data source being used for the table. Used to simplify the code
  15875. * a little (ajax) and to make it compress a little smaller.
  15876. *
  15877. * @param {object} settings dataTables settings object
  15878. * @returns {string} Data source
  15879. * @memberof DataTable#oApi
  15880. */
  15881. function _fnDataSource ( settings )
  15882. {
  15883. if ( settings.oFeatures.bServerSide ) {
  15884. return 'ssp';
  15885. }
  15886. else if ( settings.ajax || settings.sAjaxSource ) {
  15887. return 'ajax';
  15888. }
  15889. return 'dom';
  15890. }
  15891. /**
  15892. * Computed structure of the DataTables API, defined by the options passed to
  15893. * `DataTable.Api.register()` when building the API.
  15894. *
  15895. * The structure is built in order to speed creation and extension of the Api
  15896. * objects since the extensions are effectively pre-parsed.
  15897. *
  15898. * The array is an array of objects with the following structure, where this
  15899. * base array represents the Api prototype base:
  15900. *
  15901. * [
  15902. * {
  15903. * name: 'data' -- string - Property name
  15904. * val: function () {}, -- function - Api method (or undefined if just an object
  15905. * methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
  15906. * propExt: [ ... ] -- array - Array of Api object definitions to extend the property
  15907. * },
  15908. * {
  15909. * name: 'row'
  15910. * val: {},
  15911. * methodExt: [ ... ],
  15912. * propExt: [
  15913. * {
  15914. * name: 'data'
  15915. * val: function () {},
  15916. * methodExt: [ ... ],
  15917. * propExt: [ ... ]
  15918. * },
  15919. * ...
  15920. * ]
  15921. * }
  15922. * ]
  15923. *
  15924. * @type {Array}
  15925. * @ignore
  15926. */
  15927. var __apiStruct = [];
  15928. /**
  15929. * `Array.prototype` reference.
  15930. *
  15931. * @type object
  15932. * @ignore
  15933. */
  15934. var __arrayProto = Array.prototype;
  15935. /**
  15936. * Abstraction for `context` parameter of the `Api` constructor to allow it to
  15937. * take several different forms for ease of use.
  15938. *
  15939. * Each of the input parameter types will be converted to a DataTables settings
  15940. * object where possible.
  15941. *
  15942. * @param {string|node|jQuery|object} mixed DataTable identifier. Can be one
  15943. * of:
  15944. *
  15945. * * `string` - jQuery selector. Any DataTables' matching the given selector
  15946. * with be found and used.
  15947. * * `node` - `TABLE` node which has already been formed into a DataTable.
  15948. * * `jQuery` - A jQuery object of `TABLE` nodes.
  15949. * * `object` - DataTables settings object
  15950. * * `DataTables.Api` - API instance
  15951. * @return {array|null} Matching DataTables settings objects. `null` or
  15952. * `undefined` is returned if no matching DataTable is found.
  15953. * @ignore
  15954. */
  15955. var _toSettings = function ( mixed )
  15956. {
  15957. var idx, jq;
  15958. var settings = DataTable.settings;
  15959. var tables = $.map( settings, function (el, i) {
  15960. return el.nTable;
  15961. } );
  15962. if ( ! mixed ) {
  15963. return [];
  15964. }
  15965. else if ( mixed.nTable && mixed.oApi ) {
  15966. // DataTables settings object
  15967. return [ mixed ];
  15968. }
  15969. else if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {
  15970. // Table node
  15971. idx = $.inArray( mixed, tables );
  15972. return idx !== -1 ? [ settings[idx] ] : null;
  15973. }
  15974. else if ( mixed && typeof mixed.settings === 'function' ) {
  15975. return mixed.settings().toArray();
  15976. }
  15977. else if ( typeof mixed === 'string' ) {
  15978. // jQuery selector
  15979. jq = $(mixed);
  15980. }
  15981. else if ( mixed instanceof $ ) {
  15982. // jQuery object (also DataTables instance)
  15983. jq = mixed;
  15984. }
  15985. if ( jq ) {
  15986. return jq.map( function(i) {
  15987. idx = $.inArray( this, tables );
  15988. return idx !== -1 ? settings[idx] : null;
  15989. } ).toArray();
  15990. }
  15991. };
  15992. /**
  15993. * DataTables API class - used to control and interface with one or more
  15994. * DataTables enhanced tables.
  15995. *
  15996. * The API class is heavily based on jQuery, presenting a chainable interface
  15997. * that you can use to interact with tables. Each instance of the API class has
  15998. * a "context" - i.e. the tables that it will operate on. This could be a single
  15999. * table, all tables on a page or a sub-set thereof.
  16000. *
  16001. * Additionally the API is designed to allow you to easily work with the data in
  16002. * the tables, retrieving and manipulating it as required. This is done by
  16003. * presenting the API class as an array like interface. The contents of the
  16004. * array depend upon the actions requested by each method (for example
  16005. * `rows().nodes()` will return an array of nodes, while `rows().data()` will
  16006. * return an array of objects or arrays depending upon your table's
  16007. * configuration). The API object has a number of array like methods (`push`,
  16008. * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,
  16009. * `unique` etc) to assist your working with the data held in a table.
  16010. *
  16011. * Most methods (those which return an Api instance) are chainable, which means
  16012. * the return from a method call also has all of the methods available that the
  16013. * top level object had. For example, these two calls are equivalent:
  16014. *
  16015. * // Not chained
  16016. * api.row.add( {...} );
  16017. * api.draw();
  16018. *
  16019. * // Chained
  16020. * api.row.add( {...} ).draw();
  16021. *
  16022. * @class DataTable.Api
  16023. * @param {array|object|string|jQuery} context DataTable identifier. This is
  16024. * used to define which DataTables enhanced tables this API will operate on.
  16025. * Can be one of:
  16026. *
  16027. * * `string` - jQuery selector. Any DataTables' matching the given selector
  16028. * with be found and used.
  16029. * * `node` - `TABLE` node which has already been formed into a DataTable.
  16030. * * `jQuery` - A jQuery object of `TABLE` nodes.
  16031. * * `object` - DataTables settings object
  16032. * @param {array} [data] Data to initialise the Api instance with.
  16033. *
  16034. * @example
  16035. * // Direct initialisation during DataTables construction
  16036. * var api = $('#example').DataTable();
  16037. *
  16038. * @example
  16039. * // Initialisation using a DataTables jQuery object
  16040. * var api = $('#example').dataTable().api();
  16041. *
  16042. * @example
  16043. * // Initialisation as a constructor
  16044. * var api = new $.fn.DataTable.Api( 'table.dataTable' );
  16045. */
  16046. _Api = function ( context, data )
  16047. {
  16048. if ( ! (this instanceof _Api) ) {
  16049. return new _Api( context, data );
  16050. }
  16051. var settings = [];
  16052. var ctxSettings = function ( o ) {
  16053. var a = _toSettings( o );
  16054. if ( a ) {
  16055. settings = settings.concat( a );
  16056. }
  16057. };
  16058. if ( $.isArray( context ) ) {
  16059. for ( var i=0, ien=context.length ; i<ien ; i++ ) {
  16060. ctxSettings( context[i] );
  16061. }
  16062. }
  16063. else {
  16064. ctxSettings( context );
  16065. }
  16066. // Remove duplicates
  16067. this.context = _unique( settings );
  16068. // Initial data
  16069. if ( data ) {
  16070. $.merge( this, data );
  16071. }
  16072. // selector
  16073. this.selector = {
  16074. rows: null,
  16075. cols: null,
  16076. opts: null
  16077. };
  16078. _Api.extend( this, this, __apiStruct );
  16079. };
  16080. DataTable.Api = _Api;
  16081. // Don't destroy the existing prototype, just extend it. Required for jQuery 2's
  16082. // isPlainObject.
  16083. $.extend( _Api.prototype, {
  16084. any: function ()
  16085. {
  16086. return this.count() !== 0;
  16087. },
  16088. concat: __arrayProto.concat,
  16089. context: [], // array of table settings objects
  16090. count: function ()
  16091. {
  16092. return this.flatten().length;
  16093. },
  16094. each: function ( fn )
  16095. {
  16096. for ( var i=0, ien=this.length ; i<ien; i++ ) {
  16097. fn.call( this, this[i], i, this );
  16098. }
  16099. return this;
  16100. },
  16101. eq: function ( idx )
  16102. {
  16103. var ctx = this.context;
  16104. return ctx.length > idx ?
  16105. new _Api( ctx[idx], this[idx] ) :
  16106. null;
  16107. },
  16108. filter: function ( fn )
  16109. {
  16110. var a = [];
  16111. if ( __arrayProto.filter ) {
  16112. a = __arrayProto.filter.call( this, fn, this );
  16113. }
  16114. else {
  16115. // Compatibility for browsers without EMCA-252-5 (JS 1.6)
  16116. for ( var i=0, ien=this.length ; i<ien ; i++ ) {
  16117. if ( fn.call( this, this[i], i, this ) ) {
  16118. a.push( this[i] );
  16119. }
  16120. }
  16121. }
  16122. return new _Api( this.context, a );
  16123. },
  16124. flatten: function ()
  16125. {
  16126. var a = [];
  16127. return new _Api( this.context, a.concat.apply( a, this.toArray() ) );
  16128. },
  16129. join: __arrayProto.join,
  16130. indexOf: __arrayProto.indexOf || function (obj, start)
  16131. {
  16132. for ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {
  16133. if ( this[i] === obj ) {
  16134. return i;
  16135. }
  16136. }
  16137. return -1;
  16138. },
  16139. iterator: function ( flatten, type, fn, alwaysNew ) {
  16140. var
  16141. a = [], ret,
  16142. i, ien, j, jen,
  16143. context = this.context,
  16144. rows, items, item,
  16145. selector = this.selector;
  16146. // Argument shifting
  16147. if ( typeof flatten === 'string' ) {
  16148. alwaysNew = fn;
  16149. fn = type;
  16150. type = flatten;
  16151. flatten = false;
  16152. }
  16153. for ( i=0, ien=context.length ; i<ien ; i++ ) {
  16154. var apiInst = new _Api( context[i] );
  16155. if ( type === 'table' ) {
  16156. ret = fn.call( apiInst, context[i], i );
  16157. if ( ret !== undefined ) {
  16158. a.push( ret );
  16159. }
  16160. }
  16161. else if ( type === 'columns' || type === 'rows' ) {
  16162. // this has same length as context - one entry for each table
  16163. ret = fn.call( apiInst, context[i], this[i], i );
  16164. if ( ret !== undefined ) {
  16165. a.push( ret );
  16166. }
  16167. }
  16168. else if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {
  16169. // columns and rows share the same structure.
  16170. // 'this' is an array of column indexes for each context
  16171. items = this[i];
  16172. if ( type === 'column-rows' ) {
  16173. rows = _selector_row_indexes( context[i], selector.opts );
  16174. }
  16175. for ( j=0, jen=items.length ; j<jen ; j++ ) {
  16176. item = items[j];
  16177. if ( type === 'cell' ) {
  16178. ret = fn.call( apiInst, context[i], item.row, item.column, i, j );
  16179. }
  16180. else {
  16181. ret = fn.call( apiInst, context[i], item, i, j, rows );
  16182. }
  16183. if ( ret !== undefined ) {
  16184. a.push( ret );
  16185. }
  16186. }
  16187. }
  16188. }
  16189. if ( a.length || alwaysNew ) {
  16190. var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );
  16191. var apiSelector = api.selector;
  16192. apiSelector.rows = selector.rows;
  16193. apiSelector.cols = selector.cols;
  16194. apiSelector.opts = selector.opts;
  16195. return api;
  16196. }
  16197. return this;
  16198. },
  16199. lastIndexOf: __arrayProto.lastIndexOf || function (obj, start)
  16200. {
  16201. // Bit cheeky...
  16202. return this.indexOf.apply( this.toArray.reverse(), arguments );
  16203. },
  16204. length: 0,
  16205. map: function ( fn )
  16206. {
  16207. var a = [];
  16208. if ( __arrayProto.map ) {
  16209. a = __arrayProto.map.call( this, fn, this );
  16210. }
  16211. else {
  16212. // Compatibility for browsers without EMCA-252-5 (JS 1.6)
  16213. for ( var i=0, ien=this.length ; i<ien ; i++ ) {
  16214. a.push( fn.call( this, this[i], i ) );
  16215. }
  16216. }
  16217. return new _Api( this.context, a );
  16218. },
  16219. pluck: function ( prop )
  16220. {
  16221. return this.map( function ( el ) {
  16222. return el[ prop ];
  16223. } );
  16224. },
  16225. pop: __arrayProto.pop,
  16226. push: __arrayProto.push,
  16227. // Does not return an API instance
  16228. reduce: __arrayProto.reduce || function ( fn, init )
  16229. {
  16230. return _fnReduce( this, fn, init, 0, this.length, 1 );
  16231. },
  16232. reduceRight: __arrayProto.reduceRight || function ( fn, init )
  16233. {
  16234. return _fnReduce( this, fn, init, this.length-1, -1, -1 );
  16235. },
  16236. reverse: __arrayProto.reverse,
  16237. // Object with rows, columns and opts
  16238. selector: null,
  16239. shift: __arrayProto.shift,
  16240. slice: function () {
  16241. return new _Api( this.context, this );
  16242. },
  16243. sort: __arrayProto.sort, // ? name - order?
  16244. splice: __arrayProto.splice,
  16245. toArray: function ()
  16246. {
  16247. return __arrayProto.slice.call( this );
  16248. },
  16249. to$: function ()
  16250. {
  16251. return $( this );
  16252. },
  16253. toJQuery: function ()
  16254. {
  16255. return $( this );
  16256. },
  16257. unique: function ()
  16258. {
  16259. return new _Api( this.context, _unique(this) );
  16260. },
  16261. unshift: __arrayProto.unshift
  16262. } );
  16263. _Api.extend = function ( scope, obj, ext )
  16264. {
  16265. // Only extend API instances and static properties of the API
  16266. if ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {
  16267. return;
  16268. }
  16269. var
  16270. i, ien,
  16271. j, jen,
  16272. struct, inner,
  16273. methodScoping = function ( scope, fn, struc ) {
  16274. return function () {
  16275. var ret = fn.apply( scope, arguments );
  16276. // Method extension
  16277. _Api.extend( ret, ret, struc.methodExt );
  16278. return ret;
  16279. };
  16280. };
  16281. for ( i=0, ien=ext.length ; i<ien ; i++ ) {
  16282. struct = ext[i];
  16283. // Value
  16284. obj[ struct.name ] = typeof struct.val === 'function' ?
  16285. methodScoping( scope, struct.val, struct ) :
  16286. $.isPlainObject( struct.val ) ?
  16287. {} :
  16288. struct.val;
  16289. obj[ struct.name ].__dt_wrapper = true;
  16290. // Property extension
  16291. _Api.extend( scope, obj[ struct.name ], struct.propExt );
  16292. }
  16293. };
  16294. // @todo - Is there need for an augment function?
  16295. // _Api.augment = function ( inst, name )
  16296. // {
  16297. // // Find src object in the structure from the name
  16298. // var parts = name.split('.');
  16299. // _Api.extend( inst, obj );
  16300. // };
  16301. // [
  16302. // {
  16303. // name: 'data' -- string - Property name
  16304. // val: function () {}, -- function - Api method (or undefined if just an object
  16305. // methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
  16306. // propExt: [ ... ] -- array - Array of Api object definitions to extend the property
  16307. // },
  16308. // {
  16309. // name: 'row'
  16310. // val: {},
  16311. // methodExt: [ ... ],
  16312. // propExt: [
  16313. // {
  16314. // name: 'data'
  16315. // val: function () {},
  16316. // methodExt: [ ... ],
  16317. // propExt: [ ... ]
  16318. // },
  16319. // ...
  16320. // ]
  16321. // }
  16322. // ]
  16323. _Api.register = _api_register = function ( name, val )
  16324. {
  16325. if ( $.isArray( name ) ) {
  16326. for ( var j=0, jen=name.length ; j<jen ; j++ ) {
  16327. _Api.register( name[j], val );
  16328. }
  16329. return;
  16330. }
  16331. var
  16332. i, ien,
  16333. heir = name.split('.'),
  16334. struct = __apiStruct,
  16335. key, method;
  16336. var find = function ( src, name ) {
  16337. for ( var i=0, ien=src.length ; i<ien ; i++ ) {
  16338. if ( src[i].name === name ) {
  16339. return src[i];
  16340. }
  16341. }
  16342. return null;
  16343. };
  16344. for ( i=0, ien=heir.length ; i<ien ; i++ ) {
  16345. method = heir[i].indexOf('()') !== -1;
  16346. key = method ?
  16347. heir[i].replace('()', '') :
  16348. heir[i];
  16349. var src = find( struct, key );
  16350. if ( ! src ) {
  16351. src = {
  16352. name: key,
  16353. val: {},
  16354. methodExt: [],
  16355. propExt: []
  16356. };
  16357. struct.push( src );
  16358. }
  16359. if ( i === ien-1 ) {
  16360. src.val = val;
  16361. }
  16362. else {
  16363. struct = method ?
  16364. src.methodExt :
  16365. src.propExt;
  16366. }
  16367. }
  16368. };
  16369. _Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {
  16370. _Api.register( pluralName, val );
  16371. _Api.register( singularName, function () {
  16372. var ret = val.apply( this, arguments );
  16373. if ( ret === this ) {
  16374. // Returned item is the API instance that was passed in, return it
  16375. return this;
  16376. }
  16377. else if ( ret instanceof _Api ) {
  16378. // New API instance returned, want the value from the first item
  16379. // in the returned array for the singular result.
  16380. return ret.length ?
  16381. $.isArray( ret[0] ) ?
  16382. new _Api( ret.context, ret[0] ) : // Array results are 'enhanced'
  16383. ret[0] :
  16384. undefined;
  16385. }
  16386. // Non-API return - just fire it back
  16387. return ret;
  16388. } );
  16389. };
  16390. /**
  16391. * Selector for HTML tables. Apply the given selector to the give array of
  16392. * DataTables settings objects.
  16393. *
  16394. * @param {string|integer} [selector] jQuery selector string or integer
  16395. * @param {array} Array of DataTables settings objects to be filtered
  16396. * @return {array}
  16397. * @ignore
  16398. */
  16399. var __table_selector = function ( selector, a )
  16400. {
  16401. // Integer is used to pick out a table by index
  16402. if ( typeof selector === 'number' ) {
  16403. return [ a[ selector ] ];
  16404. }
  16405. // Perform a jQuery selector on the table nodes
  16406. var nodes = $.map( a, function (el, i) {
  16407. return el.nTable;
  16408. } );
  16409. return $(nodes)
  16410. .filter( selector )
  16411. .map( function (i) {
  16412. // Need to translate back from the table node to the settings
  16413. var idx = $.inArray( this, nodes );
  16414. return a[ idx ];
  16415. } )
  16416. .toArray();
  16417. };
  16418. /**
  16419. * Context selector for the API's context (i.e. the tables the API instance
  16420. * refers to.
  16421. *
  16422. * @name DataTable.Api#tables
  16423. * @param {string|integer} [selector] Selector to pick which tables the iterator
  16424. * should operate on. If not given, all tables in the current context are
  16425. * used. This can be given as a jQuery selector (for example `':gt(0)'`) to
  16426. * select multiple tables or as an integer to select a single table.
  16427. * @returns {DataTable.Api} Returns a new API instance if a selector is given.
  16428. */
  16429. _api_register( 'tables()', function ( selector ) {
  16430. // A new instance is created if there was a selector specified
  16431. return selector ?
  16432. new _Api( __table_selector( selector, this.context ) ) :
  16433. this;
  16434. } );
  16435. _api_register( 'table()', function ( selector ) {
  16436. var tables = this.tables( selector );
  16437. var ctx = tables.context;
  16438. // Truncate to the first matched table
  16439. return ctx.length ?
  16440. new _Api( ctx[0] ) :
  16441. tables;
  16442. } );
  16443. _api_registerPlural( 'tables().nodes()', 'table().node()' , function () {
  16444. return this.iterator( 'table', function ( ctx ) {
  16445. return ctx.nTable;
  16446. }, 1 );
  16447. } );
  16448. _api_registerPlural( 'tables().body()', 'table().body()' , function () {
  16449. return this.iterator( 'table', function ( ctx ) {
  16450. return ctx.nTBody;
  16451. }, 1 );
  16452. } );
  16453. _api_registerPlural( 'tables().header()', 'table().header()' , function () {
  16454. return this.iterator( 'table', function ( ctx ) {
  16455. return ctx.nTHead;
  16456. }, 1 );
  16457. } );
  16458. _api_registerPlural( 'tables().footer()', 'table().footer()' , function () {
  16459. return this.iterator( 'table', function ( ctx ) {
  16460. return ctx.nTFoot;
  16461. }, 1 );
  16462. } );
  16463. _api_registerPlural( 'tables().containers()', 'table().container()' , function () {
  16464. return this.iterator( 'table', function ( ctx ) {
  16465. return ctx.nTableWrapper;
  16466. }, 1 );
  16467. } );
  16468. /**
  16469. * Redraw the tables in the current context.
  16470. */
  16471. _api_register( 'draw()', function ( paging ) {
  16472. return this.iterator( 'table', function ( settings ) {
  16473. if ( paging === 'page' ) {
  16474. _fnDraw( settings );
  16475. }
  16476. else {
  16477. if ( typeof paging === 'string' ) {
  16478. paging = paging === 'full-hold' ?
  16479. false :
  16480. true;
  16481. }
  16482. _fnReDraw( settings, paging===false );
  16483. }
  16484. } );
  16485. } );
  16486. /**
  16487. * Get the current page index.
  16488. *
  16489. * @return {integer} Current page index (zero based)
  16490. *//**
  16491. * Set the current page.
  16492. *
  16493. * Note that if you attempt to show a page which does not exist, DataTables will
  16494. * not throw an error, but rather reset the paging.
  16495. *
  16496. * @param {integer|string} action The paging action to take. This can be one of:
  16497. * * `integer` - The page index to jump to
  16498. * * `string` - An action to take:
  16499. * * `first` - Jump to first page.
  16500. * * `next` - Jump to the next page
  16501. * * `previous` - Jump to previous page
  16502. * * `last` - Jump to the last page.
  16503. * @returns {DataTables.Api} this
  16504. */
  16505. _api_register( 'page()', function ( action ) {
  16506. if ( action === undefined ) {
  16507. return this.page.info().page; // not an expensive call
  16508. }
  16509. // else, have an action to take on all tables
  16510. return this.iterator( 'table', function ( settings ) {
  16511. _fnPageChange( settings, action );
  16512. } );
  16513. } );
  16514. /**
  16515. * Paging information for the first table in the current context.
  16516. *
  16517. * If you require paging information for another table, use the `table()` method
  16518. * with a suitable selector.
  16519. *
  16520. * @return {object} Object with the following properties set:
  16521. * * `page` - Current page index (zero based - i.e. the first page is `0`)
  16522. * * `pages` - Total number of pages
  16523. * * `start` - Display index for the first record shown on the current page
  16524. * * `end` - Display index for the last record shown on the current page
  16525. * * `length` - Display length (number of records). Note that generally `start
  16526. * + length = end`, but this is not always true, for example if there are
  16527. * only 2 records to show on the final page, with a length of 10.
  16528. * * `recordsTotal` - Full data set length
  16529. * * `recordsDisplay` - Data set length once the current filtering criterion
  16530. * are applied.
  16531. */
  16532. _api_register( 'page.info()', function ( action ) {
  16533. if ( this.context.length === 0 ) {
  16534. return undefined;
  16535. }
  16536. var
  16537. settings = this.context[0],
  16538. start = settings._iDisplayStart,
  16539. len = settings.oFeatures.bPaginate ? settings._iDisplayLength : -1,
  16540. visRecords = settings.fnRecordsDisplay(),
  16541. all = len === -1;
  16542. return {
  16543. "page": all ? 0 : Math.floor( start / len ),
  16544. "pages": all ? 1 : Math.ceil( visRecords / len ),
  16545. "start": start,
  16546. "end": settings.fnDisplayEnd(),
  16547. "length": len,
  16548. "recordsTotal": settings.fnRecordsTotal(),
  16549. "recordsDisplay": visRecords,
  16550. "serverSide": _fnDataSource( settings ) === 'ssp'
  16551. };
  16552. } );
  16553. /**
  16554. * Get the current page length.
  16555. *
  16556. * @return {integer} Current page length. Note `-1` indicates that all records
  16557. * are to be shown.
  16558. *//**
  16559. * Set the current page length.
  16560. *
  16561. * @param {integer} Page length to set. Use `-1` to show all records.
  16562. * @returns {DataTables.Api} this
  16563. */
  16564. _api_register( 'page.len()', function ( len ) {
  16565. // Note that we can't call this function 'length()' because `length`
  16566. // is a Javascript property of functions which defines how many arguments
  16567. // the function expects.
  16568. if ( len === undefined ) {
  16569. return this.context.length !== 0 ?
  16570. this.context[0]._iDisplayLength :
  16571. undefined;
  16572. }
  16573. // else, set the page length
  16574. return this.iterator( 'table', function ( settings ) {
  16575. _fnLengthChange( settings, len );
  16576. } );
  16577. } );
  16578. var __reload = function ( settings, holdPosition, callback ) {
  16579. // Use the draw event to trigger a callback
  16580. if ( callback ) {
  16581. var api = new _Api( settings );
  16582. api.one( 'draw', function () {
  16583. callback( api.ajax.json() );
  16584. } );
  16585. }
  16586. if ( _fnDataSource( settings ) == 'ssp' ) {
  16587. _fnReDraw( settings, holdPosition );
  16588. }
  16589. else {
  16590. _fnProcessingDisplay( settings, true );
  16591. // Cancel an existing request
  16592. var xhr = settings.jqXHR;
  16593. if ( xhr && xhr.readyState !== 4 ) {
  16594. xhr.abort();
  16595. }
  16596. // Trigger xhr
  16597. _fnBuildAjax( settings, [], function( json ) {
  16598. _fnClearTable( settings );
  16599. var data = _fnAjaxDataSrc( settings, json );
  16600. for ( var i=0, ien=data.length ; i<ien ; i++ ) {
  16601. _fnAddData( settings, data[i] );
  16602. }
  16603. _fnReDraw( settings, holdPosition );
  16604. _fnProcessingDisplay( settings, false );
  16605. } );
  16606. }
  16607. };
  16608. /**
  16609. * Get the JSON response from the last Ajax request that DataTables made to the
  16610. * server. Note that this returns the JSON from the first table in the current
  16611. * context.
  16612. *
  16613. * @return {object} JSON received from the server.
  16614. */
  16615. _api_register( 'ajax.json()', function () {
  16616. var ctx = this.context;
  16617. if ( ctx.length > 0 ) {
  16618. return ctx[0].json;
  16619. }
  16620. // else return undefined;
  16621. } );
  16622. /**
  16623. * Get the data submitted in the last Ajax request
  16624. */
  16625. _api_register( 'ajax.params()', function () {
  16626. var ctx = this.context;
  16627. if ( ctx.length > 0 ) {
  16628. return ctx[0].oAjaxData;
  16629. }
  16630. // else return undefined;
  16631. } );
  16632. /**
  16633. * Reload tables from the Ajax data source. Note that this function will
  16634. * automatically re-draw the table when the remote data has been loaded.
  16635. *
  16636. * @param {boolean} [reset=true] Reset (default) or hold the current paging
  16637. * position. A full re-sort and re-filter is performed when this method is
  16638. * called, which is why the pagination reset is the default action.
  16639. * @returns {DataTables.Api} this
  16640. */
  16641. _api_register( 'ajax.reload()', function ( callback, resetPaging ) {
  16642. return this.iterator( 'table', function (settings) {
  16643. __reload( settings, resetPaging===false, callback );
  16644. } );
  16645. } );
  16646. /**
  16647. * Get the current Ajax URL. Note that this returns the URL from the first
  16648. * table in the current context.
  16649. *
  16650. * @return {string} Current Ajax source URL
  16651. *//**
  16652. * Set the Ajax URL. Note that this will set the URL for all tables in the
  16653. * current context.
  16654. *
  16655. * @param {string} url URL to set.
  16656. * @returns {DataTables.Api} this
  16657. */
  16658. _api_register( 'ajax.url()', function ( url ) {
  16659. var ctx = this.context;
  16660. if ( url === undefined ) {
  16661. // get
  16662. if ( ctx.length === 0 ) {
  16663. return undefined;
  16664. }
  16665. ctx = ctx[0];
  16666. return ctx.ajax ?
  16667. $.isPlainObject( ctx.ajax ) ?
  16668. ctx.ajax.url :
  16669. ctx.ajax :
  16670. ctx.sAjaxSource;
  16671. }
  16672. // set
  16673. return this.iterator( 'table', function ( settings ) {
  16674. if ( $.isPlainObject( settings.ajax ) ) {
  16675. settings.ajax.url = url;
  16676. }
  16677. else {
  16678. settings.ajax = url;
  16679. }
  16680. // No need to consider sAjaxSource here since DataTables gives priority
  16681. // to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any
  16682. // value of `sAjaxSource` redundant.
  16683. } );
  16684. } );
  16685. /**
  16686. * Load data from the newly set Ajax URL. Note that this method is only
  16687. * available when `ajax.url()` is used to set a URL. Additionally, this method
  16688. * has the same effect as calling `ajax.reload()` but is provided for
  16689. * convenience when setting a new URL. Like `ajax.reload()` it will
  16690. * automatically redraw the table once the remote data has been loaded.
  16691. *
  16692. * @returns {DataTables.Api} this
  16693. */
  16694. _api_register( 'ajax.url().load()', function ( callback, resetPaging ) {
  16695. // Same as a reload, but makes sense to present it for easy access after a
  16696. // url change
  16697. return this.iterator( 'table', function ( ctx ) {
  16698. __reload( ctx, resetPaging===false, callback );
  16699. } );
  16700. } );
  16701. var _selector_run = function ( type, selector, selectFn, settings, opts )
  16702. {
  16703. var
  16704. out = [], res,
  16705. a, i, ien, j, jen,
  16706. selectorType = typeof selector;
  16707. // Can't just check for isArray here, as an API or jQuery instance might be
  16708. // given with their array like look
  16709. if ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {
  16710. selector = [ selector ];
  16711. }
  16712. for ( i=0, ien=selector.length ; i<ien ; i++ ) {
  16713. // Only split on simple strings - complex expressions will be jQuery selectors
  16714. a = selector[i] && selector[i].split && ! selector[i].match(/[\[\(:]/) ?
  16715. selector[i].split(',') :
  16716. [ selector[i] ];
  16717. for ( j=0, jen=a.length ; j<jen ; j++ ) {
  16718. res = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );
  16719. if ( res && res.length ) {
  16720. out = out.concat( res );
  16721. }
  16722. }
  16723. }
  16724. // selector extensions
  16725. var ext = _ext.selector[ type ];
  16726. if ( ext.length ) {
  16727. for ( i=0, ien=ext.length ; i<ien ; i++ ) {
  16728. out = ext[i]( settings, opts, out );
  16729. }
  16730. }
  16731. return _unique( out );
  16732. };
  16733. var _selector_opts = function ( opts )
  16734. {
  16735. if ( ! opts ) {
  16736. opts = {};
  16737. }
  16738. // Backwards compatibility for 1.9- which used the terminology filter rather
  16739. // than search
  16740. if ( opts.filter && opts.search === undefined ) {
  16741. opts.search = opts.filter;
  16742. }
  16743. return $.extend( {
  16744. search: 'none',
  16745. order: 'current',
  16746. page: 'all'
  16747. }, opts );
  16748. };
  16749. var _selector_first = function ( inst )
  16750. {
  16751. // Reduce the API instance to the first item found
  16752. for ( var i=0, ien=inst.length ; i<ien ; i++ ) {
  16753. if ( inst[i].length > 0 ) {
  16754. // Assign the first element to the first item in the instance
  16755. // and truncate the instance and context
  16756. inst[0] = inst[i];
  16757. inst[0].length = 1;
  16758. inst.length = 1;
  16759. inst.context = [ inst.context[i] ];
  16760. return inst;
  16761. }
  16762. }
  16763. // Not found - return an empty instance
  16764. inst.length = 0;
  16765. return inst;
  16766. };
  16767. var _selector_row_indexes = function ( settings, opts )
  16768. {
  16769. var
  16770. i, ien, tmp, a=[],
  16771. displayFiltered = settings.aiDisplay,
  16772. displayMaster = settings.aiDisplayMaster;
  16773. var
  16774. search = opts.search, // none, applied, removed
  16775. order = opts.order, // applied, current, index (original - compatibility with 1.9)
  16776. page = opts.page; // all, current
  16777. if ( _fnDataSource( settings ) == 'ssp' ) {
  16778. // In server-side processing mode, most options are irrelevant since
  16779. // rows not shown don't exist and the index order is the applied order
  16780. // Removed is a special case - for consistency just return an empty
  16781. // array
  16782. return search === 'removed' ?
  16783. [] :
  16784. _range( 0, displayMaster.length );
  16785. }
  16786. else if ( page == 'current' ) {
  16787. // Current page implies that order=current and fitler=applied, since it is
  16788. // fairly senseless otherwise, regardless of what order and search actually
  16789. // are
  16790. for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
  16791. a.push( displayFiltered[i] );
  16792. }
  16793. }
  16794. else if ( order == 'current' || order == 'applied' ) {
  16795. a = search == 'none' ?
  16796. displayMaster.slice() : // no search
  16797. search == 'applied' ?
  16798. displayFiltered.slice() : // applied search
  16799. $.map( displayMaster, function (el, i) { // removed search
  16800. return $.inArray( el, displayFiltered ) === -1 ? el : null;
  16801. } );
  16802. }
  16803. else if ( order == 'index' || order == 'original' ) {
  16804. for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
  16805. if ( search == 'none' ) {
  16806. a.push( i );
  16807. }
  16808. else { // applied | removed
  16809. tmp = $.inArray( i, displayFiltered );
  16810. if ((tmp === -1 && search == 'removed') ||
  16811. (tmp >= 0 && search == 'applied') )
  16812. {
  16813. a.push( i );
  16814. }
  16815. }
  16816. }
  16817. }
  16818. return a;
  16819. };
  16820. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  16821. * Rows
  16822. *
  16823. * {} - no selector - use all available rows
  16824. * {integer} - row aoData index
  16825. * {node} - TR node
  16826. * {string} - jQuery selector to apply to the TR elements
  16827. * {array} - jQuery array of nodes, or simply an array of TR nodes
  16828. *
  16829. */
  16830. var __row_selector = function ( settings, selector, opts )
  16831. {
  16832. var rows;
  16833. var run = function ( sel ) {
  16834. var selInt = _intVal( sel );
  16835. var i, ien;
  16836. // Short cut - selector is a number and no options provided (default is
  16837. // all records, so no need to check if the index is in there, since it
  16838. // must be - dev error if the index doesn't exist).
  16839. if ( selInt !== null && ! opts ) {
  16840. return [ selInt ];
  16841. }
  16842. if ( ! rows ) {
  16843. rows = _selector_row_indexes( settings, opts );
  16844. }
  16845. if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {
  16846. // Selector - integer
  16847. return [ selInt ];
  16848. }
  16849. else if ( sel === null || sel === undefined || sel === '' ) {
  16850. // Selector - none
  16851. return rows;
  16852. }
  16853. // Selector - function
  16854. if ( typeof sel === 'function' ) {
  16855. return $.map( rows, function (idx) {
  16856. var row = settings.aoData[ idx ];
  16857. return sel( idx, row._aData, row.nTr ) ? idx : null;
  16858. } );
  16859. }
  16860. // Get nodes in the order from the `rows` array with null values removed
  16861. var nodes = _removeEmpty(
  16862. _pluck_order( settings.aoData, rows, 'nTr' )
  16863. );
  16864. // Selector - node
  16865. if ( sel.nodeName ) {
  16866. if ( sel._DT_RowIndex !== undefined ) {
  16867. return [ sel._DT_RowIndex ]; // Property added by DT for fast lookup
  16868. }
  16869. else if ( sel._DT_CellIndex ) {
  16870. return [ sel._DT_CellIndex.row ];
  16871. }
  16872. else {
  16873. var host = $(sel).closest('*[data-dt-row]');
  16874. return host.length ?
  16875. [ host.data('dt-row') ] :
  16876. [];
  16877. }
  16878. }
  16879. // ID selector. Want to always be able to select rows by id, regardless
  16880. // of if the tr element has been created or not, so can't rely upon
  16881. // jQuery here - hence a custom implementation. This does not match
  16882. // Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,
  16883. // but to select it using a CSS selector engine (like Sizzle or
  16884. // querySelect) it would need to need to be escaped for some characters.
  16885. // DataTables simplifies this for row selectors since you can select
  16886. // only a row. A # indicates an id any anything that follows is the id -
  16887. // unescaped.
  16888. if ( typeof sel === 'string' && sel.charAt(0) === '#' ) {
  16889. // get row index from id
  16890. var rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];
  16891. if ( rowObj !== undefined ) {
  16892. return [ rowObj.idx ];
  16893. }
  16894. // need to fall through to jQuery in case there is DOM id that
  16895. // matches
  16896. }
  16897. // Selector - jQuery selector string, array of nodes or jQuery object/
  16898. // As jQuery's .filter() allows jQuery objects to be passed in filter,
  16899. // it also allows arrays, so this will cope with all three options
  16900. return $(nodes)
  16901. .filter( sel )
  16902. .map( function () {
  16903. return this._DT_RowIndex;
  16904. } )
  16905. .toArray();
  16906. };
  16907. return _selector_run( 'row', selector, run, settings, opts );
  16908. };
  16909. _api_register( 'rows()', function ( selector, opts ) {
  16910. // argument shifting
  16911. if ( selector === undefined ) {
  16912. selector = '';
  16913. }
  16914. else if ( $.isPlainObject( selector ) ) {
  16915. opts = selector;
  16916. selector = '';
  16917. }
  16918. opts = _selector_opts( opts );
  16919. var inst = this.iterator( 'table', function ( settings ) {
  16920. return __row_selector( settings, selector, opts );
  16921. }, 1 );
  16922. // Want argument shifting here and in __row_selector?
  16923. inst.selector.rows = selector;
  16924. inst.selector.opts = opts;
  16925. return inst;
  16926. } );
  16927. _api_register( 'rows().nodes()', function () {
  16928. return this.iterator( 'row', function ( settings, row ) {
  16929. return settings.aoData[ row ].nTr || undefined;
  16930. }, 1 );
  16931. } );
  16932. _api_register( 'rows().data()', function () {
  16933. return this.iterator( true, 'rows', function ( settings, rows ) {
  16934. return _pluck_order( settings.aoData, rows, '_aData' );
  16935. }, 1 );
  16936. } );
  16937. _api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {
  16938. return this.iterator( 'row', function ( settings, row ) {
  16939. var r = settings.aoData[ row ];
  16940. return type === 'search' ? r._aFilterData : r._aSortData;
  16941. }, 1 );
  16942. } );
  16943. _api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {
  16944. return this.iterator( 'row', function ( settings, row ) {
  16945. _fnInvalidate( settings, row, src );
  16946. } );
  16947. } );
  16948. _api_registerPlural( 'rows().indexes()', 'row().index()', function () {
  16949. return this.iterator( 'row', function ( settings, row ) {
  16950. return row;
  16951. }, 1 );
  16952. } );
  16953. _api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {
  16954. var a = [];
  16955. var context = this.context;
  16956. // `iterator` will drop undefined values, but in this case we want them
  16957. for ( var i=0, ien=context.length ; i<ien ; i++ ) {
  16958. for ( var j=0, jen=this[i].length ; j<jen ; j++ ) {
  16959. var id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );
  16960. a.push( (hash === true ? '#' : '' )+ id );
  16961. }
  16962. }
  16963. return new _Api( context, a );
  16964. } );
  16965. _api_registerPlural( 'rows().remove()', 'row().remove()', function () {
  16966. var that = this;
  16967. this.iterator( 'row', function ( settings, row, thatIdx ) {
  16968. var data = settings.aoData;
  16969. var rowData = data[ row ];
  16970. var i, ien, j, jen;
  16971. var loopRow, loopCells;
  16972. data.splice( row, 1 );
  16973. // Update the cached indexes
  16974. for ( i=0, ien=data.length ; i<ien ; i++ ) {
  16975. loopRow = data[i];
  16976. loopCells = loopRow.anCells;
  16977. // Rows
  16978. if ( loopRow.nTr !== null ) {
  16979. loopRow.nTr._DT_RowIndex = i;
  16980. }
  16981. // Cells
  16982. if ( loopCells !== null ) {
  16983. for ( j=0, jen=loopCells.length ; j<jen ; j++ ) {
  16984. loopCells[j]._DT_CellIndex.row = i;
  16985. }
  16986. }
  16987. }
  16988. // Delete from the display arrays
  16989. _fnDeleteIndex( settings.aiDisplayMaster, row );
  16990. _fnDeleteIndex( settings.aiDisplay, row );
  16991. _fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes
  16992. // Check for an 'overflow' they case for displaying the table
  16993. _fnLengthOverflow( settings );
  16994. // Remove the row's ID reference if there is one
  16995. var id = settings.rowIdFn( rowData._aData );
  16996. if ( id !== undefined ) {
  16997. delete settings.aIds[ id ];
  16998. }
  16999. } );
  17000. this.iterator( 'table', function ( settings ) {
  17001. for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
  17002. settings.aoData[i].idx = i;
  17003. }
  17004. } );
  17005. return this;
  17006. } );
  17007. _api_register( 'rows.add()', function ( rows ) {
  17008. var newRows = this.iterator( 'table', function ( settings ) {
  17009. var row, i, ien;
  17010. var out = [];
  17011. for ( i=0, ien=rows.length ; i<ien ; i++ ) {
  17012. row = rows[i];
  17013. if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
  17014. out.push( _fnAddTr( settings, row )[0] );
  17015. }
  17016. else {
  17017. out.push( _fnAddData( settings, row ) );
  17018. }
  17019. }
  17020. return out;
  17021. }, 1 );
  17022. // Return an Api.rows() extended instance, so rows().nodes() etc can be used
  17023. var modRows = this.rows( -1 );
  17024. modRows.pop();
  17025. $.merge( modRows, newRows );
  17026. return modRows;
  17027. } );
  17028. /**
  17029. *
  17030. */
  17031. _api_register( 'row()', function ( selector, opts ) {
  17032. return _selector_first( this.rows( selector, opts ) );
  17033. } );
  17034. _api_register( 'row().data()', function ( data ) {
  17035. var ctx = this.context;
  17036. if ( data === undefined ) {
  17037. // Get
  17038. return ctx.length && this.length ?
  17039. ctx[0].aoData[ this[0] ]._aData :
  17040. undefined;
  17041. }
  17042. // Set
  17043. ctx[0].aoData[ this[0] ]._aData = data;
  17044. // Automatically invalidate
  17045. _fnInvalidate( ctx[0], this[0], 'data' );
  17046. return this;
  17047. } );
  17048. _api_register( 'row().node()', function () {
  17049. var ctx = this.context;
  17050. return ctx.length && this.length ?
  17051. ctx[0].aoData[ this[0] ].nTr || null :
  17052. null;
  17053. } );
  17054. _api_register( 'row.add()', function ( row ) {
  17055. // Allow a jQuery object to be passed in - only a single row is added from
  17056. // it though - the first element in the set
  17057. if ( row instanceof $ && row.length ) {
  17058. row = row[0];
  17059. }
  17060. var rows = this.iterator( 'table', function ( settings ) {
  17061. if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
  17062. return _fnAddTr( settings, row )[0];
  17063. }
  17064. return _fnAddData( settings, row );
  17065. } );
  17066. // Return an Api.rows() extended instance, with the newly added row selected
  17067. return this.row( rows[0] );
  17068. } );
  17069. var __details_add = function ( ctx, row, data, klass )
  17070. {
  17071. // Convert to array of TR elements
  17072. var rows = [];
  17073. var addRow = function ( r, k ) {
  17074. // Recursion to allow for arrays of jQuery objects
  17075. if ( $.isArray( r ) || r instanceof $ ) {
  17076. for ( var i=0, ien=r.length ; i<ien ; i++ ) {
  17077. addRow( r[i], k );
  17078. }
  17079. return;
  17080. }
  17081. // If we get a TR element, then just add it directly - up to the dev
  17082. // to add the correct number of columns etc
  17083. if ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {
  17084. rows.push( r );
  17085. }
  17086. else {
  17087. // Otherwise create a row with a wrapper
  17088. var created = $('<tr><td/></tr>').addClass( k );
  17089. $('td', created)
  17090. .addClass( k )
  17091. .html( r )
  17092. [0].colSpan = _fnVisbleColumns( ctx );
  17093. rows.push( created[0] );
  17094. }
  17095. };
  17096. addRow( data, klass );
  17097. if ( row._details ) {
  17098. row._details.detach();
  17099. }
  17100. row._details = $(rows);
  17101. // If the children were already shown, that state should be retained
  17102. if ( row._detailsShow ) {
  17103. row._details.insertAfter( row.nTr );
  17104. }
  17105. };
  17106. var __details_remove = function ( api, idx )
  17107. {
  17108. var ctx = api.context;
  17109. if ( ctx.length ) {
  17110. var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];
  17111. if ( row && row._details ) {
  17112. row._details.remove();
  17113. row._detailsShow = undefined;
  17114. row._details = undefined;
  17115. }
  17116. }
  17117. };
  17118. var __details_display = function ( api, show ) {
  17119. var ctx = api.context;
  17120. if ( ctx.length && api.length ) {
  17121. var row = ctx[0].aoData[ api[0] ];
  17122. if ( row._details ) {
  17123. row._detailsShow = show;
  17124. if ( show ) {
  17125. row._details.insertAfter( row.nTr );
  17126. }
  17127. else {
  17128. row._details.detach();
  17129. }
  17130. __details_events( ctx[0] );
  17131. }
  17132. }
  17133. };
  17134. var __details_events = function ( settings )
  17135. {
  17136. var api = new _Api( settings );
  17137. var namespace = '.dt.DT_details';
  17138. var drawEvent = 'draw'+namespace;
  17139. var colvisEvent = 'column-visibility'+namespace;
  17140. var destroyEvent = 'destroy'+namespace;
  17141. var data = settings.aoData;
  17142. api.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );
  17143. if ( _pluck( data, '_details' ).length > 0 ) {
  17144. // On each draw, insert the required elements into the document
  17145. api.on( drawEvent, function ( e, ctx ) {
  17146. if ( settings !== ctx ) {
  17147. return;
  17148. }
  17149. api.rows( {page:'current'} ).eq(0).each( function (idx) {
  17150. // Internal data grab
  17151. var row = data[ idx ];
  17152. if ( row._detailsShow ) {
  17153. row._details.insertAfter( row.nTr );
  17154. }
  17155. } );
  17156. } );
  17157. // Column visibility change - update the colspan
  17158. api.on( colvisEvent, function ( e, ctx, idx, vis ) {
  17159. if ( settings !== ctx ) {
  17160. return;
  17161. }
  17162. // Update the colspan for the details rows (note, only if it already has
  17163. // a colspan)
  17164. var row, visible = _fnVisbleColumns( ctx );
  17165. for ( var i=0, ien=data.length ; i<ien ; i++ ) {
  17166. row = data[i];
  17167. if ( row._details ) {
  17168. row._details.children('td[colspan]').attr('colspan', visible );
  17169. }
  17170. }
  17171. } );
  17172. // Table destroyed - nuke any child rows
  17173. api.on( destroyEvent, function ( e, ctx ) {
  17174. if ( settings !== ctx ) {
  17175. return;
  17176. }
  17177. for ( var i=0, ien=data.length ; i<ien ; i++ ) {
  17178. if ( data[i]._details ) {
  17179. __details_remove( api, i );
  17180. }
  17181. }
  17182. } );
  17183. }
  17184. };
  17185. // Strings for the method names to help minification
  17186. var _emp = '';
  17187. var _child_obj = _emp+'row().child';
  17188. var _child_mth = _child_obj+'()';
  17189. // data can be:
  17190. // tr
  17191. // string
  17192. // jQuery or array of any of the above
  17193. _api_register( _child_mth, function ( data, klass ) {
  17194. var ctx = this.context;
  17195. if ( data === undefined ) {
  17196. // get
  17197. return ctx.length && this.length ?
  17198. ctx[0].aoData[ this[0] ]._details :
  17199. undefined;
  17200. }
  17201. else if ( data === true ) {
  17202. // show
  17203. this.child.show();
  17204. }
  17205. else if ( data === false ) {
  17206. // remove
  17207. __details_remove( this );
  17208. }
  17209. else if ( ctx.length && this.length ) {
  17210. // set
  17211. __details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );
  17212. }
  17213. return this;
  17214. } );
  17215. _api_register( [
  17216. _child_obj+'.show()',
  17217. _child_mth+'.show()' // only when `child()` was called with parameters (without
  17218. ], function ( show ) { // it returns an object and this method is not executed)
  17219. __details_display( this, true );
  17220. return this;
  17221. } );
  17222. _api_register( [
  17223. _child_obj+'.hide()',
  17224. _child_mth+'.hide()' // only when `child()` was called with parameters (without
  17225. ], function () { // it returns an object and this method is not executed)
  17226. __details_display( this, false );
  17227. return this;
  17228. } );
  17229. _api_register( [
  17230. _child_obj+'.remove()',
  17231. _child_mth+'.remove()' // only when `child()` was called with parameters (without
  17232. ], function () { // it returns an object and this method is not executed)
  17233. __details_remove( this );
  17234. return this;
  17235. } );
  17236. _api_register( _child_obj+'.isShown()', function () {
  17237. var ctx = this.context;
  17238. if ( ctx.length && this.length ) {
  17239. // _detailsShown as false or undefined will fall through to return false
  17240. return ctx[0].aoData[ this[0] ]._detailsShow || false;
  17241. }
  17242. return false;
  17243. } );
  17244. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  17245. * Columns
  17246. *
  17247. * {integer} - column index (>=0 count from left, <0 count from right)
  17248. * "{integer}:visIdx" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right)
  17249. * "{integer}:visible" - alias for {integer}:visIdx (>=0 count from left, <0 count from right)
  17250. * "{string}:name" - column name
  17251. * "{string}" - jQuery selector on column header nodes
  17252. *
  17253. */
  17254. // can be an array of these items, comma separated list, or an array of comma
  17255. // separated lists
  17256. var __re_column_selector = /^([^:]+):(name|visIdx|visible)$/;
  17257. // r1 and r2 are redundant - but it means that the parameters match for the
  17258. // iterator callback in columns().data()
  17259. var __columnData = function ( settings, column, r1, r2, rows ) {
  17260. var a = [];
  17261. for ( var row=0, ien=rows.length ; row<ien ; row++ ) {
  17262. a.push( _fnGetCellData( settings, rows[row], column ) );
  17263. }
  17264. return a;
  17265. };
  17266. var __column_selector = function ( settings, selector, opts )
  17267. {
  17268. var
  17269. columns = settings.aoColumns,
  17270. names = _pluck( columns, 'sName' ),
  17271. nodes = _pluck( columns, 'nTh' );
  17272. var run = function ( s ) {
  17273. var selInt = _intVal( s );
  17274. // Selector - all
  17275. if ( s === '' ) {
  17276. return _range( columns.length );
  17277. }
  17278. // Selector - index
  17279. if ( selInt !== null ) {
  17280. return [ selInt >= 0 ?
  17281. selInt : // Count from left
  17282. columns.length + selInt // Count from right (+ because its a negative value)
  17283. ];
  17284. }
  17285. // Selector = function
  17286. if ( typeof s === 'function' ) {
  17287. var rows = _selector_row_indexes( settings, opts );
  17288. return $.map( columns, function (col, idx) {
  17289. return s(
  17290. idx,
  17291. __columnData( settings, idx, 0, 0, rows ),
  17292. nodes[ idx ]
  17293. ) ? idx : null;
  17294. } );
  17295. }
  17296. // jQuery or string selector
  17297. var match = typeof s === 'string' ?
  17298. s.match( __re_column_selector ) :
  17299. '';
  17300. if ( match ) {
  17301. switch( match[2] ) {
  17302. case 'visIdx':
  17303. case 'visible':
  17304. var idx = parseInt( match[1], 10 );
  17305. // Visible index given, convert to column index
  17306. if ( idx < 0 ) {
  17307. // Counting from the right
  17308. var visColumns = $.map( columns, function (col,i) {
  17309. return col.bVisible ? i : null;
  17310. } );
  17311. return [ visColumns[ visColumns.length + idx ] ];
  17312. }
  17313. // Counting from the left
  17314. return [ _fnVisibleToColumnIndex( settings, idx ) ];
  17315. case 'name':
  17316. // match by name. `names` is column index complete and in order
  17317. return $.map( names, function (name, i) {
  17318. return name === match[1] ? i : null;
  17319. } );
  17320. default:
  17321. return [];
  17322. }
  17323. }
  17324. // Cell in the table body
  17325. if ( s.nodeName && s._DT_CellIndex ) {
  17326. return [ s._DT_CellIndex.column ];
  17327. }
  17328. // jQuery selector on the TH elements for the columns
  17329. var jqResult = $( nodes )
  17330. .filter( s )
  17331. .map( function () {
  17332. return $.inArray( this, nodes ); // `nodes` is column index complete and in order
  17333. } )
  17334. .toArray();
  17335. if ( jqResult.length || ! s.nodeName ) {
  17336. return jqResult;
  17337. }
  17338. // Otherwise a node which might have a `dt-column` data attribute, or be
  17339. // a child or such an element
  17340. var host = $(s).closest('*[data-dt-column]');
  17341. return host.length ?
  17342. [ host.data('dt-column') ] :
  17343. [];
  17344. };
  17345. return _selector_run( 'column', selector, run, settings, opts );
  17346. };
  17347. var __setColumnVis = function ( settings, column, vis ) {
  17348. var
  17349. cols = settings.aoColumns,
  17350. col = cols[ column ],
  17351. data = settings.aoData,
  17352. row, cells, i, ien, tr;
  17353. // Get
  17354. if ( vis === undefined ) {
  17355. return col.bVisible;
  17356. }
  17357. // Set
  17358. // No change
  17359. if ( col.bVisible === vis ) {
  17360. return;
  17361. }
  17362. if ( vis ) {
  17363. // Insert column
  17364. // Need to decide if we should use appendChild or insertBefore
  17365. var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );
  17366. for ( i=0, ien=data.length ; i<ien ; i++ ) {
  17367. tr = data[i].nTr;
  17368. cells = data[i].anCells;
  17369. if ( tr ) {
  17370. // insertBefore can act like appendChild if 2nd arg is null
  17371. tr.insertBefore( cells[ column ], cells[ insertBefore ] || null );
  17372. }
  17373. }
  17374. }
  17375. else {
  17376. // Remove column
  17377. $( _pluck( settings.aoData, 'anCells', column ) ).detach();
  17378. }
  17379. // Common actions
  17380. col.bVisible = vis;
  17381. _fnDrawHead( settings, settings.aoHeader );
  17382. _fnDrawHead( settings, settings.aoFooter );
  17383. _fnSaveState( settings );
  17384. };
  17385. _api_register( 'columns()', function ( selector, opts ) {
  17386. // argument shifting
  17387. if ( selector === undefined ) {
  17388. selector = '';
  17389. }
  17390. else if ( $.isPlainObject( selector ) ) {
  17391. opts = selector;
  17392. selector = '';
  17393. }
  17394. opts = _selector_opts( opts );
  17395. var inst = this.iterator( 'table', function ( settings ) {
  17396. return __column_selector( settings, selector, opts );
  17397. }, 1 );
  17398. // Want argument shifting here and in _row_selector?
  17399. inst.selector.cols = selector;
  17400. inst.selector.opts = opts;
  17401. return inst;
  17402. } );
  17403. _api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {
  17404. return this.iterator( 'column', function ( settings, column ) {
  17405. return settings.aoColumns[column].nTh;
  17406. }, 1 );
  17407. } );
  17408. _api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {
  17409. return this.iterator( 'column', function ( settings, column ) {
  17410. return settings.aoColumns[column].nTf;
  17411. }, 1 );
  17412. } );
  17413. _api_registerPlural( 'columns().data()', 'column().data()', function () {
  17414. return this.iterator( 'column-rows', __columnData, 1 );
  17415. } );
  17416. _api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {
  17417. return this.iterator( 'column', function ( settings, column ) {
  17418. return settings.aoColumns[column].mData;
  17419. }, 1 );
  17420. } );
  17421. _api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {
  17422. return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
  17423. return _pluck_order( settings.aoData, rows,
  17424. type === 'search' ? '_aFilterData' : '_aSortData', column
  17425. );
  17426. }, 1 );
  17427. } );
  17428. _api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {
  17429. return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
  17430. return _pluck_order( settings.aoData, rows, 'anCells', column ) ;
  17431. }, 1 );
  17432. } );
  17433. _api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {
  17434. var ret = this.iterator( 'column', function ( settings, column ) {
  17435. if ( vis === undefined ) {
  17436. return settings.aoColumns[ column ].bVisible;
  17437. } // else
  17438. __setColumnVis( settings, column, vis );
  17439. } );
  17440. // Group the column visibility changes
  17441. if ( vis !== undefined ) {
  17442. // Second loop once the first is done for events
  17443. this.iterator( 'column', function ( settings, column ) {
  17444. _fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );
  17445. } );
  17446. if ( calc === undefined || calc ) {
  17447. this.columns.adjust();
  17448. }
  17449. }
  17450. return ret;
  17451. } );
  17452. _api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {
  17453. return this.iterator( 'column', function ( settings, column ) {
  17454. return type === 'visible' ?
  17455. _fnColumnIndexToVisible( settings, column ) :
  17456. column;
  17457. }, 1 );
  17458. } );
  17459. _api_register( 'columns.adjust()', function () {
  17460. return this.iterator( 'table', function ( settings ) {
  17461. _fnAdjustColumnSizing( settings );
  17462. }, 1 );
  17463. } );
  17464. _api_register( 'column.index()', function ( type, idx ) {
  17465. if ( this.context.length !== 0 ) {
  17466. var ctx = this.context[0];
  17467. if ( type === 'fromVisible' || type === 'toData' ) {
  17468. return _fnVisibleToColumnIndex( ctx, idx );
  17469. }
  17470. else if ( type === 'fromData' || type === 'toVisible' ) {
  17471. return _fnColumnIndexToVisible( ctx, idx );
  17472. }
  17473. }
  17474. } );
  17475. _api_register( 'column()', function ( selector, opts ) {
  17476. return _selector_first( this.columns( selector, opts ) );
  17477. } );
  17478. var __cell_selector = function ( settings, selector, opts )
  17479. {
  17480. var data = settings.aoData;
  17481. var rows = _selector_row_indexes( settings, opts );
  17482. var cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );
  17483. var allCells = $( [].concat.apply([], cells) );
  17484. var row;
  17485. var columns = settings.aoColumns.length;
  17486. var a, i, ien, j, o, host;
  17487. var run = function ( s ) {
  17488. var fnSelector = typeof s === 'function';
  17489. if ( s === null || s === undefined || fnSelector ) {
  17490. // All cells and function selectors
  17491. a = [];
  17492. for ( i=0, ien=rows.length ; i<ien ; i++ ) {
  17493. row = rows[i];
  17494. for ( j=0 ; j<columns ; j++ ) {
  17495. o = {
  17496. row: row,
  17497. column: j
  17498. };
  17499. if ( fnSelector ) {
  17500. // Selector - function
  17501. host = data[ row ];
  17502. if ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {
  17503. a.push( o );
  17504. }
  17505. }
  17506. else {
  17507. // Selector - all
  17508. a.push( o );
  17509. }
  17510. }
  17511. }
  17512. return a;
  17513. }
  17514. // Selector - index
  17515. if ( $.isPlainObject( s ) ) {
  17516. return [s];
  17517. }
  17518. // Selector - jQuery filtered cells
  17519. var jqResult = allCells
  17520. .filter( s )
  17521. .map( function (i, el) {
  17522. return { // use a new object, in case someone changes the values
  17523. row: el._DT_CellIndex.row,
  17524. column: el._DT_CellIndex.column
  17525. };
  17526. } )
  17527. .toArray();
  17528. if ( jqResult.length || ! s.nodeName ) {
  17529. return jqResult;
  17530. }
  17531. // Otherwise the selector is a node, and there is one last option - the
  17532. // element might be a child of an element which has dt-row and dt-column
  17533. // data attributes
  17534. host = $(s).closest('*[data-dt-row]');
  17535. return host.length ?
  17536. [ {
  17537. row: host.data('dt-row'),
  17538. column: host.data('dt-column')
  17539. } ] :
  17540. [];
  17541. };
  17542. return _selector_run( 'cell', selector, run, settings, opts );
  17543. };
  17544. _api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {
  17545. // Argument shifting
  17546. if ( $.isPlainObject( rowSelector ) ) {
  17547. // Indexes
  17548. if ( rowSelector.row === undefined ) {
  17549. // Selector options in first parameter
  17550. opts = rowSelector;
  17551. rowSelector = null;
  17552. }
  17553. else {
  17554. // Cell index objects in first parameter
  17555. opts = columnSelector;
  17556. columnSelector = null;
  17557. }
  17558. }
  17559. if ( $.isPlainObject( columnSelector ) ) {
  17560. opts = columnSelector;
  17561. columnSelector = null;
  17562. }
  17563. // Cell selector
  17564. if ( columnSelector === null || columnSelector === undefined ) {
  17565. return this.iterator( 'table', function ( settings ) {
  17566. return __cell_selector( settings, rowSelector, _selector_opts( opts ) );
  17567. } );
  17568. }
  17569. // Row + column selector
  17570. var columns = this.columns( columnSelector, opts );
  17571. var rows = this.rows( rowSelector, opts );
  17572. var a, i, ien, j, jen;
  17573. var cells = this.iterator( 'table', function ( settings, idx ) {
  17574. a = [];
  17575. for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
  17576. for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {
  17577. a.push( {
  17578. row: rows[idx][i],
  17579. column: columns[idx][j]
  17580. } );
  17581. }
  17582. }
  17583. return a;
  17584. }, 1 );
  17585. $.extend( cells.selector, {
  17586. cols: columnSelector,
  17587. rows: rowSelector,
  17588. opts: opts
  17589. } );
  17590. return cells;
  17591. } );
  17592. _api_registerPlural( 'cells().nodes()', 'cell().node()', function () {
  17593. return this.iterator( 'cell', function ( settings, row, column ) {
  17594. var data = settings.aoData[ row ];
  17595. return data && data.anCells ?
  17596. data.anCells[ column ] :
  17597. undefined;
  17598. }, 1 );
  17599. } );
  17600. _api_register( 'cells().data()', function () {
  17601. return this.iterator( 'cell', function ( settings, row, column ) {
  17602. return _fnGetCellData( settings, row, column );
  17603. }, 1 );
  17604. } );
  17605. _api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {
  17606. type = type === 'search' ? '_aFilterData' : '_aSortData';
  17607. return this.iterator( 'cell', function ( settings, row, column ) {
  17608. return settings.aoData[ row ][ type ][ column ];
  17609. }, 1 );
  17610. } );
  17611. _api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {
  17612. return this.iterator( 'cell', function ( settings, row, column ) {
  17613. return _fnGetCellData( settings, row, column, type );
  17614. }, 1 );
  17615. } );
  17616. _api_registerPlural( 'cells().indexes()', 'cell().index()', function () {
  17617. return this.iterator( 'cell', function ( settings, row, column ) {
  17618. return {
  17619. row: row,
  17620. column: column,
  17621. columnVisible: _fnColumnIndexToVisible( settings, column )
  17622. };
  17623. }, 1 );
  17624. } );
  17625. _api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {
  17626. return this.iterator( 'cell', function ( settings, row, column ) {
  17627. _fnInvalidate( settings, row, src, column );
  17628. } );
  17629. } );
  17630. _api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {
  17631. return _selector_first( this.cells( rowSelector, columnSelector, opts ) );
  17632. } );
  17633. _api_register( 'cell().data()', function ( data ) {
  17634. var ctx = this.context;
  17635. var cell = this[0];
  17636. if ( data === undefined ) {
  17637. // Get
  17638. return ctx.length && cell.length ?
  17639. _fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :
  17640. undefined;
  17641. }
  17642. // Set
  17643. _fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );
  17644. _fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );
  17645. return this;
  17646. } );
  17647. /**
  17648. * Get current ordering (sorting) that has been applied to the table.
  17649. *
  17650. * @returns {array} 2D array containing the sorting information for the first
  17651. * table in the current context. Each element in the parent array represents
  17652. * a column being sorted upon (i.e. multi-sorting with two columns would have
  17653. * 2 inner arrays). The inner arrays may have 2 or 3 elements. The first is
  17654. * the column index that the sorting condition applies to, the second is the
  17655. * direction of the sort (`desc` or `asc`) and, optionally, the third is the
  17656. * index of the sorting order from the `column.sorting` initialisation array.
  17657. *//**
  17658. * Set the ordering for the table.
  17659. *
  17660. * @param {integer} order Column index to sort upon.
  17661. * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)
  17662. * @returns {DataTables.Api} this
  17663. *//**
  17664. * Set the ordering for the table.
  17665. *
  17666. * @param {array} order 1D array of sorting information to be applied.
  17667. * @param {array} [...] Optional additional sorting conditions
  17668. * @returns {DataTables.Api} this
  17669. *//**
  17670. * Set the ordering for the table.
  17671. *
  17672. * @param {array} order 2D array of sorting information to be applied.
  17673. * @returns {DataTables.Api} this
  17674. */
  17675. _api_register( 'order()', function ( order, dir ) {
  17676. var ctx = this.context;
  17677. if ( order === undefined ) {
  17678. // get
  17679. return ctx.length !== 0 ?
  17680. ctx[0].aaSorting :
  17681. undefined;
  17682. }
  17683. // set
  17684. if ( typeof order === 'number' ) {
  17685. // Simple column / direction passed in
  17686. order = [ [ order, dir ] ];
  17687. }
  17688. else if ( order.length && ! $.isArray( order[0] ) ) {
  17689. // Arguments passed in (list of 1D arrays)
  17690. order = Array.prototype.slice.call( arguments );
  17691. }
  17692. // otherwise a 2D array was passed in
  17693. return this.iterator( 'table', function ( settings ) {
  17694. settings.aaSorting = order.slice();
  17695. } );
  17696. } );
  17697. /**
  17698. * Attach a sort listener to an element for a given column
  17699. *
  17700. * @param {node|jQuery|string} node Identifier for the element(s) to attach the
  17701. * listener to. This can take the form of a single DOM node, a jQuery
  17702. * collection of nodes or a jQuery selector which will identify the node(s).
  17703. * @param {integer} column the column that a click on this node will sort on
  17704. * @param {function} [callback] callback function when sort is run
  17705. * @returns {DataTables.Api} this
  17706. */
  17707. _api_register( 'order.listener()', function ( node, column, callback ) {
  17708. return this.iterator( 'table', function ( settings ) {
  17709. _fnSortAttachListener( settings, node, column, callback );
  17710. } );
  17711. } );
  17712. _api_register( 'order.fixed()', function ( set ) {
  17713. if ( ! set ) {
  17714. var ctx = this.context;
  17715. var fixed = ctx.length ?
  17716. ctx[0].aaSortingFixed :
  17717. undefined;
  17718. return $.isArray( fixed ) ?
  17719. { pre: fixed } :
  17720. fixed;
  17721. }
  17722. return this.iterator( 'table', function ( settings ) {
  17723. settings.aaSortingFixed = $.extend( true, {}, set );
  17724. } );
  17725. } );
  17726. // Order by the selected column(s)
  17727. _api_register( [
  17728. 'columns().order()',
  17729. 'column().order()'
  17730. ], function ( dir ) {
  17731. var that = this;
  17732. return this.iterator( 'table', function ( settings, i ) {
  17733. var sort = [];
  17734. $.each( that[i], function (j, col) {
  17735. sort.push( [ col, dir ] );
  17736. } );
  17737. settings.aaSorting = sort;
  17738. } );
  17739. } );
  17740. _api_register( 'search()', function ( input, regex, smart, caseInsen ) {
  17741. var ctx = this.context;
  17742. if ( input === undefined ) {
  17743. // get
  17744. return ctx.length !== 0 ?
  17745. ctx[0].oPreviousSearch.sSearch :
  17746. undefined;
  17747. }
  17748. // set
  17749. return this.iterator( 'table', function ( settings ) {
  17750. if ( ! settings.oFeatures.bFilter ) {
  17751. return;
  17752. }
  17753. _fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {
  17754. "sSearch": input+"",
  17755. "bRegex": regex === null ? false : regex,
  17756. "bSmart": smart === null ? true : smart,
  17757. "bCaseInsensitive": caseInsen === null ? true : caseInsen
  17758. } ), 1 );
  17759. } );
  17760. } );
  17761. _api_registerPlural(
  17762. 'columns().search()',
  17763. 'column().search()',
  17764. function ( input, regex, smart, caseInsen ) {
  17765. return this.iterator( 'column', function ( settings, column ) {
  17766. var preSearch = settings.aoPreSearchCols;
  17767. if ( input === undefined ) {
  17768. // get
  17769. return preSearch[ column ].sSearch;
  17770. }
  17771. // set
  17772. if ( ! settings.oFeatures.bFilter ) {
  17773. return;
  17774. }
  17775. $.extend( preSearch[ column ], {
  17776. "sSearch": input+"",
  17777. "bRegex": regex === null ? false : regex,
  17778. "bSmart": smart === null ? true : smart,
  17779. "bCaseInsensitive": caseInsen === null ? true : caseInsen
  17780. } );
  17781. _fnFilterComplete( settings, settings.oPreviousSearch, 1 );
  17782. } );
  17783. }
  17784. );
  17785. /*
  17786. * State API methods
  17787. */
  17788. _api_register( 'state()', function () {
  17789. return this.context.length ?
  17790. this.context[0].oSavedState :
  17791. null;
  17792. } );
  17793. _api_register( 'state.clear()', function () {
  17794. return this.iterator( 'table', function ( settings ) {
  17795. // Save an empty object
  17796. settings.fnStateSaveCallback.call( settings.oInstance, settings, {} );
  17797. } );
  17798. } );
  17799. _api_register( 'state.loaded()', function () {
  17800. return this.context.length ?
  17801. this.context[0].oLoadedState :
  17802. null;
  17803. } );
  17804. _api_register( 'state.save()', function () {
  17805. return this.iterator( 'table', function ( settings ) {
  17806. _fnSaveState( settings );
  17807. } );
  17808. } );
  17809. /**
  17810. * Provide a common method for plug-ins to check the version of DataTables being
  17811. * used, in order to ensure compatibility.
  17812. *
  17813. * @param {string} version Version string to check for, in the format "X.Y.Z".
  17814. * Note that the formats "X" and "X.Y" are also acceptable.
  17815. * @returns {boolean} true if this version of DataTables is greater or equal to
  17816. * the required version, or false if this version of DataTales is not
  17817. * suitable
  17818. * @static
  17819. * @dtopt API-Static
  17820. *
  17821. * @example
  17822. * alert( $.fn.dataTable.versionCheck( '1.9.0' ) );
  17823. */
  17824. DataTable.versionCheck = DataTable.fnVersionCheck = function( version )
  17825. {
  17826. var aThis = DataTable.version.split('.');
  17827. var aThat = version.split('.');
  17828. var iThis, iThat;
  17829. for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {
  17830. iThis = parseInt( aThis[i], 10 ) || 0;
  17831. iThat = parseInt( aThat[i], 10 ) || 0;
  17832. // Parts are the same, keep comparing
  17833. if (iThis === iThat) {
  17834. continue;
  17835. }
  17836. // Parts are different, return immediately
  17837. return iThis > iThat;
  17838. }
  17839. return true;
  17840. };
  17841. /**
  17842. * Check if a `<table>` node is a DataTable table already or not.
  17843. *
  17844. * @param {node|jquery|string} table Table node, jQuery object or jQuery
  17845. * selector for the table to test. Note that if more than more than one
  17846. * table is passed on, only the first will be checked
  17847. * @returns {boolean} true the table given is a DataTable, or false otherwise
  17848. * @static
  17849. * @dtopt API-Static
  17850. *
  17851. * @example
  17852. * if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
  17853. * $('#example').dataTable();
  17854. * }
  17855. */
  17856. DataTable.isDataTable = DataTable.fnIsDataTable = function ( table )
  17857. {
  17858. var t = $(table).get(0);
  17859. var is = false;
  17860. if ( table instanceof DataTable.Api ) {
  17861. return true;
  17862. }
  17863. $.each( DataTable.settings, function (i, o) {
  17864. var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;
  17865. var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;
  17866. if ( o.nTable === t || head === t || foot === t ) {
  17867. is = true;
  17868. }
  17869. } );
  17870. return is;
  17871. };
  17872. /**
  17873. * Get all DataTable tables that have been initialised - optionally you can
  17874. * select to get only currently visible tables.
  17875. *
  17876. * @param {boolean} [visible=false] Flag to indicate if you want all (default)
  17877. * or visible tables only.
  17878. * @returns {array} Array of `table` nodes (not DataTable instances) which are
  17879. * DataTables
  17880. * @static
  17881. * @dtopt API-Static
  17882. *
  17883. * @example
  17884. * $.each( $.fn.dataTable.tables(true), function () {
  17885. * $(table).DataTable().columns.adjust();
  17886. * } );
  17887. */
  17888. DataTable.tables = DataTable.fnTables = function ( visible )
  17889. {
  17890. var api = false;
  17891. if ( $.isPlainObject( visible ) ) {
  17892. api = visible.api;
  17893. visible = visible.visible;
  17894. }
  17895. var a = $.map( DataTable.settings, function (o) {
  17896. if ( !visible || (visible && $(o.nTable).is(':visible')) ) {
  17897. return o.nTable;
  17898. }
  17899. } );
  17900. return api ?
  17901. new _Api( a ) :
  17902. a;
  17903. };
  17904. /**
  17905. * Convert from camel case parameters to Hungarian notation. This is made public
  17906. * for the extensions to provide the same ability as DataTables core to accept
  17907. * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase
  17908. * parameters.
  17909. *
  17910. * @param {object} src The model object which holds all parameters that can be
  17911. * mapped.
  17912. * @param {object} user The object to convert from camel case to Hungarian.
  17913. * @param {boolean} force When set to `true`, properties which already have a
  17914. * Hungarian value in the `user` object will be overwritten. Otherwise they
  17915. * won't be.
  17916. */
  17917. DataTable.camelToHungarian = _fnCamelToHungarian;
  17918. /**
  17919. *
  17920. */
  17921. _api_register( '$()', function ( selector, opts ) {
  17922. var
  17923. rows = this.rows( opts ).nodes(), // Get all rows
  17924. jqRows = $(rows);
  17925. return $( [].concat(
  17926. jqRows.filter( selector ).toArray(),
  17927. jqRows.find( selector ).toArray()
  17928. ) );
  17929. } );
  17930. // jQuery functions to operate on the tables
  17931. $.each( [ 'on', 'one', 'off' ], function (i, key) {
  17932. _api_register( key+'()', function ( /* event, handler */ ) {
  17933. var args = Array.prototype.slice.call(arguments);
  17934. // Add the `dt` namespace automatically if it isn't already present
  17935. args[0] = $.map( args[0].split( /\s/ ), function ( e ) {
  17936. return ! e.match(/\.dt\b/) ?
  17937. e+'.dt' :
  17938. e;
  17939. } ).join( ' ' );
  17940. var inst = $( this.tables().nodes() );
  17941. inst[key].apply( inst, args );
  17942. return this;
  17943. } );
  17944. } );
  17945. _api_register( 'clear()', function () {
  17946. return this.iterator( 'table', function ( settings ) {
  17947. _fnClearTable( settings );
  17948. } );
  17949. } );
  17950. _api_register( 'settings()', function () {
  17951. return new _Api( this.context, this.context );
  17952. } );
  17953. _api_register( 'init()', function () {
  17954. var ctx = this.context;
  17955. return ctx.length ? ctx[0].oInit : null;
  17956. } );
  17957. _api_register( 'data()', function () {
  17958. return this.iterator( 'table', function ( settings ) {
  17959. return _pluck( settings.aoData, '_aData' );
  17960. } ).flatten();
  17961. } );
  17962. _api_register( 'destroy()', function ( remove ) {
  17963. remove = remove || false;
  17964. return this.iterator( 'table', function ( settings ) {
  17965. var orig = settings.nTableWrapper.parentNode;
  17966. var classes = settings.oClasses;
  17967. var table = settings.nTable;
  17968. var tbody = settings.nTBody;
  17969. var thead = settings.nTHead;
  17970. var tfoot = settings.nTFoot;
  17971. var jqTable = $(table);
  17972. var jqTbody = $(tbody);
  17973. var jqWrapper = $(settings.nTableWrapper);
  17974. var rows = $.map( settings.aoData, function (r) { return r.nTr; } );
  17975. var i, ien;
  17976. // Flag to note that the table is currently being destroyed - no action
  17977. // should be taken
  17978. settings.bDestroying = true;
  17979. // Fire off the destroy callbacks for plug-ins etc
  17980. _fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] );
  17981. // If not being removed from the document, make all columns visible
  17982. if ( ! remove ) {
  17983. new _Api( settings ).columns().visible( true );
  17984. }
  17985. // Blitz all `DT` namespaced events (these are internal events, the
  17986. // lowercase, `dt` events are user subscribed and they are responsible
  17987. // for removing them
  17988. jqWrapper.off('.DT').find(':not(tbody *)').off('.DT');
  17989. $(window).off('.DT-'+settings.sInstance);
  17990. // When scrolling we had to break the table up - restore it
  17991. if ( table != thead.parentNode ) {
  17992. jqTable.children('thead').detach();
  17993. jqTable.append( thead );
  17994. }
  17995. if ( tfoot && table != tfoot.parentNode ) {
  17996. jqTable.children('tfoot').detach();
  17997. jqTable.append( tfoot );
  17998. }
  17999. settings.aaSorting = [];
  18000. settings.aaSortingFixed = [];
  18001. _fnSortingClasses( settings );
  18002. $( rows ).removeClass( settings.asStripeClasses.join(' ') );
  18003. $('th, td', thead).removeClass( classes.sSortable+' '+
  18004. classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone
  18005. );
  18006. if ( settings.bJUI ) {
  18007. $('th span.'+classes.sSortIcon+ ', td span.'+classes.sSortIcon, thead).detach();
  18008. $('th, td', thead).each( function () {
  18009. var wrapper = $('div.'+classes.sSortJUIWrapper, this);
  18010. $(this).append( wrapper.contents() );
  18011. wrapper.detach();
  18012. } );
  18013. }
  18014. // Add the TR elements back into the table in their original order
  18015. jqTbody.children().detach();
  18016. jqTbody.append( rows );
  18017. // Remove the DataTables generated nodes, events and classes
  18018. var removedMethod = remove ? 'remove' : 'detach';
  18019. jqTable[ removedMethod ]();
  18020. jqWrapper[ removedMethod ]();
  18021. // If we need to reattach the table to the document
  18022. if ( ! remove && orig ) {
  18023. // insertBefore acts like appendChild if !arg[1]
  18024. orig.insertBefore( table, settings.nTableReinsertBefore );
  18025. // Restore the width of the original table - was read from the style property,
  18026. // so we can restore directly to that
  18027. jqTable
  18028. .css( 'width', settings.sDestroyWidth )
  18029. .removeClass( classes.sTable );
  18030. // If the were originally stripe classes - then we add them back here.
  18031. // Note this is not fool proof (for example if not all rows had stripe
  18032. // classes - but it's a good effort without getting carried away
  18033. ien = settings.asDestroyStripes.length;
  18034. if ( ien ) {
  18035. jqTbody.children().each( function (i) {
  18036. $(this).addClass( settings.asDestroyStripes[i % ien] );
  18037. } );
  18038. }
  18039. }
  18040. /* Remove the settings object from the settings array */
  18041. var idx = $.inArray( settings, DataTable.settings );
  18042. if ( idx !== -1 ) {
  18043. DataTable.settings.splice( idx, 1 );
  18044. }
  18045. } );
  18046. } );
  18047. // Add the `every()` method for rows, columns and cells in a compact form
  18048. $.each( [ 'column', 'row', 'cell' ], function ( i, type ) {
  18049. _api_register( type+'s().every()', function ( fn ) {
  18050. var opts = this.selector.opts;
  18051. var api = this;
  18052. return this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {
  18053. // Rows and columns:
  18054. // arg1 - index
  18055. // arg2 - table counter
  18056. // arg3 - loop counter
  18057. // arg4 - undefined
  18058. // Cells:
  18059. // arg1 - row index
  18060. // arg2 - column index
  18061. // arg3 - table counter
  18062. // arg4 - loop counter
  18063. fn.call(
  18064. api[ type ](
  18065. arg1,
  18066. type==='cell' ? arg2 : opts,
  18067. type==='cell' ? opts : undefined
  18068. ),
  18069. arg1, arg2, arg3, arg4
  18070. );
  18071. } );
  18072. } );
  18073. } );
  18074. // i18n method for extensions to be able to use the language object from the
  18075. // DataTable
  18076. _api_register( 'i18n()', function ( token, def, plural ) {
  18077. var ctx = this.context[0];
  18078. var resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );
  18079. if ( resolved === undefined ) {
  18080. resolved = def;
  18081. }
  18082. if ( plural !== undefined && $.isPlainObject( resolved ) ) {
  18083. resolved = resolved[ plural ] !== undefined ?
  18084. resolved[ plural ] :
  18085. resolved._;
  18086. }
  18087. return resolved.replace( '%d', plural ); // nb: plural might be undefined,
  18088. } );
  18089. /**
  18090. * Version string for plug-ins to check compatibility. Allowed format is
  18091. * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
  18092. * only for non-release builds. See http://semver.org/ for more information.
  18093. * @member
  18094. * @type string
  18095. * @default Version number
  18096. */
  18097. DataTable.version = "1.10.15";
  18098. /**
  18099. * Private data store, containing all of the settings objects that are
  18100. * created for the tables on a given page.
  18101. *
  18102. * Note that the `DataTable.settings` object is aliased to
  18103. * `jQuery.fn.dataTableExt` through which it may be accessed and
  18104. * manipulated, or `jQuery.fn.dataTable.settings`.
  18105. * @member
  18106. * @type array
  18107. * @default []
  18108. * @private
  18109. */
  18110. DataTable.settings = [];
  18111. /**
  18112. * Object models container, for the various models that DataTables has
  18113. * available to it. These models define the objects that are used to hold
  18114. * the active state and configuration of the table.
  18115. * @namespace
  18116. */
  18117. DataTable.models = {};
  18118. /**
  18119. * Template object for the way in which DataTables holds information about
  18120. * search information for the global filter and individual column filters.
  18121. * @namespace
  18122. */
  18123. DataTable.models.oSearch = {
  18124. /**
  18125. * Flag to indicate if the filtering should be case insensitive or not
  18126. * @type boolean
  18127. * @default true
  18128. */
  18129. "bCaseInsensitive": true,
  18130. /**
  18131. * Applied search term
  18132. * @type string
  18133. * @default <i>Empty string</i>
  18134. */
  18135. "sSearch": "",
  18136. /**
  18137. * Flag to indicate if the search term should be interpreted as a
  18138. * regular expression (true) or not (false) and therefore and special
  18139. * regex characters escaped.
  18140. * @type boolean
  18141. * @default false
  18142. */
  18143. "bRegex": false,
  18144. /**
  18145. * Flag to indicate if DataTables is to use its smart filtering or not.
  18146. * @type boolean
  18147. * @default true
  18148. */
  18149. "bSmart": true
  18150. };
  18151. /**
  18152. * Template object for the way in which DataTables holds information about
  18153. * each individual row. This is the object format used for the settings
  18154. * aoData array.
  18155. * @namespace
  18156. */
  18157. DataTable.models.oRow = {
  18158. /**
  18159. * TR element for the row
  18160. * @type node
  18161. * @default null
  18162. */
  18163. "nTr": null,
  18164. /**
  18165. * Array of TD elements for each row. This is null until the row has been
  18166. * created.
  18167. * @type array nodes
  18168. * @default []
  18169. */
  18170. "anCells": null,
  18171. /**
  18172. * Data object from the original data source for the row. This is either
  18173. * an array if using the traditional form of DataTables, or an object if
  18174. * using mData options. The exact type will depend on the passed in
  18175. * data from the data source, or will be an array if using DOM a data
  18176. * source.
  18177. * @type array|object
  18178. * @default []
  18179. */
  18180. "_aData": [],
  18181. /**
  18182. * Sorting data cache - this array is ostensibly the same length as the
  18183. * number of columns (although each index is generated only as it is
  18184. * needed), and holds the data that is used for sorting each column in the
  18185. * row. We do this cache generation at the start of the sort in order that
  18186. * the formatting of the sort data need be done only once for each cell
  18187. * per sort. This array should not be read from or written to by anything
  18188. * other than the master sorting methods.
  18189. * @type array
  18190. * @default null
  18191. * @private
  18192. */
  18193. "_aSortData": null,
  18194. /**
  18195. * Per cell filtering data cache. As per the sort data cache, used to
  18196. * increase the performance of the filtering in DataTables
  18197. * @type array
  18198. * @default null
  18199. * @private
  18200. */
  18201. "_aFilterData": null,
  18202. /**
  18203. * Filtering data cache. This is the same as the cell filtering cache, but
  18204. * in this case a string rather than an array. This is easily computed with
  18205. * a join on `_aFilterData`, but is provided as a cache so the join isn't
  18206. * needed on every search (memory traded for performance)
  18207. * @type array
  18208. * @default null
  18209. * @private
  18210. */
  18211. "_sFilterRow": null,
  18212. /**
  18213. * Cache of the class name that DataTables has applied to the row, so we
  18214. * can quickly look at this variable rather than needing to do a DOM check
  18215. * on className for the nTr property.
  18216. * @type string
  18217. * @default <i>Empty string</i>
  18218. * @private
  18219. */
  18220. "_sRowStripe": "",
  18221. /**
  18222. * Denote if the original data source was from the DOM, or the data source
  18223. * object. This is used for invalidating data, so DataTables can
  18224. * automatically read data from the original source, unless uninstructed
  18225. * otherwise.
  18226. * @type string
  18227. * @default null
  18228. * @private
  18229. */
  18230. "src": null,
  18231. /**
  18232. * Index in the aoData array. This saves an indexOf lookup when we have the
  18233. * object, but want to know the index
  18234. * @type integer
  18235. * @default -1
  18236. * @private
  18237. */
  18238. "idx": -1
  18239. };
  18240. /**
  18241. * Template object for the column information object in DataTables. This object
  18242. * is held in the settings aoColumns array and contains all the information that
  18243. * DataTables needs about each individual column.
  18244. *
  18245. * Note that this object is related to {@link DataTable.defaults.column}
  18246. * but this one is the internal data store for DataTables's cache of columns.
  18247. * It should NOT be manipulated outside of DataTables. Any configuration should
  18248. * be done through the initialisation options.
  18249. * @namespace
  18250. */
  18251. DataTable.models.oColumn = {
  18252. /**
  18253. * Column index. This could be worked out on-the-fly with $.inArray, but it
  18254. * is faster to just hold it as a variable
  18255. * @type integer
  18256. * @default null
  18257. */
  18258. "idx": null,
  18259. /**
  18260. * A list of the columns that sorting should occur on when this column
  18261. * is sorted. That this property is an array allows multi-column sorting
  18262. * to be defined for a column (for example first name / last name columns
  18263. * would benefit from this). The values are integers pointing to the
  18264. * columns to be sorted on (typically it will be a single integer pointing
  18265. * at itself, but that doesn't need to be the case).
  18266. * @type array
  18267. */
  18268. "aDataSort": null,
  18269. /**
  18270. * Define the sorting directions that are applied to the column, in sequence
  18271. * as the column is repeatedly sorted upon - i.e. the first value is used
  18272. * as the sorting direction when the column if first sorted (clicked on).
  18273. * Sort it again (click again) and it will move on to the next index.
  18274. * Repeat until loop.
  18275. * @type array
  18276. */
  18277. "asSorting": null,
  18278. /**
  18279. * Flag to indicate if the column is searchable, and thus should be included
  18280. * in the filtering or not.
  18281. * @type boolean
  18282. */
  18283. "bSearchable": null,
  18284. /**
  18285. * Flag to indicate if the column is sortable or not.
  18286. * @type boolean
  18287. */
  18288. "bSortable": null,
  18289. /**
  18290. * Flag to indicate if the column is currently visible in the table or not
  18291. * @type boolean
  18292. */
  18293. "bVisible": null,
  18294. /**
  18295. * Store for manual type assignment using the `column.type` option. This
  18296. * is held in store so we can manipulate the column's `sType` property.
  18297. * @type string
  18298. * @default null
  18299. * @private
  18300. */
  18301. "_sManualType": null,
  18302. /**
  18303. * Flag to indicate if HTML5 data attributes should be used as the data
  18304. * source for filtering or sorting. True is either are.
  18305. * @type boolean
  18306. * @default false
  18307. * @private
  18308. */
  18309. "_bAttrSrc": false,
  18310. /**
  18311. * Developer definable function that is called whenever a cell is created (Ajax source,
  18312. * etc) or processed for input (DOM source). This can be used as a compliment to mRender
  18313. * allowing you to modify the DOM element (add background colour for example) when the
  18314. * element is available.
  18315. * @type function
  18316. * @param {element} nTd The TD node that has been created
  18317. * @param {*} sData The Data for the cell
  18318. * @param {array|object} oData The data for the whole row
  18319. * @param {int} iRow The row index for the aoData data store
  18320. * @default null
  18321. */
  18322. "fnCreatedCell": null,
  18323. /**
  18324. * Function to get data from a cell in a column. You should <b>never</b>
  18325. * access data directly through _aData internally in DataTables - always use
  18326. * the method attached to this property. It allows mData to function as
  18327. * required. This function is automatically assigned by the column
  18328. * initialisation method
  18329. * @type function
  18330. * @param {array|object} oData The data array/object for the array
  18331. * (i.e. aoData[]._aData)
  18332. * @param {string} sSpecific The specific data type you want to get -
  18333. * 'display', 'type' 'filter' 'sort'
  18334. * @returns {*} The data for the cell from the given row's data
  18335. * @default null
  18336. */
  18337. "fnGetData": null,
  18338. /**
  18339. * Function to set data for a cell in the column. You should <b>never</b>
  18340. * set the data directly to _aData internally in DataTables - always use
  18341. * this method. It allows mData to function as required. This function
  18342. * is automatically assigned by the column initialisation method
  18343. * @type function
  18344. * @param {array|object} oData The data array/object for the array
  18345. * (i.e. aoData[]._aData)
  18346. * @param {*} sValue Value to set
  18347. * @default null
  18348. */
  18349. "fnSetData": null,
  18350. /**
  18351. * Property to read the value for the cells in the column from the data
  18352. * source array / object. If null, then the default content is used, if a
  18353. * function is given then the return from the function is used.
  18354. * @type function|int|string|null
  18355. * @default null
  18356. */
  18357. "mData": null,
  18358. /**
  18359. * Partner property to mData which is used (only when defined) to get
  18360. * the data - i.e. it is basically the same as mData, but without the
  18361. * 'set' option, and also the data fed to it is the result from mData.
  18362. * This is the rendering method to match the data method of mData.
  18363. * @type function|int|string|null
  18364. * @default null
  18365. */
  18366. "mRender": null,
  18367. /**
  18368. * Unique header TH/TD element for this column - this is what the sorting
  18369. * listener is attached to (if sorting is enabled.)
  18370. * @type node
  18371. * @default null
  18372. */
  18373. "nTh": null,
  18374. /**
  18375. * Unique footer TH/TD element for this column (if there is one). Not used
  18376. * in DataTables as such, but can be used for plug-ins to reference the
  18377. * footer for each column.
  18378. * @type node
  18379. * @default null
  18380. */
  18381. "nTf": null,
  18382. /**
  18383. * The class to apply to all TD elements in the table's TBODY for the column
  18384. * @type string
  18385. * @default null
  18386. */
  18387. "sClass": null,
  18388. /**
  18389. * When DataTables calculates the column widths to assign to each column,
  18390. * it finds the longest string in each column and then constructs a
  18391. * temporary table and reads the widths from that. The problem with this
  18392. * is that "mmm" is much wider then "iiii", but the latter is a longer
  18393. * string - thus the calculation can go wrong (doing it properly and putting
  18394. * it into an DOM object and measuring that is horribly(!) slow). Thus as
  18395. * a "work around" we provide this option. It will append its value to the
  18396. * text that is found to be the longest string for the column - i.e. padding.
  18397. * @type string
  18398. */
  18399. "sContentPadding": null,
  18400. /**
  18401. * Allows a default value to be given for a column's data, and will be used
  18402. * whenever a null data source is encountered (this can be because mData
  18403. * is set to null, or because the data source itself is null).
  18404. * @type string
  18405. * @default null
  18406. */
  18407. "sDefaultContent": null,
  18408. /**
  18409. * Name for the column, allowing reference to the column by name as well as
  18410. * by index (needs a lookup to work by name).
  18411. * @type string
  18412. */
  18413. "sName": null,
  18414. /**
  18415. * Custom sorting data type - defines which of the available plug-ins in
  18416. * afnSortData the custom sorting will use - if any is defined.
  18417. * @type string
  18418. * @default std
  18419. */
  18420. "sSortDataType": 'std',
  18421. /**
  18422. * Class to be applied to the header element when sorting on this column
  18423. * @type string
  18424. * @default null
  18425. */
  18426. "sSortingClass": null,
  18427. /**
  18428. * Class to be applied to the header element when sorting on this column -
  18429. * when jQuery UI theming is used.
  18430. * @type string
  18431. * @default null
  18432. */
  18433. "sSortingClassJUI": null,
  18434. /**
  18435. * Title of the column - what is seen in the TH element (nTh).
  18436. * @type string
  18437. */
  18438. "sTitle": null,
  18439. /**
  18440. * Column sorting and filtering type
  18441. * @type string
  18442. * @default null
  18443. */
  18444. "sType": null,
  18445. /**
  18446. * Width of the column
  18447. * @type string
  18448. * @default null
  18449. */
  18450. "sWidth": null,
  18451. /**
  18452. * Width of the column when it was first "encountered"
  18453. * @type string
  18454. * @default null
  18455. */
  18456. "sWidthOrig": null
  18457. };
  18458. /*
  18459. * Developer note: The properties of the object below are given in Hungarian
  18460. * notation, that was used as the interface for DataTables prior to v1.10, however
  18461. * from v1.10 onwards the primary interface is camel case. In order to avoid
  18462. * breaking backwards compatibility utterly with this change, the Hungarian
  18463. * version is still, internally the primary interface, but is is not documented
  18464. * - hence the @name tags in each doc comment. This allows a Javascript function
  18465. * to create a map from Hungarian notation to camel case (going the other direction
  18466. * would require each property to be listed, which would at around 3K to the size
  18467. * of DataTables, while this method is about a 0.5K hit.
  18468. *
  18469. * Ultimately this does pave the way for Hungarian notation to be dropped
  18470. * completely, but that is a massive amount of work and will break current
  18471. * installs (therefore is on-hold until v2).
  18472. */
  18473. /**
  18474. * Initialisation options that can be given to DataTables at initialisation
  18475. * time.
  18476. * @namespace
  18477. */
  18478. DataTable.defaults = {
  18479. /**
  18480. * An array of data to use for the table, passed in at initialisation which
  18481. * will be used in preference to any data which is already in the DOM. This is
  18482. * particularly useful for constructing tables purely in Javascript, for
  18483. * example with a custom Ajax call.
  18484. * @type array
  18485. * @default null
  18486. *
  18487. * @dtopt Option
  18488. * @name DataTable.defaults.data
  18489. *
  18490. * @example
  18491. * // Using a 2D array data source
  18492. * $(document).ready( function () {
  18493. * $('#example').dataTable( {
  18494. * "data": [
  18495. * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
  18496. * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
  18497. * ],
  18498. * "columns": [
  18499. * { "title": "Engine" },
  18500. * { "title": "Browser" },
  18501. * { "title": "Platform" },
  18502. * { "title": "Version" },
  18503. * { "title": "Grade" }
  18504. * ]
  18505. * } );
  18506. * } );
  18507. *
  18508. * @example
  18509. * // Using an array of objects as a data source (`data`)
  18510. * $(document).ready( function () {
  18511. * $('#example').dataTable( {
  18512. * "data": [
  18513. * {
  18514. * "engine": "Trident",
  18515. * "browser": "Internet Explorer 4.0",
  18516. * "platform": "Win 95+",
  18517. * "version": 4,
  18518. * "grade": "X"
  18519. * },
  18520. * {
  18521. * "engine": "Trident",
  18522. * "browser": "Internet Explorer 5.0",
  18523. * "platform": "Win 95+",
  18524. * "version": 5,
  18525. * "grade": "C"
  18526. * }
  18527. * ],
  18528. * "columns": [
  18529. * { "title": "Engine", "data": "engine" },
  18530. * { "title": "Browser", "data": "browser" },
  18531. * { "title": "Platform", "data": "platform" },
  18532. * { "title": "Version", "data": "version" },
  18533. * { "title": "Grade", "data": "grade" }
  18534. * ]
  18535. * } );
  18536. * } );
  18537. */
  18538. "aaData": null,
  18539. /**
  18540. * If ordering is enabled, then DataTables will perform a first pass sort on
  18541. * initialisation. You can define which column(s) the sort is performed
  18542. * upon, and the sorting direction, with this variable. The `sorting` array
  18543. * should contain an array for each column to be sorted initially containing
  18544. * the column's index and a direction string ('asc' or 'desc').
  18545. * @type array
  18546. * @default [[0,'asc']]
  18547. *
  18548. * @dtopt Option
  18549. * @name DataTable.defaults.order
  18550. *
  18551. * @example
  18552. * // Sort by 3rd column first, and then 4th column
  18553. * $(document).ready( function() {
  18554. * $('#example').dataTable( {
  18555. * "order": [[2,'asc'], [3,'desc']]
  18556. * } );
  18557. * } );
  18558. *
  18559. * // No initial sorting
  18560. * $(document).ready( function() {
  18561. * $('#example').dataTable( {
  18562. * "order": []
  18563. * } );
  18564. * } );
  18565. */
  18566. "aaSorting": [[0,'asc']],
  18567. /**
  18568. * This parameter is basically identical to the `sorting` parameter, but
  18569. * cannot be overridden by user interaction with the table. What this means
  18570. * is that you could have a column (visible or hidden) which the sorting
  18571. * will always be forced on first - any sorting after that (from the user)
  18572. * will then be performed as required. This can be useful for grouping rows
  18573. * together.
  18574. * @type array
  18575. * @default null
  18576. *
  18577. * @dtopt Option
  18578. * @name DataTable.defaults.orderFixed
  18579. *
  18580. * @example
  18581. * $(document).ready( function() {
  18582. * $('#example').dataTable( {
  18583. * "orderFixed": [[0,'asc']]
  18584. * } );
  18585. * } )
  18586. */
  18587. "aaSortingFixed": [],
  18588. /**
  18589. * DataTables can be instructed to load data to display in the table from a
  18590. * Ajax source. This option defines how that Ajax call is made and where to.
  18591. *
  18592. * The `ajax` property has three different modes of operation, depending on
  18593. * how it is defined. These are:
  18594. *
  18595. * * `string` - Set the URL from where the data should be loaded from.
  18596. * * `object` - Define properties for `jQuery.ajax`.
  18597. * * `function` - Custom data get function
  18598. *
  18599. * `string`
  18600. * --------
  18601. *
  18602. * As a string, the `ajax` property simply defines the URL from which
  18603. * DataTables will load data.
  18604. *
  18605. * `object`
  18606. * --------
  18607. *
  18608. * As an object, the parameters in the object are passed to
  18609. * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control
  18610. * of the Ajax request. DataTables has a number of default parameters which
  18611. * you can override using this option. Please refer to the jQuery
  18612. * documentation for a full description of the options available, although
  18613. * the following parameters provide additional options in DataTables or
  18614. * require special consideration:
  18615. *
  18616. * * `data` - As with jQuery, `data` can be provided as an object, but it
  18617. * can also be used as a function to manipulate the data DataTables sends
  18618. * to the server. The function takes a single parameter, an object of
  18619. * parameters with the values that DataTables has readied for sending. An
  18620. * object may be returned which will be merged into the DataTables
  18621. * defaults, or you can add the items to the object that was passed in and
  18622. * not return anything from the function. This supersedes `fnServerParams`
  18623. * from DataTables 1.9-.
  18624. *
  18625. * * `dataSrc` - By default DataTables will look for the property `data` (or
  18626. * `aaData` for compatibility with DataTables 1.9-) when obtaining data
  18627. * from an Ajax source or for server-side processing - this parameter
  18628. * allows that property to be changed. You can use Javascript dotted
  18629. * object notation to get a data source for multiple levels of nesting, or
  18630. * it my be used as a function. As a function it takes a single parameter,
  18631. * the JSON returned from the server, which can be manipulated as
  18632. * required, with the returned value being that used by DataTables as the
  18633. * data source for the table. This supersedes `sAjaxDataProp` from
  18634. * DataTables 1.9-.
  18635. *
  18636. * * `success` - Should not be overridden it is used internally in
  18637. * DataTables. To manipulate / transform the data returned by the server
  18638. * use `ajax.dataSrc`, or use `ajax` as a function (see below).
  18639. *
  18640. * `function`
  18641. * ----------
  18642. *
  18643. * As a function, making the Ajax call is left up to yourself allowing
  18644. * complete control of the Ajax request. Indeed, if desired, a method other
  18645. * than Ajax could be used to obtain the required data, such as Web storage
  18646. * or an AIR database.
  18647. *
  18648. * The function is given four parameters and no return is required. The
  18649. * parameters are:
  18650. *
  18651. * 1. _object_ - Data to send to the server
  18652. * 2. _function_ - Callback function that must be executed when the required
  18653. * data has been obtained. That data should be passed into the callback
  18654. * as the only parameter
  18655. * 3. _object_ - DataTables settings object for the table
  18656. *
  18657. * Note that this supersedes `fnServerData` from DataTables 1.9-.
  18658. *
  18659. * @type string|object|function
  18660. * @default null
  18661. *
  18662. * @dtopt Option
  18663. * @name DataTable.defaults.ajax
  18664. * @since 1.10.0
  18665. *
  18666. * @example
  18667. * // Get JSON data from a file via Ajax.
  18668. * // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).
  18669. * $('#example').dataTable( {
  18670. * "ajax": "data.json"
  18671. * } );
  18672. *
  18673. * @example
  18674. * // Get JSON data from a file via Ajax, using `dataSrc` to change
  18675. * // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)
  18676. * $('#example').dataTable( {
  18677. * "ajax": {
  18678. * "url": "data.json",
  18679. * "dataSrc": "tableData"
  18680. * }
  18681. * } );
  18682. *
  18683. * @example
  18684. * // Get JSON data from a file via Ajax, using `dataSrc` to read data
  18685. * // from a plain array rather than an array in an object
  18686. * $('#example').dataTable( {
  18687. * "ajax": {
  18688. * "url": "data.json",
  18689. * "dataSrc": ""
  18690. * }
  18691. * } );
  18692. *
  18693. * @example
  18694. * // Manipulate the data returned from the server - add a link to data
  18695. * // (note this can, should, be done using `render` for the column - this
  18696. * // is just a simple example of how the data can be manipulated).
  18697. * $('#example').dataTable( {
  18698. * "ajax": {
  18699. * "url": "data.json",
  18700. * "dataSrc": function ( json ) {
  18701. * for ( var i=0, ien=json.length ; i<ien ; i++ ) {
  18702. * json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>';
  18703. * }
  18704. * return json;
  18705. * }
  18706. * }
  18707. * } );
  18708. *
  18709. * @example
  18710. * // Add data to the request
  18711. * $('#example').dataTable( {
  18712. * "ajax": {
  18713. * "url": "data.json",
  18714. * "data": function ( d ) {
  18715. * return {
  18716. * "extra_search": $('#extra').val()
  18717. * };
  18718. * }
  18719. * }
  18720. * } );
  18721. *
  18722. * @example
  18723. * // Send request as POST
  18724. * $('#example').dataTable( {
  18725. * "ajax": {
  18726. * "url": "data.json",
  18727. * "type": "POST"
  18728. * }
  18729. * } );
  18730. *
  18731. * @example
  18732. * // Get the data from localStorage (could interface with a form for
  18733. * // adding, editing and removing rows).
  18734. * $('#example').dataTable( {
  18735. * "ajax": function (data, callback, settings) {
  18736. * callback(
  18737. * JSON.parse( localStorage.getItem('dataTablesData') )
  18738. * );
  18739. * }
  18740. * } );
  18741. */
  18742. "ajax": null,
  18743. /**
  18744. * This parameter allows you to readily specify the entries in the length drop
  18745. * down menu that DataTables shows when pagination is enabled. It can be
  18746. * either a 1D array of options which will be used for both the displayed
  18747. * option and the value, or a 2D array which will use the array in the first
  18748. * position as the value, and the array in the second position as the
  18749. * displayed options (useful for language strings such as 'All').
  18750. *
  18751. * Note that the `pageLength` property will be automatically set to the
  18752. * first value given in this array, unless `pageLength` is also provided.
  18753. * @type array
  18754. * @default [ 10, 25, 50, 100 ]
  18755. *
  18756. * @dtopt Option
  18757. * @name DataTable.defaults.lengthMenu
  18758. *
  18759. * @example
  18760. * $(document).ready( function() {
  18761. * $('#example').dataTable( {
  18762. * "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
  18763. * } );
  18764. * } );
  18765. */
  18766. "aLengthMenu": [ 10, 25, 50, 100 ],
  18767. /**
  18768. * The `columns` option in the initialisation parameter allows you to define
  18769. * details about the way individual columns behave. For a full list of
  18770. * column options that can be set, please see
  18771. * {@link DataTable.defaults.column}. Note that if you use `columns` to
  18772. * define your columns, you must have an entry in the array for every single
  18773. * column that you have in your table (these can be null if you don't which
  18774. * to specify any options).
  18775. * @member
  18776. *
  18777. * @name DataTable.defaults.column
  18778. */
  18779. "aoColumns": null,
  18780. /**
  18781. * Very similar to `columns`, `columnDefs` allows you to target a specific
  18782. * column, multiple columns, or all columns, using the `targets` property of
  18783. * each object in the array. This allows great flexibility when creating
  18784. * tables, as the `columnDefs` arrays can be of any length, targeting the
  18785. * columns you specifically want. `columnDefs` may use any of the column
  18786. * options available: {@link DataTable.defaults.column}, but it _must_
  18787. * have `targets` defined in each object in the array. Values in the `targets`
  18788. * array may be:
  18789. * <ul>
  18790. * <li>a string - class name will be matched on the TH for the column</li>
  18791. * <li>0 or a positive integer - column index counting from the left</li>
  18792. * <li>a negative integer - column index counting from the right</li>
  18793. * <li>the string "_all" - all columns (i.e. assign a default)</li>
  18794. * </ul>
  18795. * @member
  18796. *
  18797. * @name DataTable.defaults.columnDefs
  18798. */
  18799. "aoColumnDefs": null,
  18800. /**
  18801. * Basically the same as `search`, this parameter defines the individual column
  18802. * filtering state at initialisation time. The array must be of the same size
  18803. * as the number of columns, and each element be an object with the parameters
  18804. * `search` and `escapeRegex` (the latter is optional). 'null' is also
  18805. * accepted and the default will be used.
  18806. * @type array
  18807. * @default []
  18808. *
  18809. * @dtopt Option
  18810. * @name DataTable.defaults.searchCols
  18811. *
  18812. * @example
  18813. * $(document).ready( function() {
  18814. * $('#example').dataTable( {
  18815. * "searchCols": [
  18816. * null,
  18817. * { "search": "My filter" },
  18818. * null,
  18819. * { "search": "^[0-9]", "escapeRegex": false }
  18820. * ]
  18821. * } );
  18822. * } )
  18823. */
  18824. "aoSearchCols": [],
  18825. /**
  18826. * An array of CSS classes that should be applied to displayed rows. This
  18827. * array may be of any length, and DataTables will apply each class
  18828. * sequentially, looping when required.
  18829. * @type array
  18830. * @default null <i>Will take the values determined by the `oClasses.stripe*`
  18831. * options</i>
  18832. *
  18833. * @dtopt Option
  18834. * @name DataTable.defaults.stripeClasses
  18835. *
  18836. * @example
  18837. * $(document).ready( function() {
  18838. * $('#example').dataTable( {
  18839. * "stripeClasses": [ 'strip1', 'strip2', 'strip3' ]
  18840. * } );
  18841. * } )
  18842. */
  18843. "asStripeClasses": null,
  18844. /**
  18845. * Enable or disable automatic column width calculation. This can be disabled
  18846. * as an optimisation (it takes some time to calculate the widths) if the
  18847. * tables widths are passed in using `columns`.
  18848. * @type boolean
  18849. * @default true
  18850. *
  18851. * @dtopt Features
  18852. * @name DataTable.defaults.autoWidth
  18853. *
  18854. * @example
  18855. * $(document).ready( function () {
  18856. * $('#example').dataTable( {
  18857. * "autoWidth": false
  18858. * } );
  18859. * } );
  18860. */
  18861. "bAutoWidth": true,
  18862. /**
  18863. * Deferred rendering can provide DataTables with a huge speed boost when you
  18864. * are using an Ajax or JS data source for the table. This option, when set to
  18865. * true, will cause DataTables to defer the creation of the table elements for
  18866. * each row until they are needed for a draw - saving a significant amount of
  18867. * time.
  18868. * @type boolean
  18869. * @default false
  18870. *
  18871. * @dtopt Features
  18872. * @name DataTable.defaults.deferRender
  18873. *
  18874. * @example
  18875. * $(document).ready( function() {
  18876. * $('#example').dataTable( {
  18877. * "ajax": "sources/arrays.txt",
  18878. * "deferRender": true
  18879. * } );
  18880. * } );
  18881. */
  18882. "bDeferRender": false,
  18883. /**
  18884. * Replace a DataTable which matches the given selector and replace it with
  18885. * one which has the properties of the new initialisation object passed. If no
  18886. * table matches the selector, then the new DataTable will be constructed as
  18887. * per normal.
  18888. * @type boolean
  18889. * @default false
  18890. *
  18891. * @dtopt Options
  18892. * @name DataTable.defaults.destroy
  18893. *
  18894. * @example
  18895. * $(document).ready( function() {
  18896. * $('#example').dataTable( {
  18897. * "srollY": "200px",
  18898. * "paginate": false
  18899. * } );
  18900. *
  18901. * // Some time later....
  18902. * $('#example').dataTable( {
  18903. * "filter": false,
  18904. * "destroy": true
  18905. * } );
  18906. * } );
  18907. */
  18908. "bDestroy": false,
  18909. /**
  18910. * Enable or disable filtering of data. Filtering in DataTables is "smart" in
  18911. * that it allows the end user to input multiple words (space separated) and
  18912. * will match a row containing those words, even if not in the order that was
  18913. * specified (this allow matching across multiple columns). Note that if you
  18914. * wish to use filtering in DataTables this must remain 'true' - to remove the
  18915. * default filtering input box and retain filtering abilities, please use
  18916. * {@link DataTable.defaults.dom}.
  18917. * @type boolean
  18918. * @default true
  18919. *
  18920. * @dtopt Features
  18921. * @name DataTable.defaults.searching
  18922. *
  18923. * @example
  18924. * $(document).ready( function () {
  18925. * $('#example').dataTable( {
  18926. * "searching": false
  18927. * } );
  18928. * } );
  18929. */
  18930. "bFilter": true,
  18931. /**
  18932. * Enable or disable the table information display. This shows information
  18933. * about the data that is currently visible on the page, including information
  18934. * about filtered data if that action is being performed.
  18935. * @type boolean
  18936. * @default true
  18937. *
  18938. * @dtopt Features
  18939. * @name DataTable.defaults.info
  18940. *
  18941. * @example
  18942. * $(document).ready( function () {
  18943. * $('#example').dataTable( {
  18944. * "info": false
  18945. * } );
  18946. * } );
  18947. */
  18948. "bInfo": true,
  18949. /**
  18950. * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some
  18951. * slightly different and additional mark-up from what DataTables has
  18952. * traditionally used).
  18953. * @type boolean
  18954. * @default false
  18955. *
  18956. * @dtopt Features
  18957. * @name DataTable.defaults.jQueryUI
  18958. *
  18959. * @example
  18960. * $(document).ready( function() {
  18961. * $('#example').dataTable( {
  18962. * "jQueryUI": true
  18963. * } );
  18964. * } );
  18965. */
  18966. "bJQueryUI": false,
  18967. /**
  18968. * Allows the end user to select the size of a formatted page from a select
  18969. * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).
  18970. * @type boolean
  18971. * @default true
  18972. *
  18973. * @dtopt Features
  18974. * @name DataTable.defaults.lengthChange
  18975. *
  18976. * @example
  18977. * $(document).ready( function () {
  18978. * $('#example').dataTable( {
  18979. * "lengthChange": false
  18980. * } );
  18981. * } );
  18982. */
  18983. "bLengthChange": true,
  18984. /**
  18985. * Enable or disable pagination.
  18986. * @type boolean
  18987. * @default true
  18988. *
  18989. * @dtopt Features
  18990. * @name DataTable.defaults.paging
  18991. *
  18992. * @example
  18993. * $(document).ready( function () {
  18994. * $('#example').dataTable( {
  18995. * "paging": false
  18996. * } );
  18997. * } );
  18998. */
  18999. "bPaginate": true,
  19000. /**
  19001. * Enable or disable the display of a 'processing' indicator when the table is
  19002. * being processed (e.g. a sort). This is particularly useful for tables with
  19003. * large amounts of data where it can take a noticeable amount of time to sort
  19004. * the entries.
  19005. * @type boolean
  19006. * @default false
  19007. *
  19008. * @dtopt Features
  19009. * @name DataTable.defaults.processing
  19010. *
  19011. * @example
  19012. * $(document).ready( function () {
  19013. * $('#example').dataTable( {
  19014. * "processing": true
  19015. * } );
  19016. * } );
  19017. */
  19018. "bProcessing": false,
  19019. /**
  19020. * Retrieve the DataTables object for the given selector. Note that if the
  19021. * table has already been initialised, this parameter will cause DataTables
  19022. * to simply return the object that has already been set up - it will not take
  19023. * account of any changes you might have made to the initialisation object
  19024. * passed to DataTables (setting this parameter to true is an acknowledgement
  19025. * that you understand this). `destroy` can be used to reinitialise a table if
  19026. * you need.
  19027. * @type boolean
  19028. * @default false
  19029. *
  19030. * @dtopt Options
  19031. * @name DataTable.defaults.retrieve
  19032. *
  19033. * @example
  19034. * $(document).ready( function() {
  19035. * initTable();
  19036. * tableActions();
  19037. * } );
  19038. *
  19039. * function initTable ()
  19040. * {
  19041. * return $('#example').dataTable( {
  19042. * "scrollY": "200px",
  19043. * "paginate": false,
  19044. * "retrieve": true
  19045. * } );
  19046. * }
  19047. *
  19048. * function tableActions ()
  19049. * {
  19050. * var table = initTable();
  19051. * // perform API operations with oTable
  19052. * }
  19053. */
  19054. "bRetrieve": false,
  19055. /**
  19056. * When vertical (y) scrolling is enabled, DataTables will force the height of
  19057. * the table's viewport to the given height at all times (useful for layout).
  19058. * However, this can look odd when filtering data down to a small data set,
  19059. * and the footer is left "floating" further down. This parameter (when
  19060. * enabled) will cause DataTables to collapse the table's viewport down when
  19061. * the result set will fit within the given Y height.
  19062. * @type boolean
  19063. * @default false
  19064. *
  19065. * @dtopt Options
  19066. * @name DataTable.defaults.scrollCollapse
  19067. *
  19068. * @example
  19069. * $(document).ready( function() {
  19070. * $('#example').dataTable( {
  19071. * "scrollY": "200",
  19072. * "scrollCollapse": true
  19073. * } );
  19074. * } );
  19075. */
  19076. "bScrollCollapse": false,
  19077. /**
  19078. * Configure DataTables to use server-side processing. Note that the
  19079. * `ajax` parameter must also be given in order to give DataTables a
  19080. * source to obtain the required data for each draw.
  19081. * @type boolean
  19082. * @default false
  19083. *
  19084. * @dtopt Features
  19085. * @dtopt Server-side
  19086. * @name DataTable.defaults.serverSide
  19087. *
  19088. * @example
  19089. * $(document).ready( function () {
  19090. * $('#example').dataTable( {
  19091. * "serverSide": true,
  19092. * "ajax": "xhr.php"
  19093. * } );
  19094. * } );
  19095. */
  19096. "bServerSide": false,
  19097. /**
  19098. * Enable or disable sorting of columns. Sorting of individual columns can be
  19099. * disabled by the `sortable` option for each column.
  19100. * @type boolean
  19101. * @default true
  19102. *
  19103. * @dtopt Features
  19104. * @name DataTable.defaults.ordering
  19105. *
  19106. * @example
  19107. * $(document).ready( function () {
  19108. * $('#example').dataTable( {
  19109. * "ordering": false
  19110. * } );
  19111. * } );
  19112. */
  19113. "bSort": true,
  19114. /**
  19115. * Enable or display DataTables' ability to sort multiple columns at the
  19116. * same time (activated by shift-click by the user).
  19117. * @type boolean
  19118. * @default true
  19119. *
  19120. * @dtopt Options
  19121. * @name DataTable.defaults.orderMulti
  19122. *
  19123. * @example
  19124. * // Disable multiple column sorting ability
  19125. * $(document).ready( function () {
  19126. * $('#example').dataTable( {
  19127. * "orderMulti": false
  19128. * } );
  19129. * } );
  19130. */
  19131. "bSortMulti": true,
  19132. /**
  19133. * Allows control over whether DataTables should use the top (true) unique
  19134. * cell that is found for a single column, or the bottom (false - default).
  19135. * This is useful when using complex headers.
  19136. * @type boolean
  19137. * @default false
  19138. *
  19139. * @dtopt Options
  19140. * @name DataTable.defaults.orderCellsTop
  19141. *
  19142. * @example
  19143. * $(document).ready( function() {
  19144. * $('#example').dataTable( {
  19145. * "orderCellsTop": true
  19146. * } );
  19147. * } );
  19148. */
  19149. "bSortCellsTop": false,
  19150. /**
  19151. * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
  19152. * `sorting\_3` to the columns which are currently being sorted on. This is
  19153. * presented as a feature switch as it can increase processing time (while
  19154. * classes are removed and added) so for large data sets you might want to
  19155. * turn this off.
  19156. * @type boolean
  19157. * @default true
  19158. *
  19159. * @dtopt Features
  19160. * @name DataTable.defaults.orderClasses
  19161. *
  19162. * @example
  19163. * $(document).ready( function () {
  19164. * $('#example').dataTable( {
  19165. * "orderClasses": false
  19166. * } );
  19167. * } );
  19168. */
  19169. "bSortClasses": true,
  19170. /**
  19171. * Enable or disable state saving. When enabled HTML5 `localStorage` will be
  19172. * used to save table display information such as pagination information,
  19173. * display length, filtering and sorting. As such when the end user reloads
  19174. * the page the display display will match what thy had previously set up.
  19175. *
  19176. * Due to the use of `localStorage` the default state saving is not supported
  19177. * in IE6 or 7. If state saving is required in those browsers, use
  19178. * `stateSaveCallback` to provide a storage solution such as cookies.
  19179. * @type boolean
  19180. * @default false
  19181. *
  19182. * @dtopt Features
  19183. * @name DataTable.defaults.stateSave
  19184. *
  19185. * @example
  19186. * $(document).ready( function () {
  19187. * $('#example').dataTable( {
  19188. * "stateSave": true
  19189. * } );
  19190. * } );
  19191. */
  19192. "bStateSave": false,
  19193. /**
  19194. * This function is called when a TR element is created (and all TD child
  19195. * elements have been inserted), or registered if using a DOM source, allowing
  19196. * manipulation of the TR element (adding classes etc).
  19197. * @type function
  19198. * @param {node} row "TR" element for the current row
  19199. * @param {array} data Raw data array for this row
  19200. * @param {int} dataIndex The index of this row in the internal aoData array
  19201. *
  19202. * @dtopt Callbacks
  19203. * @name DataTable.defaults.createdRow
  19204. *
  19205. * @example
  19206. * $(document).ready( function() {
  19207. * $('#example').dataTable( {
  19208. * "createdRow": function( row, data, dataIndex ) {
  19209. * // Bold the grade for all 'A' grade browsers
  19210. * if ( data[4] == "A" )
  19211. * {
  19212. * $('td:eq(4)', row).html( '<b>A</b>' );
  19213. * }
  19214. * }
  19215. * } );
  19216. * } );
  19217. */
  19218. "fnCreatedRow": null,
  19219. /**
  19220. * This function is called on every 'draw' event, and allows you to
  19221. * dynamically modify any aspect you want about the created DOM.
  19222. * @type function
  19223. * @param {object} settings DataTables settings object
  19224. *
  19225. * @dtopt Callbacks
  19226. * @name DataTable.defaults.drawCallback
  19227. *
  19228. * @example
  19229. * $(document).ready( function() {
  19230. * $('#example').dataTable( {
  19231. * "drawCallback": function( settings ) {
  19232. * alert( 'DataTables has redrawn the table' );
  19233. * }
  19234. * } );
  19235. * } );
  19236. */
  19237. "fnDrawCallback": null,
  19238. /**
  19239. * Identical to fnHeaderCallback() but for the table footer this function
  19240. * allows you to modify the table footer on every 'draw' event.
  19241. * @type function
  19242. * @param {node} foot "TR" element for the footer
  19243. * @param {array} data Full table data (as derived from the original HTML)
  19244. * @param {int} start Index for the current display starting point in the
  19245. * display array
  19246. * @param {int} end Index for the current display ending point in the
  19247. * display array
  19248. * @param {array int} display Index array to translate the visual position
  19249. * to the full data array
  19250. *
  19251. * @dtopt Callbacks
  19252. * @name DataTable.defaults.footerCallback
  19253. *
  19254. * @example
  19255. * $(document).ready( function() {
  19256. * $('#example').dataTable( {
  19257. * "footerCallback": function( tfoot, data, start, end, display ) {
  19258. * tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start;
  19259. * }
  19260. * } );
  19261. * } )
  19262. */
  19263. "fnFooterCallback": null,
  19264. /**
  19265. * When rendering large numbers in the information element for the table
  19266. * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
  19267. * to have a comma separator for the 'thousands' units (e.g. 1 million is
  19268. * rendered as "1,000,000") to help readability for the end user. This
  19269. * function will override the default method DataTables uses.
  19270. * @type function
  19271. * @member
  19272. * @param {int} toFormat number to be formatted
  19273. * @returns {string} formatted string for DataTables to show the number
  19274. *
  19275. * @dtopt Callbacks
  19276. * @name DataTable.defaults.formatNumber
  19277. *
  19278. * @example
  19279. * // Format a number using a single quote for the separator (note that
  19280. * // this can also be done with the language.thousands option)
  19281. * $(document).ready( function() {
  19282. * $('#example').dataTable( {
  19283. * "formatNumber": function ( toFormat ) {
  19284. * return toFormat.toString().replace(
  19285. * /\B(?=(\d{3})+(?!\d))/g, "'"
  19286. * );
  19287. * };
  19288. * } );
  19289. * } );
  19290. */
  19291. "fnFormatNumber": function ( toFormat ) {
  19292. return toFormat.toString().replace(
  19293. /\B(?=(\d{3})+(?!\d))/g,
  19294. this.oLanguage.sThousands
  19295. );
  19296. },
  19297. /**
  19298. * This function is called on every 'draw' event, and allows you to
  19299. * dynamically modify the header row. This can be used to calculate and
  19300. * display useful information about the table.
  19301. * @type function
  19302. * @param {node} head "TR" element for the header
  19303. * @param {array} data Full table data (as derived from the original HTML)
  19304. * @param {int} start Index for the current display starting point in the
  19305. * display array
  19306. * @param {int} end Index for the current display ending point in the
  19307. * display array
  19308. * @param {array int} display Index array to translate the visual position
  19309. * to the full data array
  19310. *
  19311. * @dtopt Callbacks
  19312. * @name DataTable.defaults.headerCallback
  19313. *
  19314. * @example
  19315. * $(document).ready( function() {
  19316. * $('#example').dataTable( {
  19317. * "fheaderCallback": function( head, data, start, end, display ) {
  19318. * head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records";
  19319. * }
  19320. * } );
  19321. * } )
  19322. */
  19323. "fnHeaderCallback": null,
  19324. /**
  19325. * The information element can be used to convey information about the current
  19326. * state of the table. Although the internationalisation options presented by
  19327. * DataTables are quite capable of dealing with most customisations, there may
  19328. * be times where you wish to customise the string further. This callback
  19329. * allows you to do exactly that.
  19330. * @type function
  19331. * @param {object} oSettings DataTables settings object
  19332. * @param {int} start Starting position in data for the draw
  19333. * @param {int} end End position in data for the draw
  19334. * @param {int} max Total number of rows in the table (regardless of
  19335. * filtering)
  19336. * @param {int} total Total number of rows in the data set, after filtering
  19337. * @param {string} pre The string that DataTables has formatted using it's
  19338. * own rules
  19339. * @returns {string} The string to be displayed in the information element.
  19340. *
  19341. * @dtopt Callbacks
  19342. * @name DataTable.defaults.infoCallback
  19343. *
  19344. * @example
  19345. * $('#example').dataTable( {
  19346. * "infoCallback": function( settings, start, end, max, total, pre ) {
  19347. * return start +" to "+ end;
  19348. * }
  19349. * } );
  19350. */
  19351. "fnInfoCallback": null,
  19352. /**
  19353. * Called when the table has been initialised. Normally DataTables will
  19354. * initialise sequentially and there will be no need for this function,
  19355. * however, this does not hold true when using external language information
  19356. * since that is obtained using an async XHR call.
  19357. * @type function
  19358. * @param {object} settings DataTables settings object
  19359. * @param {object} json The JSON object request from the server - only
  19360. * present if client-side Ajax sourced data is used
  19361. *
  19362. * @dtopt Callbacks
  19363. * @name DataTable.defaults.initComplete
  19364. *
  19365. * @example
  19366. * $(document).ready( function() {
  19367. * $('#example').dataTable( {
  19368. * "initComplete": function(settings, json) {
  19369. * alert( 'DataTables has finished its initialisation.' );
  19370. * }
  19371. * } );
  19372. * } )
  19373. */
  19374. "fnInitComplete": null,
  19375. /**
  19376. * Called at the very start of each table draw and can be used to cancel the
  19377. * draw by returning false, any other return (including undefined) results in
  19378. * the full draw occurring).
  19379. * @type function
  19380. * @param {object} settings DataTables settings object
  19381. * @returns {boolean} False will cancel the draw, anything else (including no
  19382. * return) will allow it to complete.
  19383. *
  19384. * @dtopt Callbacks
  19385. * @name DataTable.defaults.preDrawCallback
  19386. *
  19387. * @example
  19388. * $(document).ready( function() {
  19389. * $('#example').dataTable( {
  19390. * "preDrawCallback": function( settings ) {
  19391. * if ( $('#test').val() == 1 ) {
  19392. * return false;
  19393. * }
  19394. * }
  19395. * } );
  19396. * } );
  19397. */
  19398. "fnPreDrawCallback": null,
  19399. /**
  19400. * This function allows you to 'post process' each row after it have been
  19401. * generated for each table draw, but before it is rendered on screen. This
  19402. * function might be used for setting the row class name etc.
  19403. * @type function
  19404. * @param {node} row "TR" element for the current row
  19405. * @param {array} data Raw data array for this row
  19406. * @param {int} displayIndex The display index for the current table draw
  19407. * @param {int} displayIndexFull The index of the data in the full list of
  19408. * rows (after filtering)
  19409. *
  19410. * @dtopt Callbacks
  19411. * @name DataTable.defaults.rowCallback
  19412. *
  19413. * @example
  19414. * $(document).ready( function() {
  19415. * $('#example').dataTable( {
  19416. * "rowCallback": function( row, data, displayIndex, displayIndexFull ) {
  19417. * // Bold the grade for all 'A' grade browsers
  19418. * if ( data[4] == "A" ) {
  19419. * $('td:eq(4)', row).html( '<b>A</b>' );
  19420. * }
  19421. * }
  19422. * } );
  19423. * } );
  19424. */
  19425. "fnRowCallback": null,
  19426. /**
  19427. * __Deprecated__ The functionality provided by this parameter has now been
  19428. * superseded by that provided through `ajax`, which should be used instead.
  19429. *
  19430. * This parameter allows you to override the default function which obtains
  19431. * the data from the server so something more suitable for your application.
  19432. * For example you could use POST data, or pull information from a Gears or
  19433. * AIR database.
  19434. * @type function
  19435. * @member
  19436. * @param {string} source HTTP source to obtain the data from (`ajax`)
  19437. * @param {array} data A key/value pair object containing the data to send
  19438. * to the server
  19439. * @param {function} callback to be called on completion of the data get
  19440. * process that will draw the data on the page.
  19441. * @param {object} settings DataTables settings object
  19442. *
  19443. * @dtopt Callbacks
  19444. * @dtopt Server-side
  19445. * @name DataTable.defaults.serverData
  19446. *
  19447. * @deprecated 1.10. Please use `ajax` for this functionality now.
  19448. */
  19449. "fnServerData": null,
  19450. /**
  19451. * __Deprecated__ The functionality provided by this parameter has now been
  19452. * superseded by that provided through `ajax`, which should be used instead.
  19453. *
  19454. * It is often useful to send extra data to the server when making an Ajax
  19455. * request - for example custom filtering information, and this callback
  19456. * function makes it trivial to send extra information to the server. The
  19457. * passed in parameter is the data set that has been constructed by
  19458. * DataTables, and you can add to this or modify it as you require.
  19459. * @type function
  19460. * @param {array} data Data array (array of objects which are name/value
  19461. * pairs) that has been constructed by DataTables and will be sent to the
  19462. * server. In the case of Ajax sourced data with server-side processing
  19463. * this will be an empty array, for server-side processing there will be a
  19464. * significant number of parameters!
  19465. * @returns {undefined} Ensure that you modify the data array passed in,
  19466. * as this is passed by reference.
  19467. *
  19468. * @dtopt Callbacks
  19469. * @dtopt Server-side
  19470. * @name DataTable.defaults.serverParams
  19471. *
  19472. * @deprecated 1.10. Please use `ajax` for this functionality now.
  19473. */
  19474. "fnServerParams": null,
  19475. /**
  19476. * Load the table state. With this function you can define from where, and how, the
  19477. * state of a table is loaded. By default DataTables will load from `localStorage`
  19478. * but you might wish to use a server-side database or cookies.
  19479. * @type function
  19480. * @member
  19481. * @param {object} settings DataTables settings object
  19482. * @param {object} callback Callback that can be executed when done. It
  19483. * should be passed the loaded state object.
  19484. * @return {object} The DataTables state object to be loaded
  19485. *
  19486. * @dtopt Callbacks
  19487. * @name DataTable.defaults.stateLoadCallback
  19488. *
  19489. * @example
  19490. * $(document).ready( function() {
  19491. * $('#example').dataTable( {
  19492. * "stateSave": true,
  19493. * "stateLoadCallback": function (settings, callback) {
  19494. * $.ajax( {
  19495. * "url": "/state_load",
  19496. * "dataType": "json",
  19497. * "success": function (json) {
  19498. * callback( json );
  19499. * }
  19500. * } );
  19501. * }
  19502. * } );
  19503. * } );
  19504. */
  19505. "fnStateLoadCallback": function ( settings ) {
  19506. try {
  19507. return JSON.parse(
  19508. (settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(
  19509. 'DataTables_'+settings.sInstance+'_'+location.pathname
  19510. )
  19511. );
  19512. } catch (e) {}
  19513. },
  19514. /**
  19515. * Callback which allows modification of the saved state prior to loading that state.
  19516. * This callback is called when the table is loading state from the stored data, but
  19517. * prior to the settings object being modified by the saved state. Note that for
  19518. * plug-in authors, you should use the `stateLoadParams` event to load parameters for
  19519. * a plug-in.
  19520. * @type function
  19521. * @param {object} settings DataTables settings object
  19522. * @param {object} data The state object that is to be loaded
  19523. *
  19524. * @dtopt Callbacks
  19525. * @name DataTable.defaults.stateLoadParams
  19526. *
  19527. * @example
  19528. * // Remove a saved filter, so filtering is never loaded
  19529. * $(document).ready( function() {
  19530. * $('#example').dataTable( {
  19531. * "stateSave": true,
  19532. * "stateLoadParams": function (settings, data) {
  19533. * data.oSearch.sSearch = "";
  19534. * }
  19535. * } );
  19536. * } );
  19537. *
  19538. * @example
  19539. * // Disallow state loading by returning false
  19540. * $(document).ready( function() {
  19541. * $('#example').dataTable( {
  19542. * "stateSave": true,
  19543. * "stateLoadParams": function (settings, data) {
  19544. * return false;
  19545. * }
  19546. * } );
  19547. * } );
  19548. */
  19549. "fnStateLoadParams": null,
  19550. /**
  19551. * Callback that is called when the state has been loaded from the state saving method
  19552. * and the DataTables settings object has been modified as a result of the loaded state.
  19553. * @type function
  19554. * @param {object} settings DataTables settings object
  19555. * @param {object} data The state object that was loaded
  19556. *
  19557. * @dtopt Callbacks
  19558. * @name DataTable.defaults.stateLoaded
  19559. *
  19560. * @example
  19561. * // Show an alert with the filtering value that was saved
  19562. * $(document).ready( function() {
  19563. * $('#example').dataTable( {
  19564. * "stateSave": true,
  19565. * "stateLoaded": function (settings, data) {
  19566. * alert( 'Saved filter was: '+data.oSearch.sSearch );
  19567. * }
  19568. * } );
  19569. * } );
  19570. */
  19571. "fnStateLoaded": null,
  19572. /**
  19573. * Save the table state. This function allows you to define where and how the state
  19574. * information for the table is stored By default DataTables will use `localStorage`
  19575. * but you might wish to use a server-side database or cookies.
  19576. * @type function
  19577. * @member
  19578. * @param {object} settings DataTables settings object
  19579. * @param {object} data The state object to be saved
  19580. *
  19581. * @dtopt Callbacks
  19582. * @name DataTable.defaults.stateSaveCallback
  19583. *
  19584. * @example
  19585. * $(document).ready( function() {
  19586. * $('#example').dataTable( {
  19587. * "stateSave": true,
  19588. * "stateSaveCallback": function (settings, data) {
  19589. * // Send an Ajax request to the server with the state object
  19590. * $.ajax( {
  19591. * "url": "/state_save",
  19592. * "data": data,
  19593. * "dataType": "json",
  19594. * "method": "POST"
  19595. * "success": function () {}
  19596. * } );
  19597. * }
  19598. * } );
  19599. * } );
  19600. */
  19601. "fnStateSaveCallback": function ( settings, data ) {
  19602. try {
  19603. (settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
  19604. 'DataTables_'+settings.sInstance+'_'+location.pathname,
  19605. JSON.stringify( data )
  19606. );
  19607. } catch (e) {}
  19608. },
  19609. /**
  19610. * Callback which allows modification of the state to be saved. Called when the table
  19611. * has changed state a new state save is required. This method allows modification of
  19612. * the state saving object prior to actually doing the save, including addition or
  19613. * other state properties or modification. Note that for plug-in authors, you should
  19614. * use the `stateSaveParams` event to save parameters for a plug-in.
  19615. * @type function
  19616. * @param {object} settings DataTables settings object
  19617. * @param {object} data The state object to be saved
  19618. *
  19619. * @dtopt Callbacks
  19620. * @name DataTable.defaults.stateSaveParams
  19621. *
  19622. * @example
  19623. * // Remove a saved filter, so filtering is never saved
  19624. * $(document).ready( function() {
  19625. * $('#example').dataTable( {
  19626. * "stateSave": true,
  19627. * "stateSaveParams": function (settings, data) {
  19628. * data.oSearch.sSearch = "";
  19629. * }
  19630. * } );
  19631. * } );
  19632. */
  19633. "fnStateSaveParams": null,
  19634. /**
  19635. * Duration for which the saved state information is considered valid. After this period
  19636. * has elapsed the state will be returned to the default.
  19637. * Value is given in seconds.
  19638. * @type int
  19639. * @default 7200 <i>(2 hours)</i>
  19640. *
  19641. * @dtopt Options
  19642. * @name DataTable.defaults.stateDuration
  19643. *
  19644. * @example
  19645. * $(document).ready( function() {
  19646. * $('#example').dataTable( {
  19647. * "stateDuration": 60*60*24; // 1 day
  19648. * } );
  19649. * } )
  19650. */
  19651. "iStateDuration": 7200,
  19652. /**
  19653. * When enabled DataTables will not make a request to the server for the first
  19654. * page draw - rather it will use the data already on the page (no sorting etc
  19655. * will be applied to it), thus saving on an XHR at load time. `deferLoading`
  19656. * is used to indicate that deferred loading is required, but it is also used
  19657. * to tell DataTables how many records there are in the full table (allowing
  19658. * the information element and pagination to be displayed correctly). In the case
  19659. * where a filtering is applied to the table on initial load, this can be
  19660. * indicated by giving the parameter as an array, where the first element is
  19661. * the number of records available after filtering and the second element is the
  19662. * number of records without filtering (allowing the table information element
  19663. * to be shown correctly).
  19664. * @type int | array
  19665. * @default null
  19666. *
  19667. * @dtopt Options
  19668. * @name DataTable.defaults.deferLoading
  19669. *
  19670. * @example
  19671. * // 57 records available in the table, no filtering applied
  19672. * $(document).ready( function() {
  19673. * $('#example').dataTable( {
  19674. * "serverSide": true,
  19675. * "ajax": "scripts/server_processing.php",
  19676. * "deferLoading": 57
  19677. * } );
  19678. * } );
  19679. *
  19680. * @example
  19681. * // 57 records after filtering, 100 without filtering (an initial filter applied)
  19682. * $(document).ready( function() {
  19683. * $('#example').dataTable( {
  19684. * "serverSide": true,
  19685. * "ajax": "scripts/server_processing.php",
  19686. * "deferLoading": [ 57, 100 ],
  19687. * "search": {
  19688. * "search": "my_filter"
  19689. * }
  19690. * } );
  19691. * } );
  19692. */
  19693. "iDeferLoading": null,
  19694. /**
  19695. * Number of rows to display on a single page when using pagination. If
  19696. * feature enabled (`lengthChange`) then the end user will be able to override
  19697. * this to a custom setting using a pop-up menu.
  19698. * @type int
  19699. * @default 10
  19700. *
  19701. * @dtopt Options
  19702. * @name DataTable.defaults.pageLength
  19703. *
  19704. * @example
  19705. * $(document).ready( function() {
  19706. * $('#example').dataTable( {
  19707. * "pageLength": 50
  19708. * } );
  19709. * } )
  19710. */
  19711. "iDisplayLength": 10,
  19712. /**
  19713. * Define the starting point for data display when using DataTables with
  19714. * pagination. Note that this parameter is the number of records, rather than
  19715. * the page number, so if you have 10 records per page and want to start on
  19716. * the third page, it should be "20".
  19717. * @type int
  19718. * @default 0
  19719. *
  19720. * @dtopt Options
  19721. * @name DataTable.defaults.displayStart
  19722. *
  19723. * @example
  19724. * $(document).ready( function() {
  19725. * $('#example').dataTable( {
  19726. * "displayStart": 20
  19727. * } );
  19728. * } )
  19729. */
  19730. "iDisplayStart": 0,
  19731. /**
  19732. * By default DataTables allows keyboard navigation of the table (sorting, paging,
  19733. * and filtering) by adding a `tabindex` attribute to the required elements. This
  19734. * allows you to tab through the controls and press the enter key to activate them.
  19735. * The tabindex is default 0, meaning that the tab follows the flow of the document.
  19736. * You can overrule this using this parameter if you wish. Use a value of -1 to
  19737. * disable built-in keyboard navigation.
  19738. * @type int
  19739. * @default 0
  19740. *
  19741. * @dtopt Options
  19742. * @name DataTable.defaults.tabIndex
  19743. *
  19744. * @example
  19745. * $(document).ready( function() {
  19746. * $('#example').dataTable( {
  19747. * "tabIndex": 1
  19748. * } );
  19749. * } );
  19750. */
  19751. "iTabIndex": 0,
  19752. /**
  19753. * Classes that DataTables assigns to the various components and features
  19754. * that it adds to the HTML table. This allows classes to be configured
  19755. * during initialisation in addition to through the static
  19756. * {@link DataTable.ext.oStdClasses} object).
  19757. * @namespace
  19758. * @name DataTable.defaults.classes
  19759. */
  19760. "oClasses": {},
  19761. /**
  19762. * All strings that DataTables uses in the user interface that it creates
  19763. * are defined in this object, allowing you to modified them individually or
  19764. * completely replace them all as required.
  19765. * @namespace
  19766. * @name DataTable.defaults.language
  19767. */
  19768. "oLanguage": {
  19769. /**
  19770. * Strings that are used for WAI-ARIA labels and controls only (these are not
  19771. * actually visible on the page, but will be read by screenreaders, and thus
  19772. * must be internationalised as well).
  19773. * @namespace
  19774. * @name DataTable.defaults.language.aria
  19775. */
  19776. "oAria": {
  19777. /**
  19778. * ARIA label that is added to the table headers when the column may be
  19779. * sorted ascending by activing the column (click or return when focused).
  19780. * Note that the column header is prefixed to this string.
  19781. * @type string
  19782. * @default : activate to sort column ascending
  19783. *
  19784. * @dtopt Language
  19785. * @name DataTable.defaults.language.aria.sortAscending
  19786. *
  19787. * @example
  19788. * $(document).ready( function() {
  19789. * $('#example').dataTable( {
  19790. * "language": {
  19791. * "aria": {
  19792. * "sortAscending": " - click/return to sort ascending"
  19793. * }
  19794. * }
  19795. * } );
  19796. * } );
  19797. */
  19798. "sSortAscending": ": activate to sort column ascending",
  19799. /**
  19800. * ARIA label that is added to the table headers when the column may be
  19801. * sorted descending by activing the column (click or return when focused).
  19802. * Note that the column header is prefixed to this string.
  19803. * @type string
  19804. * @default : activate to sort column ascending
  19805. *
  19806. * @dtopt Language
  19807. * @name DataTable.defaults.language.aria.sortDescending
  19808. *
  19809. * @example
  19810. * $(document).ready( function() {
  19811. * $('#example').dataTable( {
  19812. * "language": {
  19813. * "aria": {
  19814. * "sortDescending": " - click/return to sort descending"
  19815. * }
  19816. * }
  19817. * } );
  19818. * } );
  19819. */
  19820. "sSortDescending": ": activate to sort column descending"
  19821. },
  19822. /**
  19823. * Pagination string used by DataTables for the built-in pagination
  19824. * control types.
  19825. * @namespace
  19826. * @name DataTable.defaults.language.paginate
  19827. */
  19828. "oPaginate": {
  19829. /**
  19830. * Text to use when using the 'full_numbers' type of pagination for the
  19831. * button to take the user to the first page.
  19832. * @type string
  19833. * @default First
  19834. *
  19835. * @dtopt Language
  19836. * @name DataTable.defaults.language.paginate.first
  19837. *
  19838. * @example
  19839. * $(document).ready( function() {
  19840. * $('#example').dataTable( {
  19841. * "language": {
  19842. * "paginate": {
  19843. * "first": "First page"
  19844. * }
  19845. * }
  19846. * } );
  19847. * } );
  19848. */
  19849. "sFirst": "First",
  19850. /**
  19851. * Text to use when using the 'full_numbers' type of pagination for the
  19852. * button to take the user to the last page.
  19853. * @type string
  19854. * @default Last
  19855. *
  19856. * @dtopt Language
  19857. * @name DataTable.defaults.language.paginate.last
  19858. *
  19859. * @example
  19860. * $(document).ready( function() {
  19861. * $('#example').dataTable( {
  19862. * "language": {
  19863. * "paginate": {
  19864. * "last": "Last page"
  19865. * }
  19866. * }
  19867. * } );
  19868. * } );
  19869. */
  19870. "sLast": "Last",
  19871. /**
  19872. * Text to use for the 'next' pagination button (to take the user to the
  19873. * next page).
  19874. * @type string
  19875. * @default Next
  19876. *
  19877. * @dtopt Language
  19878. * @name DataTable.defaults.language.paginate.next
  19879. *
  19880. * @example
  19881. * $(document).ready( function() {
  19882. * $('#example').dataTable( {
  19883. * "language": {
  19884. * "paginate": {
  19885. * "next": "Next page"
  19886. * }
  19887. * }
  19888. * } );
  19889. * } );
  19890. */
  19891. "sNext": "Next",
  19892. /**
  19893. * Text to use for the 'previous' pagination button (to take the user to
  19894. * the previous page).
  19895. * @type string
  19896. * @default Previous
  19897. *
  19898. * @dtopt Language
  19899. * @name DataTable.defaults.language.paginate.previous
  19900. *
  19901. * @example
  19902. * $(document).ready( function() {
  19903. * $('#example').dataTable( {
  19904. * "language": {
  19905. * "paginate": {
  19906. * "previous": "Previous page"
  19907. * }
  19908. * }
  19909. * } );
  19910. * } );
  19911. */
  19912. "sPrevious": "Previous"
  19913. },
  19914. /**
  19915. * This string is shown in preference to `zeroRecords` when the table is
  19916. * empty of data (regardless of filtering). Note that this is an optional
  19917. * parameter - if it is not given, the value of `zeroRecords` will be used
  19918. * instead (either the default or given value).
  19919. * @type string
  19920. * @default No data available in table
  19921. *
  19922. * @dtopt Language
  19923. * @name DataTable.defaults.language.emptyTable
  19924. *
  19925. * @example
  19926. * $(document).ready( function() {
  19927. * $('#example').dataTable( {
  19928. * "language": {
  19929. * "emptyTable": "No data available in table"
  19930. * }
  19931. * } );
  19932. * } );
  19933. */
  19934. "sEmptyTable": "No data available in table",
  19935. /**
  19936. * This string gives information to the end user about the information
  19937. * that is current on display on the page. The following tokens can be
  19938. * used in the string and will be dynamically replaced as the table
  19939. * display updates. This tokens can be placed anywhere in the string, or
  19940. * removed as needed by the language requires:
  19941. *
  19942. * * `\_START\_` - Display index of the first record on the current page
  19943. * * `\_END\_` - Display index of the last record on the current page
  19944. * * `\_TOTAL\_` - Number of records in the table after filtering
  19945. * * `\_MAX\_` - Number of records in the table without filtering
  19946. * * `\_PAGE\_` - Current page number
  19947. * * `\_PAGES\_` - Total number of pages of data in the table
  19948. *
  19949. * @type string
  19950. * @default Showing _START_ to _END_ of _TOTAL_ entries
  19951. *
  19952. * @dtopt Language
  19953. * @name DataTable.defaults.language.info
  19954. *
  19955. * @example
  19956. * $(document).ready( function() {
  19957. * $('#example').dataTable( {
  19958. * "language": {
  19959. * "info": "Showing page _PAGE_ of _PAGES_"
  19960. * }
  19961. * } );
  19962. * } );
  19963. */
  19964. "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
  19965. /**
  19966. * Display information string for when the table is empty. Typically the
  19967. * format of this string should match `info`.
  19968. * @type string
  19969. * @default Showing 0 to 0 of 0 entries
  19970. *
  19971. * @dtopt Language
  19972. * @name DataTable.defaults.language.infoEmpty
  19973. *
  19974. * @example
  19975. * $(document).ready( function() {
  19976. * $('#example').dataTable( {
  19977. * "language": {
  19978. * "infoEmpty": "No entries to show"
  19979. * }
  19980. * } );
  19981. * } );
  19982. */
  19983. "sInfoEmpty": "Showing 0 to 0 of 0 entries",
  19984. /**
  19985. * When a user filters the information in a table, this string is appended
  19986. * to the information (`info`) to give an idea of how strong the filtering
  19987. * is. The variable _MAX_ is dynamically updated.
  19988. * @type string
  19989. * @default (filtered from _MAX_ total entries)
  19990. *
  19991. * @dtopt Language
  19992. * @name DataTable.defaults.language.infoFiltered
  19993. *
  19994. * @example
  19995. * $(document).ready( function() {
  19996. * $('#example').dataTable( {
  19997. * "language": {
  19998. * "infoFiltered": " - filtering from _MAX_ records"
  19999. * }
  20000. * } );
  20001. * } );
  20002. */
  20003. "sInfoFiltered": "(filtered from _MAX_ total entries)",
  20004. /**
  20005. * If can be useful to append extra information to the info string at times,
  20006. * and this variable does exactly that. This information will be appended to
  20007. * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are
  20008. * being used) at all times.
  20009. * @type string
  20010. * @default <i>Empty string</i>
  20011. *
  20012. * @dtopt Language
  20013. * @name DataTable.defaults.language.infoPostFix
  20014. *
  20015. * @example
  20016. * $(document).ready( function() {
  20017. * $('#example').dataTable( {
  20018. * "language": {
  20019. * "infoPostFix": "All records shown are derived from real information."
  20020. * }
  20021. * } );
  20022. * } );
  20023. */
  20024. "sInfoPostFix": "",
  20025. /**
  20026. * This decimal place operator is a little different from the other
  20027. * language options since DataTables doesn't output floating point
  20028. * numbers, so it won't ever use this for display of a number. Rather,
  20029. * what this parameter does is modify the sort methods of the table so
  20030. * that numbers which are in a format which has a character other than
  20031. * a period (`.`) as a decimal place will be sorted numerically.
  20032. *
  20033. * Note that numbers with different decimal places cannot be shown in
  20034. * the same table and still be sortable, the table must be consistent.
  20035. * However, multiple different tables on the page can use different
  20036. * decimal place characters.
  20037. * @type string
  20038. * @default
  20039. *
  20040. * @dtopt Language
  20041. * @name DataTable.defaults.language.decimal
  20042. *
  20043. * @example
  20044. * $(document).ready( function() {
  20045. * $('#example').dataTable( {
  20046. * "language": {
  20047. * "decimal": ","
  20048. * "thousands": "."
  20049. * }
  20050. * } );
  20051. * } );
  20052. */
  20053. "sDecimal": "",
  20054. /**
  20055. * DataTables has a build in number formatter (`formatNumber`) which is
  20056. * used to format large numbers that are used in the table information.
  20057. * By default a comma is used, but this can be trivially changed to any
  20058. * character you wish with this parameter.
  20059. * @type string
  20060. * @default ,
  20061. *
  20062. * @dtopt Language
  20063. * @name DataTable.defaults.language.thousands
  20064. *
  20065. * @example
  20066. * $(document).ready( function() {
  20067. * $('#example').dataTable( {
  20068. * "language": {
  20069. * "thousands": "'"
  20070. * }
  20071. * } );
  20072. * } );
  20073. */
  20074. "sThousands": ",",
  20075. /**
  20076. * Detail the action that will be taken when the drop down menu for the
  20077. * pagination length option is changed. The '_MENU_' variable is replaced
  20078. * with a default select list of 10, 25, 50 and 100, and can be replaced
  20079. * with a custom select box if required.
  20080. * @type string
  20081. * @default Show _MENU_ entries
  20082. *
  20083. * @dtopt Language
  20084. * @name DataTable.defaults.language.lengthMenu
  20085. *
  20086. * @example
  20087. * // Language change only
  20088. * $(document).ready( function() {
  20089. * $('#example').dataTable( {
  20090. * "language": {
  20091. * "lengthMenu": "Display _MENU_ records"
  20092. * }
  20093. * } );
  20094. * } );
  20095. *
  20096. * @example
  20097. * // Language and options change
  20098. * $(document).ready( function() {
  20099. * $('#example').dataTable( {
  20100. * "language": {
  20101. * "lengthMenu": 'Display <select>'+
  20102. * '<option value="10">10</option>'+
  20103. * '<option value="20">20</option>'+
  20104. * '<option value="30">30</option>'+
  20105. * '<option value="40">40</option>'+
  20106. * '<option value="50">50</option>'+
  20107. * '<option value="-1">All</option>'+
  20108. * '</select> records'
  20109. * }
  20110. * } );
  20111. * } );
  20112. */
  20113. "sLengthMenu": "Show _MENU_ entries",
  20114. /**
  20115. * When using Ajax sourced data and during the first draw when DataTables is
  20116. * gathering the data, this message is shown in an empty row in the table to
  20117. * indicate to the end user the the data is being loaded. Note that this
  20118. * parameter is not used when loading data by server-side processing, just
  20119. * Ajax sourced data with client-side processing.
  20120. * @type string
  20121. * @default Loading...
  20122. *
  20123. * @dtopt Language
  20124. * @name DataTable.defaults.language.loadingRecords
  20125. *
  20126. * @example
  20127. * $(document).ready( function() {
  20128. * $('#example').dataTable( {
  20129. * "language": {
  20130. * "loadingRecords": "Please wait - loading..."
  20131. * }
  20132. * } );
  20133. * } );
  20134. */
  20135. "sLoadingRecords": "Loading...",
  20136. /**
  20137. * Text which is displayed when the table is processing a user action
  20138. * (usually a sort command or similar).
  20139. * @type string
  20140. * @default Processing...
  20141. *
  20142. * @dtopt Language
  20143. * @name DataTable.defaults.language.processing
  20144. *
  20145. * @example
  20146. * $(document).ready( function() {
  20147. * $('#example').dataTable( {
  20148. * "language": {
  20149. * "processing": "DataTables is currently busy"
  20150. * }
  20151. * } );
  20152. * } );
  20153. */
  20154. "sProcessing": "Processing...",
  20155. /**
  20156. * Details the actions that will be taken when the user types into the
  20157. * filtering input text box. The variable "_INPUT_", if used in the string,
  20158. * is replaced with the HTML text box for the filtering input allowing
  20159. * control over where it appears in the string. If "_INPUT_" is not given
  20160. * then the input box is appended to the string automatically.
  20161. * @type string
  20162. * @default Search:
  20163. *
  20164. * @dtopt Language
  20165. * @name DataTable.defaults.language.search
  20166. *
  20167. * @example
  20168. * // Input text box will be appended at the end automatically
  20169. * $(document).ready( function() {
  20170. * $('#example').dataTable( {
  20171. * "language": {
  20172. * "search": "Filter records:"
  20173. * }
  20174. * } );
  20175. * } );
  20176. *
  20177. * @example
  20178. * // Specify where the filter should appear
  20179. * $(document).ready( function() {
  20180. * $('#example').dataTable( {
  20181. * "language": {
  20182. * "search": "Apply filter _INPUT_ to table"
  20183. * }
  20184. * } );
  20185. * } );
  20186. */
  20187. "sSearch": "Search:",
  20188. /**
  20189. * Assign a `placeholder` attribute to the search `input` element
  20190. * @type string
  20191. * @default
  20192. *
  20193. * @dtopt Language
  20194. * @name DataTable.defaults.language.searchPlaceholder
  20195. */
  20196. "sSearchPlaceholder": "",
  20197. /**
  20198. * All of the language information can be stored in a file on the
  20199. * server-side, which DataTables will look up if this parameter is passed.
  20200. * It must store the URL of the language file, which is in a JSON format,
  20201. * and the object has the same properties as the oLanguage object in the
  20202. * initialiser object (i.e. the above parameters). Please refer to one of
  20203. * the example language files to see how this works in action.
  20204. * @type string
  20205. * @default <i>Empty string - i.e. disabled</i>
  20206. *
  20207. * @dtopt Language
  20208. * @name DataTable.defaults.language.url
  20209. *
  20210. * @example
  20211. * $(document).ready( function() {
  20212. * $('#example').dataTable( {
  20213. * "language": {
  20214. * "url": "http://www.sprymedia.co.uk/dataTables/lang.txt"
  20215. * }
  20216. * } );
  20217. * } );
  20218. */
  20219. "sUrl": "",
  20220. /**
  20221. * Text shown inside the table records when the is no information to be
  20222. * displayed after filtering. `emptyTable` is shown when there is simply no
  20223. * information in the table at all (regardless of filtering).
  20224. * @type string
  20225. * @default No matching records found
  20226. *
  20227. * @dtopt Language
  20228. * @name DataTable.defaults.language.zeroRecords
  20229. *
  20230. * @example
  20231. * $(document).ready( function() {
  20232. * $('#example').dataTable( {
  20233. * "language": {
  20234. * "zeroRecords": "No records to display"
  20235. * }
  20236. * } );
  20237. * } );
  20238. */
  20239. "sZeroRecords": "No matching records found"
  20240. },
  20241. /**
  20242. * This parameter allows you to have define the global filtering state at
  20243. * initialisation time. As an object the `search` parameter must be
  20244. * defined, but all other parameters are optional. When `regex` is true,
  20245. * the search string will be treated as a regular expression, when false
  20246. * (default) it will be treated as a straight string. When `smart`
  20247. * DataTables will use it's smart filtering methods (to word match at
  20248. * any point in the data), when false this will not be done.
  20249. * @namespace
  20250. * @extends DataTable.models.oSearch
  20251. *
  20252. * @dtopt Options
  20253. * @name DataTable.defaults.search
  20254. *
  20255. * @example
  20256. * $(document).ready( function() {
  20257. * $('#example').dataTable( {
  20258. * "search": {"search": "Initial search"}
  20259. * } );
  20260. * } )
  20261. */
  20262. "oSearch": $.extend( {}, DataTable.models.oSearch ),
  20263. /**
  20264. * __Deprecated__ The functionality provided by this parameter has now been
  20265. * superseded by that provided through `ajax`, which should be used instead.
  20266. *
  20267. * By default DataTables will look for the property `data` (or `aaData` for
  20268. * compatibility with DataTables 1.9-) when obtaining data from an Ajax
  20269. * source or for server-side processing - this parameter allows that
  20270. * property to be changed. You can use Javascript dotted object notation to
  20271. * get a data source for multiple levels of nesting.
  20272. * @type string
  20273. * @default data
  20274. *
  20275. * @dtopt Options
  20276. * @dtopt Server-side
  20277. * @name DataTable.defaults.ajaxDataProp
  20278. *
  20279. * @deprecated 1.10. Please use `ajax` for this functionality now.
  20280. */
  20281. "sAjaxDataProp": "data",
  20282. /**
  20283. * __Deprecated__ The functionality provided by this parameter has now been
  20284. * superseded by that provided through `ajax`, which should be used instead.
  20285. *
  20286. * You can instruct DataTables to load data from an external
  20287. * source using this parameter (use aData if you want to pass data in you
  20288. * already have). Simply provide a url a JSON object can be obtained from.
  20289. * @type string
  20290. * @default null
  20291. *
  20292. * @dtopt Options
  20293. * @dtopt Server-side
  20294. * @name DataTable.defaults.ajaxSource
  20295. *
  20296. * @deprecated 1.10. Please use `ajax` for this functionality now.
  20297. */
  20298. "sAjaxSource": null,
  20299. /**
  20300. * This initialisation variable allows you to specify exactly where in the
  20301. * DOM you want DataTables to inject the various controls it adds to the page
  20302. * (for example you might want the pagination controls at the top of the
  20303. * table). DIV elements (with or without a custom class) can also be added to
  20304. * aid styling. The follow syntax is used:
  20305. * <ul>
  20306. * <li>The following options are allowed:
  20307. * <ul>
  20308. * <li>'l' - Length changing</li>
  20309. * <li>'f' - Filtering input</li>
  20310. * <li>'t' - The table!</li>
  20311. * <li>'i' - Information</li>
  20312. * <li>'p' - Pagination</li>
  20313. * <li>'r' - pRocessing</li>
  20314. * </ul>
  20315. * </li>
  20316. * <li>The following constants are allowed:
  20317. * <ul>
  20318. * <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
  20319. * <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
  20320. * </ul>
  20321. * </li>
  20322. * <li>The following syntax is expected:
  20323. * <ul>
  20324. * <li>'&lt;' and '&gt;' - div elements</li>
  20325. * <li>'&lt;"class" and '&gt;' - div with a class</li>
  20326. * <li>'&lt;"#id" and '&gt;' - div with an ID</li>
  20327. * </ul>
  20328. * </li>
  20329. * <li>Examples:
  20330. * <ul>
  20331. * <li>'&lt;"wrapper"flipt&gt;'</li>
  20332. * <li>'&lt;lf&lt;t&gt;ip&gt;'</li>
  20333. * </ul>
  20334. * </li>
  20335. * </ul>
  20336. * @type string
  20337. * @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>
  20338. * <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i>
  20339. *
  20340. * @dtopt Options
  20341. * @name DataTable.defaults.dom
  20342. *
  20343. * @example
  20344. * $(document).ready( function() {
  20345. * $('#example').dataTable( {
  20346. * "dom": '&lt;"top"i&gt;rt&lt;"bottom"flp&gt;&lt;"clear"&gt;'
  20347. * } );
  20348. * } );
  20349. */
  20350. "sDom": "lfrtip",
  20351. /**
  20352. * Search delay option. This will throttle full table searches that use the
  20353. * DataTables provided search input element (it does not effect calls to
  20354. * `dt-api search()`, providing a delay before the search is made.
  20355. * @type integer
  20356. * @default 0
  20357. *
  20358. * @dtopt Options
  20359. * @name DataTable.defaults.searchDelay
  20360. *
  20361. * @example
  20362. * $(document).ready( function() {
  20363. * $('#example').dataTable( {
  20364. * "searchDelay": 200
  20365. * } );
  20366. * } )
  20367. */
  20368. "searchDelay": null,
  20369. /**
  20370. * DataTables features six different built-in options for the buttons to
  20371. * display for pagination control:
  20372. *
  20373. * * `numbers` - Page number buttons only
  20374. * * `simple` - 'Previous' and 'Next' buttons only
  20375. * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
  20376. * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
  20377. * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers
  20378. * * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers
  20379. *
  20380. * Further methods can be added using {@link DataTable.ext.oPagination}.
  20381. * @type string
  20382. * @default simple_numbers
  20383. *
  20384. * @dtopt Options
  20385. * @name DataTable.defaults.pagingType
  20386. *
  20387. * @example
  20388. * $(document).ready( function() {
  20389. * $('#example').dataTable( {
  20390. * "pagingType": "full_numbers"
  20391. * } );
  20392. * } )
  20393. */
  20394. "sPaginationType": "simple_numbers",
  20395. /**
  20396. * Enable horizontal scrolling. When a table is too wide to fit into a
  20397. * certain layout, or you have a large number of columns in the table, you
  20398. * can enable x-scrolling to show the table in a viewport, which can be
  20399. * scrolled. This property can be `true` which will allow the table to
  20400. * scroll horizontally when needed, or any CSS unit, or a number (in which
  20401. * case it will be treated as a pixel measurement). Setting as simply `true`
  20402. * is recommended.
  20403. * @type boolean|string
  20404. * @default <i>blank string - i.e. disabled</i>
  20405. *
  20406. * @dtopt Features
  20407. * @name DataTable.defaults.scrollX
  20408. *
  20409. * @example
  20410. * $(document).ready( function() {
  20411. * $('#example').dataTable( {
  20412. * "scrollX": true,
  20413. * "scrollCollapse": true
  20414. * } );
  20415. * } );
  20416. */
  20417. "sScrollX": "",
  20418. /**
  20419. * This property can be used to force a DataTable to use more width than it
  20420. * might otherwise do when x-scrolling is enabled. For example if you have a
  20421. * table which requires to be well spaced, this parameter is useful for
  20422. * "over-sizing" the table, and thus forcing scrolling. This property can by
  20423. * any CSS unit, or a number (in which case it will be treated as a pixel
  20424. * measurement).
  20425. * @type string
  20426. * @default <i>blank string - i.e. disabled</i>
  20427. *
  20428. * @dtopt Options
  20429. * @name DataTable.defaults.scrollXInner
  20430. *
  20431. * @example
  20432. * $(document).ready( function() {
  20433. * $('#example').dataTable( {
  20434. * "scrollX": "100%",
  20435. * "scrollXInner": "110%"
  20436. * } );
  20437. * } );
  20438. */
  20439. "sScrollXInner": "",
  20440. /**
  20441. * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
  20442. * to the given height, and enable scrolling for any data which overflows the
  20443. * current viewport. This can be used as an alternative to paging to display
  20444. * a lot of data in a small area (although paging and scrolling can both be
  20445. * enabled at the same time). This property can be any CSS unit, or a number
  20446. * (in which case it will be treated as a pixel measurement).
  20447. * @type string
  20448. * @default <i>blank string - i.e. disabled</i>
  20449. *
  20450. * @dtopt Features
  20451. * @name DataTable.defaults.scrollY
  20452. *
  20453. * @example
  20454. * $(document).ready( function() {
  20455. * $('#example').dataTable( {
  20456. * "scrollY": "200px",
  20457. * "paginate": false
  20458. * } );
  20459. * } );
  20460. */
  20461. "sScrollY": "",
  20462. /**
  20463. * __Deprecated__ The functionality provided by this parameter has now been
  20464. * superseded by that provided through `ajax`, which should be used instead.
  20465. *
  20466. * Set the HTTP method that is used to make the Ajax call for server-side
  20467. * processing or Ajax sourced data.
  20468. * @type string
  20469. * @default GET
  20470. *
  20471. * @dtopt Options
  20472. * @dtopt Server-side
  20473. * @name DataTable.defaults.serverMethod
  20474. *
  20475. * @deprecated 1.10. Please use `ajax` for this functionality now.
  20476. */
  20477. "sServerMethod": "GET",
  20478. /**
  20479. * DataTables makes use of renderers when displaying HTML elements for
  20480. * a table. These renderers can be added or modified by plug-ins to
  20481. * generate suitable mark-up for a site. For example the Bootstrap
  20482. * integration plug-in for DataTables uses a paging button renderer to
  20483. * display pagination buttons in the mark-up required by Bootstrap.
  20484. *
  20485. * For further information about the renderers available see
  20486. * DataTable.ext.renderer
  20487. * @type string|object
  20488. * @default null
  20489. *
  20490. * @name DataTable.defaults.renderer
  20491. *
  20492. */
  20493. "renderer": null,
  20494. /**
  20495. * Set the data property name that DataTables should use to get a row's id
  20496. * to set as the `id` property in the node.
  20497. * @type string
  20498. * @default DT_RowId
  20499. *
  20500. * @name DataTable.defaults.rowId
  20501. */
  20502. "rowId": "DT_RowId"
  20503. };
  20504. _fnHungarianMap( DataTable.defaults );
  20505. /*
  20506. * Developer note - See note in model.defaults.js about the use of Hungarian
  20507. * notation and camel case.
  20508. */
  20509. /**
  20510. * Column options that can be given to DataTables at initialisation time.
  20511. * @namespace
  20512. */
  20513. DataTable.defaults.column = {
  20514. /**
  20515. * Define which column(s) an order will occur on for this column. This
  20516. * allows a column's ordering to take multiple columns into account when
  20517. * doing a sort or use the data from a different column. For example first
  20518. * name / last name columns make sense to do a multi-column sort over the
  20519. * two columns.
  20520. * @type array|int
  20521. * @default null <i>Takes the value of the column index automatically</i>
  20522. *
  20523. * @name DataTable.defaults.column.orderData
  20524. * @dtopt Columns
  20525. *
  20526. * @example
  20527. * // Using `columnDefs`
  20528. * $(document).ready( function() {
  20529. * $('#example').dataTable( {
  20530. * "columnDefs": [
  20531. * { "orderData": [ 0, 1 ], "targets": [ 0 ] },
  20532. * { "orderData": [ 1, 0 ], "targets": [ 1 ] },
  20533. * { "orderData": 2, "targets": [ 2 ] }
  20534. * ]
  20535. * } );
  20536. * } );
  20537. *
  20538. * @example
  20539. * // Using `columns`
  20540. * $(document).ready( function() {
  20541. * $('#example').dataTable( {
  20542. * "columns": [
  20543. * { "orderData": [ 0, 1 ] },
  20544. * { "orderData": [ 1, 0 ] },
  20545. * { "orderData": 2 },
  20546. * null,
  20547. * null
  20548. * ]
  20549. * } );
  20550. * } );
  20551. */
  20552. "aDataSort": null,
  20553. "iDataSort": -1,
  20554. /**
  20555. * You can control the default ordering direction, and even alter the
  20556. * behaviour of the sort handler (i.e. only allow ascending ordering etc)
  20557. * using this parameter.
  20558. * @type array
  20559. * @default [ 'asc', 'desc' ]
  20560. *
  20561. * @name DataTable.defaults.column.orderSequence
  20562. * @dtopt Columns
  20563. *
  20564. * @example
  20565. * // Using `columnDefs`
  20566. * $(document).ready( function() {
  20567. * $('#example').dataTable( {
  20568. * "columnDefs": [
  20569. * { "orderSequence": [ "asc" ], "targets": [ 1 ] },
  20570. * { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] },
  20571. * { "orderSequence": [ "desc" ], "targets": [ 3 ] }
  20572. * ]
  20573. * } );
  20574. * } );
  20575. *
  20576. * @example
  20577. * // Using `columns`
  20578. * $(document).ready( function() {
  20579. * $('#example').dataTable( {
  20580. * "columns": [
  20581. * null,
  20582. * { "orderSequence": [ "asc" ] },
  20583. * { "orderSequence": [ "desc", "asc", "asc" ] },
  20584. * { "orderSequence": [ "desc" ] },
  20585. * null
  20586. * ]
  20587. * } );
  20588. * } );
  20589. */
  20590. "asSorting": [ 'asc', 'desc' ],
  20591. /**
  20592. * Enable or disable filtering on the data in this column.
  20593. * @type boolean
  20594. * @default true
  20595. *
  20596. * @name DataTable.defaults.column.searchable
  20597. * @dtopt Columns
  20598. *
  20599. * @example
  20600. * // Using `columnDefs`
  20601. * $(document).ready( function() {
  20602. * $('#example').dataTable( {
  20603. * "columnDefs": [
  20604. * { "searchable": false, "targets": [ 0 ] }
  20605. * ] } );
  20606. * } );
  20607. *
  20608. * @example
  20609. * // Using `columns`
  20610. * $(document).ready( function() {
  20611. * $('#example').dataTable( {
  20612. * "columns": [
  20613. * { "searchable": false },
  20614. * null,
  20615. * null,
  20616. * null,
  20617. * null
  20618. * ] } );
  20619. * } );
  20620. */
  20621. "bSearchable": true,
  20622. /**
  20623. * Enable or disable ordering on this column.
  20624. * @type boolean
  20625. * @default true
  20626. *
  20627. * @name DataTable.defaults.column.orderable
  20628. * @dtopt Columns
  20629. *
  20630. * @example
  20631. * // Using `columnDefs`
  20632. * $(document).ready( function() {
  20633. * $('#example').dataTable( {
  20634. * "columnDefs": [
  20635. * { "orderable": false, "targets": [ 0 ] }
  20636. * ] } );
  20637. * } );
  20638. *
  20639. * @example
  20640. * // Using `columns`
  20641. * $(document).ready( function() {
  20642. * $('#example').dataTable( {
  20643. * "columns": [
  20644. * { "orderable": false },
  20645. * null,
  20646. * null,
  20647. * null,
  20648. * null
  20649. * ] } );
  20650. * } );
  20651. */
  20652. "bSortable": true,
  20653. /**
  20654. * Enable or disable the display of this column.
  20655. * @type boolean
  20656. * @default true
  20657. *
  20658. * @name DataTable.defaults.column.visible
  20659. * @dtopt Columns
  20660. *
  20661. * @example
  20662. * // Using `columnDefs`
  20663. * $(document).ready( function() {
  20664. * $('#example').dataTable( {
  20665. * "columnDefs": [
  20666. * { "visible": false, "targets": [ 0 ] }
  20667. * ] } );
  20668. * } );
  20669. *
  20670. * @example
  20671. * // Using `columns`
  20672. * $(document).ready( function() {
  20673. * $('#example').dataTable( {
  20674. * "columns": [
  20675. * { "visible": false },
  20676. * null,
  20677. * null,
  20678. * null,
  20679. * null
  20680. * ] } );
  20681. * } );
  20682. */
  20683. "bVisible": true,
  20684. /**
  20685. * Developer definable function that is called whenever a cell is created (Ajax source,
  20686. * etc) or processed for input (DOM source). This can be used as a compliment to mRender
  20687. * allowing you to modify the DOM element (add background colour for example) when the
  20688. * element is available.
  20689. * @type function
  20690. * @param {element} td The TD node that has been created
  20691. * @param {*} cellData The Data for the cell
  20692. * @param {array|object} rowData The data for the whole row
  20693. * @param {int} row The row index for the aoData data store
  20694. * @param {int} col The column index for aoColumns
  20695. *
  20696. * @name DataTable.defaults.column.createdCell
  20697. * @dtopt Columns
  20698. *
  20699. * @example
  20700. * $(document).ready( function() {
  20701. * $('#example').dataTable( {
  20702. * "columnDefs": [ {
  20703. * "targets": [3],
  20704. * "createdCell": function (td, cellData, rowData, row, col) {
  20705. * if ( cellData == "1.7" ) {
  20706. * $(td).css('color', 'blue')
  20707. * }
  20708. * }
  20709. * } ]
  20710. * });
  20711. * } );
  20712. */
  20713. "fnCreatedCell": null,
  20714. /**
  20715. * This parameter has been replaced by `data` in DataTables to ensure naming
  20716. * consistency. `dataProp` can still be used, as there is backwards
  20717. * compatibility in DataTables for this option, but it is strongly
  20718. * recommended that you use `data` in preference to `dataProp`.
  20719. * @name DataTable.defaults.column.dataProp
  20720. */
  20721. /**
  20722. * This property can be used to read data from any data source property,
  20723. * including deeply nested objects / properties. `data` can be given in a
  20724. * number of different ways which effect its behaviour:
  20725. *
  20726. * * `integer` - treated as an array index for the data source. This is the
  20727. * default that DataTables uses (incrementally increased for each column).
  20728. * * `string` - read an object property from the data source. There are
  20729. * three 'special' options that can be used in the string to alter how
  20730. * DataTables reads the data from the source object:
  20731. * * `.` - Dotted Javascript notation. Just as you use a `.` in
  20732. * Javascript to read from nested objects, so to can the options
  20733. * specified in `data`. For example: `browser.version` or
  20734. * `browser.name`. If your object parameter name contains a period, use
  20735. * `\\` to escape it - i.e. `first\\.name`.
  20736. * * `[]` - Array notation. DataTables can automatically combine data
  20737. * from and array source, joining the data with the characters provided
  20738. * between the two brackets. For example: `name[, ]` would provide a
  20739. * comma-space separated list from the source array. If no characters
  20740. * are provided between the brackets, the original array source is
  20741. * returned.
  20742. * * `()` - Function notation. Adding `()` to the end of a parameter will
  20743. * execute a function of the name given. For example: `browser()` for a
  20744. * simple function on the data source, `browser.version()` for a
  20745. * function in a nested property or even `browser().version` to get an
  20746. * object property if the function called returns an object. Note that
  20747. * function notation is recommended for use in `render` rather than
  20748. * `data` as it is much simpler to use as a renderer.
  20749. * * `null` - use the original data source for the row rather than plucking
  20750. * data directly from it. This action has effects on two other
  20751. * initialisation options:
  20752. * * `defaultContent` - When null is given as the `data` option and
  20753. * `defaultContent` is specified for the column, the value defined by
  20754. * `defaultContent` will be used for the cell.
  20755. * * `render` - When null is used for the `data` option and the `render`
  20756. * option is specified for the column, the whole data source for the
  20757. * row is used for the renderer.
  20758. * * `function` - the function given will be executed whenever DataTables
  20759. * needs to set or get the data for a cell in the column. The function
  20760. * takes three parameters:
  20761. * * Parameters:
  20762. * * `{array|object}` The data source for the row
  20763. * * `{string}` The type call data requested - this will be 'set' when
  20764. * setting data or 'filter', 'display', 'type', 'sort' or undefined
  20765. * when gathering data. Note that when `undefined` is given for the
  20766. * type DataTables expects to get the raw data for the object back<
  20767. * * `{*}` Data to set when the second parameter is 'set'.
  20768. * * Return:
  20769. * * The return value from the function is not required when 'set' is
  20770. * the type of call, but otherwise the return is what will be used
  20771. * for the data requested.
  20772. *
  20773. * Note that `data` is a getter and setter option. If you just require
  20774. * formatting of data for output, you will likely want to use `render` which
  20775. * is simply a getter and thus simpler to use.
  20776. *
  20777. * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
  20778. * name change reflects the flexibility of this property and is consistent
  20779. * with the naming of mRender. If 'mDataProp' is given, then it will still
  20780. * be used by DataTables, as it automatically maps the old name to the new
  20781. * if required.
  20782. *
  20783. * @type string|int|function|null
  20784. * @default null <i>Use automatically calculated column index</i>
  20785. *
  20786. * @name DataTable.defaults.column.data
  20787. * @dtopt Columns
  20788. *
  20789. * @example
  20790. * // Read table data from objects
  20791. * // JSON structure for each row:
  20792. * // {
  20793. * // "engine": {value},
  20794. * // "browser": {value},
  20795. * // "platform": {value},
  20796. * // "version": {value},
  20797. * // "grade": {value}
  20798. * // }
  20799. * $(document).ready( function() {
  20800. * $('#example').dataTable( {
  20801. * "ajaxSource": "sources/objects.txt",
  20802. * "columns": [
  20803. * { "data": "engine" },
  20804. * { "data": "browser" },
  20805. * { "data": "platform" },
  20806. * { "data": "version" },
  20807. * { "data": "grade" }
  20808. * ]
  20809. * } );
  20810. * } );
  20811. *
  20812. * @example
  20813. * // Read information from deeply nested objects
  20814. * // JSON structure for each row:
  20815. * // {
  20816. * // "engine": {value},
  20817. * // "browser": {value},
  20818. * // "platform": {
  20819. * // "inner": {value}
  20820. * // },
  20821. * // "details": [
  20822. * // {value}, {value}
  20823. * // ]
  20824. * // }
  20825. * $(document).ready( function() {
  20826. * $('#example').dataTable( {
  20827. * "ajaxSource": "sources/deep.txt",
  20828. * "columns": [
  20829. * { "data": "engine" },
  20830. * { "data": "browser" },
  20831. * { "data": "platform.inner" },
  20832. * { "data": "platform.details.0" },
  20833. * { "data": "platform.details.1" }
  20834. * ]
  20835. * } );
  20836. * } );
  20837. *
  20838. * @example
  20839. * // Using `data` as a function to provide different information for
  20840. * // sorting, filtering and display. In this case, currency (price)
  20841. * $(document).ready( function() {
  20842. * $('#example').dataTable( {
  20843. * "columnDefs": [ {
  20844. * "targets": [ 0 ],
  20845. * "data": function ( source, type, val ) {
  20846. * if (type === 'set') {
  20847. * source.price = val;
  20848. * // Store the computed dislay and filter values for efficiency
  20849. * source.price_display = val=="" ? "" : "$"+numberFormat(val);
  20850. * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val;
  20851. * return;
  20852. * }
  20853. * else if (type === 'display') {
  20854. * return source.price_display;
  20855. * }
  20856. * else if (type === 'filter') {
  20857. * return source.price_filter;
  20858. * }
  20859. * // 'sort', 'type' and undefined all just use the integer
  20860. * return source.price;
  20861. * }
  20862. * } ]
  20863. * } );
  20864. * } );
  20865. *
  20866. * @example
  20867. * // Using default content
  20868. * $(document).ready( function() {
  20869. * $('#example').dataTable( {
  20870. * "columnDefs": [ {
  20871. * "targets": [ 0 ],
  20872. * "data": null,
  20873. * "defaultContent": "Click to edit"
  20874. * } ]
  20875. * } );
  20876. * } );
  20877. *
  20878. * @example
  20879. * // Using array notation - outputting a list from an array
  20880. * $(document).ready( function() {
  20881. * $('#example').dataTable( {
  20882. * "columnDefs": [ {
  20883. * "targets": [ 0 ],
  20884. * "data": "name[, ]"
  20885. * } ]
  20886. * } );
  20887. * } );
  20888. *
  20889. */
  20890. "mData": null,
  20891. /**
  20892. * This property is the rendering partner to `data` and it is suggested that
  20893. * when you want to manipulate data for display (including filtering,
  20894. * sorting etc) without altering the underlying data for the table, use this
  20895. * property. `render` can be considered to be the the read only companion to
  20896. * `data` which is read / write (then as such more complex). Like `data`
  20897. * this option can be given in a number of different ways to effect its
  20898. * behaviour:
  20899. *
  20900. * * `integer` - treated as an array index for the data source. This is the
  20901. * default that DataTables uses (incrementally increased for each column).
  20902. * * `string` - read an object property from the data source. There are
  20903. * three 'special' options that can be used in the string to alter how
  20904. * DataTables reads the data from the source object:
  20905. * * `.` - Dotted Javascript notation. Just as you use a `.` in
  20906. * Javascript to read from nested objects, so to can the options
  20907. * specified in `data`. For example: `browser.version` or
  20908. * `browser.name`. If your object parameter name contains a period, use
  20909. * `\\` to escape it - i.e. `first\\.name`.
  20910. * * `[]` - Array notation. DataTables can automatically combine data
  20911. * from and array source, joining the data with the characters provided
  20912. * between the two brackets. For example: `name[, ]` would provide a
  20913. * comma-space separated list from the source array. If no characters
  20914. * are provided between the brackets, the original array source is
  20915. * returned.
  20916. * * `()` - Function notation. Adding `()` to the end of a parameter will
  20917. * execute a function of the name given. For example: `browser()` for a
  20918. * simple function on the data source, `browser.version()` for a
  20919. * function in a nested property or even `browser().version` to get an
  20920. * object property if the function called returns an object.
  20921. * * `object` - use different data for the different data types requested by
  20922. * DataTables ('filter', 'display', 'type' or 'sort'). The property names
  20923. * of the object is the data type the property refers to and the value can
  20924. * defined using an integer, string or function using the same rules as
  20925. * `render` normally does. Note that an `_` option _must_ be specified.
  20926. * This is the default value to use if you haven't specified a value for
  20927. * the data type requested by DataTables.
  20928. * * `function` - the function given will be executed whenever DataTables
  20929. * needs to set or get the data for a cell in the column. The function
  20930. * takes three parameters:
  20931. * * Parameters:
  20932. * * {array|object} The data source for the row (based on `data`)
  20933. * * {string} The type call data requested - this will be 'filter',
  20934. * 'display', 'type' or 'sort'.
  20935. * * {array|object} The full data source for the row (not based on
  20936. * `data`)
  20937. * * Return:
  20938. * * The return value from the function is what will be used for the
  20939. * data requested.
  20940. *
  20941. * @type string|int|function|object|null
  20942. * @default null Use the data source value.
  20943. *
  20944. * @name DataTable.defaults.column.render
  20945. * @dtopt Columns
  20946. *
  20947. * @example
  20948. * // Create a comma separated list from an array of objects
  20949. * $(document).ready( function() {
  20950. * $('#example').dataTable( {
  20951. * "ajaxSource": "sources/deep.txt",
  20952. * "columns": [
  20953. * { "data": "engine" },
  20954. * { "data": "browser" },
  20955. * {
  20956. * "data": "platform",
  20957. * "render": "[, ].name"
  20958. * }
  20959. * ]
  20960. * } );
  20961. * } );
  20962. *
  20963. * @example
  20964. * // Execute a function to obtain data
  20965. * $(document).ready( function() {
  20966. * $('#example').dataTable( {
  20967. * "columnDefs": [ {
  20968. * "targets": [ 0 ],
  20969. * "data": null, // Use the full data source object for the renderer's source
  20970. * "render": "browserName()"
  20971. * } ]
  20972. * } );
  20973. * } );
  20974. *
  20975. * @example
  20976. * // As an object, extracting different data for the different types
  20977. * // This would be used with a data source such as:
  20978. * // { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
  20979. * // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
  20980. * // (which has both forms) is used for filtering for if a user inputs either format, while
  20981. * // the formatted phone number is the one that is shown in the table.
  20982. * $(document).ready( function() {
  20983. * $('#example').dataTable( {
  20984. * "columnDefs": [ {
  20985. * "targets": [ 0 ],
  20986. * "data": null, // Use the full data source object for the renderer's source
  20987. * "render": {
  20988. * "_": "phone",
  20989. * "filter": "phone_filter",
  20990. * "display": "phone_display"
  20991. * }
  20992. * } ]
  20993. * } );
  20994. * } );
  20995. *
  20996. * @example
  20997. * // Use as a function to create a link from the data source
  20998. * $(document).ready( function() {
  20999. * $('#example').dataTable( {
  21000. * "columnDefs": [ {
  21001. * "targets": [ 0 ],
  21002. * "data": "download_link",
  21003. * "render": function ( data, type, full ) {
  21004. * return '<a href="'+data+'">Download</a>';
  21005. * }
  21006. * } ]
  21007. * } );
  21008. * } );
  21009. */
  21010. "mRender": null,
  21011. /**
  21012. * Change the cell type created for the column - either TD cells or TH cells. This
  21013. * can be useful as TH cells have semantic meaning in the table body, allowing them
  21014. * to act as a header for a row (you may wish to add scope='row' to the TH elements).
  21015. * @type string
  21016. * @default td
  21017. *
  21018. * @name DataTable.defaults.column.cellType
  21019. * @dtopt Columns
  21020. *
  21021. * @example
  21022. * // Make the first column use TH cells
  21023. * $(document).ready( function() {
  21024. * $('#example').dataTable( {
  21025. * "columnDefs": [ {
  21026. * "targets": [ 0 ],
  21027. * "cellType": "th"
  21028. * } ]
  21029. * } );
  21030. * } );
  21031. */
  21032. "sCellType": "td",
  21033. /**
  21034. * Class to give to each cell in this column.
  21035. * @type string
  21036. * @default <i>Empty string</i>
  21037. *
  21038. * @name DataTable.defaults.column.class
  21039. * @dtopt Columns
  21040. *
  21041. * @example
  21042. * // Using `columnDefs`
  21043. * $(document).ready( function() {
  21044. * $('#example').dataTable( {
  21045. * "columnDefs": [
  21046. * { "class": "my_class", "targets": [ 0 ] }
  21047. * ]
  21048. * } );
  21049. * } );
  21050. *
  21051. * @example
  21052. * // Using `columns`
  21053. * $(document).ready( function() {
  21054. * $('#example').dataTable( {
  21055. * "columns": [
  21056. * { "class": "my_class" },
  21057. * null,
  21058. * null,
  21059. * null,
  21060. * null
  21061. * ]
  21062. * } );
  21063. * } );
  21064. */
  21065. "sClass": "",
  21066. /**
  21067. * When DataTables calculates the column widths to assign to each column,
  21068. * it finds the longest string in each column and then constructs a
  21069. * temporary table and reads the widths from that. The problem with this
  21070. * is that "mmm" is much wider then "iiii", but the latter is a longer
  21071. * string - thus the calculation can go wrong (doing it properly and putting
  21072. * it into an DOM object and measuring that is horribly(!) slow). Thus as
  21073. * a "work around" we provide this option. It will append its value to the
  21074. * text that is found to be the longest string for the column - i.e. padding.
  21075. * Generally you shouldn't need this!
  21076. * @type string
  21077. * @default <i>Empty string<i>
  21078. *
  21079. * @name DataTable.defaults.column.contentPadding
  21080. * @dtopt Columns
  21081. *
  21082. * @example
  21083. * // Using `columns`
  21084. * $(document).ready( function() {
  21085. * $('#example').dataTable( {
  21086. * "columns": [
  21087. * null,
  21088. * null,
  21089. * null,
  21090. * {
  21091. * "contentPadding": "mmm"
  21092. * }
  21093. * ]
  21094. * } );
  21095. * } );
  21096. */
  21097. "sContentPadding": "",
  21098. /**
  21099. * Allows a default value to be given for a column's data, and will be used
  21100. * whenever a null data source is encountered (this can be because `data`
  21101. * is set to null, or because the data source itself is null).
  21102. * @type string
  21103. * @default null
  21104. *
  21105. * @name DataTable.defaults.column.defaultContent
  21106. * @dtopt Columns
  21107. *
  21108. * @example
  21109. * // Using `columnDefs`
  21110. * $(document).ready( function() {
  21111. * $('#example').dataTable( {
  21112. * "columnDefs": [
  21113. * {
  21114. * "data": null,
  21115. * "defaultContent": "Edit",
  21116. * "targets": [ -1 ]
  21117. * }
  21118. * ]
  21119. * } );
  21120. * } );
  21121. *
  21122. * @example
  21123. * // Using `columns`
  21124. * $(document).ready( function() {
  21125. * $('#example').dataTable( {
  21126. * "columns": [
  21127. * null,
  21128. * null,
  21129. * null,
  21130. * {
  21131. * "data": null,
  21132. * "defaultContent": "Edit"
  21133. * }
  21134. * ]
  21135. * } );
  21136. * } );
  21137. */
  21138. "sDefaultContent": null,
  21139. /**
  21140. * This parameter is only used in DataTables' server-side processing. It can
  21141. * be exceptionally useful to know what columns are being displayed on the
  21142. * client side, and to map these to database fields. When defined, the names
  21143. * also allow DataTables to reorder information from the server if it comes
  21144. * back in an unexpected order (i.e. if you switch your columns around on the
  21145. * client-side, your server-side code does not also need updating).
  21146. * @type string
  21147. * @default <i>Empty string</i>
  21148. *
  21149. * @name DataTable.defaults.column.name
  21150. * @dtopt Columns
  21151. *
  21152. * @example
  21153. * // Using `columnDefs`
  21154. * $(document).ready( function() {
  21155. * $('#example').dataTable( {
  21156. * "columnDefs": [
  21157. * { "name": "engine", "targets": [ 0 ] },
  21158. * { "name": "browser", "targets": [ 1 ] },
  21159. * { "name": "platform", "targets": [ 2 ] },
  21160. * { "name": "version", "targets": [ 3 ] },
  21161. * { "name": "grade", "targets": [ 4 ] }
  21162. * ]
  21163. * } );
  21164. * } );
  21165. *
  21166. * @example
  21167. * // Using `columns`
  21168. * $(document).ready( function() {
  21169. * $('#example').dataTable( {
  21170. * "columns": [
  21171. * { "name": "engine" },
  21172. * { "name": "browser" },
  21173. * { "name": "platform" },
  21174. * { "name": "version" },
  21175. * { "name": "grade" }
  21176. * ]
  21177. * } );
  21178. * } );
  21179. */
  21180. "sName": "",
  21181. /**
  21182. * Defines a data source type for the ordering which can be used to read
  21183. * real-time information from the table (updating the internally cached
  21184. * version) prior to ordering. This allows ordering to occur on user
  21185. * editable elements such as form inputs.
  21186. * @type string
  21187. * @default std
  21188. *
  21189. * @name DataTable.defaults.column.orderDataType
  21190. * @dtopt Columns
  21191. *
  21192. * @example
  21193. * // Using `columnDefs`
  21194. * $(document).ready( function() {
  21195. * $('#example').dataTable( {
  21196. * "columnDefs": [
  21197. * { "orderDataType": "dom-text", "targets": [ 2, 3 ] },
  21198. * { "type": "numeric", "targets": [ 3 ] },
  21199. * { "orderDataType": "dom-select", "targets": [ 4 ] },
  21200. * { "orderDataType": "dom-checkbox", "targets": [ 5 ] }
  21201. * ]
  21202. * } );
  21203. * } );
  21204. *
  21205. * @example
  21206. * // Using `columns`
  21207. * $(document).ready( function() {
  21208. * $('#example').dataTable( {
  21209. * "columns": [
  21210. * null,
  21211. * null,
  21212. * { "orderDataType": "dom-text" },
  21213. * { "orderDataType": "dom-text", "type": "numeric" },
  21214. * { "orderDataType": "dom-select" },
  21215. * { "orderDataType": "dom-checkbox" }
  21216. * ]
  21217. * } );
  21218. * } );
  21219. */
  21220. "sSortDataType": "std",
  21221. /**
  21222. * The title of this column.
  21223. * @type string
  21224. * @default null <i>Derived from the 'TH' value for this column in the
  21225. * original HTML table.</i>
  21226. *
  21227. * @name DataTable.defaults.column.title
  21228. * @dtopt Columns
  21229. *
  21230. * @example
  21231. * // Using `columnDefs`
  21232. * $(document).ready( function() {
  21233. * $('#example').dataTable( {
  21234. * "columnDefs": [
  21235. * { "title": "My column title", "targets": [ 0 ] }
  21236. * ]
  21237. * } );
  21238. * } );
  21239. *
  21240. * @example
  21241. * // Using `columns`
  21242. * $(document).ready( function() {
  21243. * $('#example').dataTable( {
  21244. * "columns": [
  21245. * { "title": "My column title" },
  21246. * null,
  21247. * null,
  21248. * null,
  21249. * null
  21250. * ]
  21251. * } );
  21252. * } );
  21253. */
  21254. "sTitle": null,
  21255. /**
  21256. * The type allows you to specify how the data for this column will be
  21257. * ordered. Four types (string, numeric, date and html (which will strip
  21258. * HTML tags before ordering)) are currently available. Note that only date
  21259. * formats understood by Javascript's Date() object will be accepted as type
  21260. * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
  21261. * 'numeric', 'date' or 'html' (by default). Further types can be adding
  21262. * through plug-ins.
  21263. * @type string
  21264. * @default null <i>Auto-detected from raw data</i>
  21265. *
  21266. * @name DataTable.defaults.column.type
  21267. * @dtopt Columns
  21268. *
  21269. * @example
  21270. * // Using `columnDefs`
  21271. * $(document).ready( function() {
  21272. * $('#example').dataTable( {
  21273. * "columnDefs": [
  21274. * { "type": "html", "targets": [ 0 ] }
  21275. * ]
  21276. * } );
  21277. * } );
  21278. *
  21279. * @example
  21280. * // Using `columns`
  21281. * $(document).ready( function() {
  21282. * $('#example').dataTable( {
  21283. * "columns": [
  21284. * { "type": "html" },
  21285. * null,
  21286. * null,
  21287. * null,
  21288. * null
  21289. * ]
  21290. * } );
  21291. * } );
  21292. */
  21293. "sType": null,
  21294. /**
  21295. * Defining the width of the column, this parameter may take any CSS value
  21296. * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not
  21297. * been given a specific width through this interface ensuring that the table
  21298. * remains readable.
  21299. * @type string
  21300. * @default null <i>Automatic</i>
  21301. *
  21302. * @name DataTable.defaults.column.width
  21303. * @dtopt Columns
  21304. *
  21305. * @example
  21306. * // Using `columnDefs`
  21307. * $(document).ready( function() {
  21308. * $('#example').dataTable( {
  21309. * "columnDefs": [
  21310. * { "width": "20%", "targets": [ 0 ] }
  21311. * ]
  21312. * } );
  21313. * } );
  21314. *
  21315. * @example
  21316. * // Using `columns`
  21317. * $(document).ready( function() {
  21318. * $('#example').dataTable( {
  21319. * "columns": [
  21320. * { "width": "20%" },
  21321. * null,
  21322. * null,
  21323. * null,
  21324. * null
  21325. * ]
  21326. * } );
  21327. * } );
  21328. */
  21329. "sWidth": null
  21330. };
  21331. _fnHungarianMap( DataTable.defaults.column );
  21332. /**
  21333. * DataTables settings object - this holds all the information needed for a
  21334. * given table, including configuration, data and current application of the
  21335. * table options. DataTables does not have a single instance for each DataTable
  21336. * with the settings attached to that instance, but rather instances of the
  21337. * DataTable "class" are created on-the-fly as needed (typically by a
  21338. * $().dataTable() call) and the settings object is then applied to that
  21339. * instance.
  21340. *
  21341. * Note that this object is related to {@link DataTable.defaults} but this
  21342. * one is the internal data store for DataTables's cache of columns. It should
  21343. * NOT be manipulated outside of DataTables. Any configuration should be done
  21344. * through the initialisation options.
  21345. * @namespace
  21346. * @todo Really should attach the settings object to individual instances so we
  21347. * don't need to create new instances on each $().dataTable() call (if the
  21348. * table already exists). It would also save passing oSettings around and
  21349. * into every single function. However, this is a very significant
  21350. * architecture change for DataTables and will almost certainly break
  21351. * backwards compatibility with older installations. This is something that
  21352. * will be done in 2.0.
  21353. */
  21354. DataTable.models.oSettings = {
  21355. /**
  21356. * Primary features of DataTables and their enablement state.
  21357. * @namespace
  21358. */
  21359. "oFeatures": {
  21360. /**
  21361. * Flag to say if DataTables should automatically try to calculate the
  21362. * optimum table and columns widths (true) or not (false).
  21363. * Note that this parameter will be set by the initialisation routine. To
  21364. * set a default use {@link DataTable.defaults}.
  21365. * @type boolean
  21366. */
  21367. "bAutoWidth": null,
  21368. /**
  21369. * Delay the creation of TR and TD elements until they are actually
  21370. * needed by a driven page draw. This can give a significant speed
  21371. * increase for Ajax source and Javascript source data, but makes no
  21372. * difference at all fro DOM and server-side processing tables.
  21373. * Note that this parameter will be set by the initialisation routine. To
  21374. * set a default use {@link DataTable.defaults}.
  21375. * @type boolean
  21376. */
  21377. "bDeferRender": null,
  21378. /**
  21379. * Enable filtering on the table or not. Note that if this is disabled
  21380. * then there is no filtering at all on the table, including fnFilter.
  21381. * To just remove the filtering input use sDom and remove the 'f' option.
  21382. * Note that this parameter will be set by the initialisation routine. To
  21383. * set a default use {@link DataTable.defaults}.
  21384. * @type boolean
  21385. */
  21386. "bFilter": null,
  21387. /**
  21388. * Table information element (the 'Showing x of y records' div) enable
  21389. * flag.
  21390. * Note that this parameter will be set by the initialisation routine. To
  21391. * set a default use {@link DataTable.defaults}.
  21392. * @type boolean
  21393. */
  21394. "bInfo": null,
  21395. /**
  21396. * Present a user control allowing the end user to change the page size
  21397. * when pagination is enabled.
  21398. * Note that this parameter will be set by the initialisation routine. To
  21399. * set a default use {@link DataTable.defaults}.
  21400. * @type boolean
  21401. */
  21402. "bLengthChange": null,
  21403. /**
  21404. * Pagination enabled or not. Note that if this is disabled then length
  21405. * changing must also be disabled.
  21406. * Note that this parameter will be set by the initialisation routine. To
  21407. * set a default use {@link DataTable.defaults}.
  21408. * @type boolean
  21409. */
  21410. "bPaginate": null,
  21411. /**
  21412. * Processing indicator enable flag whenever DataTables is enacting a
  21413. * user request - typically an Ajax request for server-side processing.
  21414. * Note that this parameter will be set by the initialisation routine. To
  21415. * set a default use {@link DataTable.defaults}.
  21416. * @type boolean
  21417. */
  21418. "bProcessing": null,
  21419. /**
  21420. * Server-side processing enabled flag - when enabled DataTables will
  21421. * get all data from the server for every draw - there is no filtering,
  21422. * sorting or paging done on the client-side.
  21423. * Note that this parameter will be set by the initialisation routine. To
  21424. * set a default use {@link DataTable.defaults}.
  21425. * @type boolean
  21426. */
  21427. "bServerSide": null,
  21428. /**
  21429. * Sorting enablement flag.
  21430. * Note that this parameter will be set by the initialisation routine. To
  21431. * set a default use {@link DataTable.defaults}.
  21432. * @type boolean
  21433. */
  21434. "bSort": null,
  21435. /**
  21436. * Multi-column sorting
  21437. * Note that this parameter will be set by the initialisation routine. To
  21438. * set a default use {@link DataTable.defaults}.
  21439. * @type boolean
  21440. */
  21441. "bSortMulti": null,
  21442. /**
  21443. * Apply a class to the columns which are being sorted to provide a
  21444. * visual highlight or not. This can slow things down when enabled since
  21445. * there is a lot of DOM interaction.
  21446. * Note that this parameter will be set by the initialisation routine. To
  21447. * set a default use {@link DataTable.defaults}.
  21448. * @type boolean
  21449. */
  21450. "bSortClasses": null,
  21451. /**
  21452. * State saving enablement flag.
  21453. * Note that this parameter will be set by the initialisation routine. To
  21454. * set a default use {@link DataTable.defaults}.
  21455. * @type boolean
  21456. */
  21457. "bStateSave": null
  21458. },
  21459. /**
  21460. * Scrolling settings for a table.
  21461. * @namespace
  21462. */
  21463. "oScroll": {
  21464. /**
  21465. * When the table is shorter in height than sScrollY, collapse the
  21466. * table container down to the height of the table (when true).
  21467. * Note that this parameter will be set by the initialisation routine. To
  21468. * set a default use {@link DataTable.defaults}.
  21469. * @type boolean
  21470. */
  21471. "bCollapse": null,
  21472. /**
  21473. * Width of the scrollbar for the web-browser's platform. Calculated
  21474. * during table initialisation.
  21475. * @type int
  21476. * @default 0
  21477. */
  21478. "iBarWidth": 0,
  21479. /**
  21480. * Viewport width for horizontal scrolling. Horizontal scrolling is
  21481. * disabled if an empty string.
  21482. * Note that this parameter will be set by the initialisation routine. To
  21483. * set a default use {@link DataTable.defaults}.
  21484. * @type string
  21485. */
  21486. "sX": null,
  21487. /**
  21488. * Width to expand the table to when using x-scrolling. Typically you
  21489. * should not need to use this.
  21490. * Note that this parameter will be set by the initialisation routine. To
  21491. * set a default use {@link DataTable.defaults}.
  21492. * @type string
  21493. * @deprecated
  21494. */
  21495. "sXInner": null,
  21496. /**
  21497. * Viewport height for vertical scrolling. Vertical scrolling is disabled
  21498. * if an empty string.
  21499. * Note that this parameter will be set by the initialisation routine. To
  21500. * set a default use {@link DataTable.defaults}.
  21501. * @type string
  21502. */
  21503. "sY": null
  21504. },
  21505. /**
  21506. * Language information for the table.
  21507. * @namespace
  21508. * @extends DataTable.defaults.oLanguage
  21509. */
  21510. "oLanguage": {
  21511. /**
  21512. * Information callback function. See
  21513. * {@link DataTable.defaults.fnInfoCallback}
  21514. * @type function
  21515. * @default null
  21516. */
  21517. "fnInfoCallback": null
  21518. },
  21519. /**
  21520. * Browser support parameters
  21521. * @namespace
  21522. */
  21523. "oBrowser": {
  21524. /**
  21525. * Indicate if the browser incorrectly calculates width:100% inside a
  21526. * scrolling element (IE6/7)
  21527. * @type boolean
  21528. * @default false
  21529. */
  21530. "bScrollOversize": false,
  21531. /**
  21532. * Determine if the vertical scrollbar is on the right or left of the
  21533. * scrolling container - needed for rtl language layout, although not
  21534. * all browsers move the scrollbar (Safari).
  21535. * @type boolean
  21536. * @default false
  21537. */
  21538. "bScrollbarLeft": false,
  21539. /**
  21540. * Flag for if `getBoundingClientRect` is fully supported or not
  21541. * @type boolean
  21542. * @default false
  21543. */
  21544. "bBounding": false,
  21545. /**
  21546. * Browser scrollbar width
  21547. * @type integer
  21548. * @default 0
  21549. */
  21550. "barWidth": 0
  21551. },
  21552. "ajax": null,
  21553. /**
  21554. * Array referencing the nodes which are used for the features. The
  21555. * parameters of this object match what is allowed by sDom - i.e.
  21556. * <ul>
  21557. * <li>'l' - Length changing</li>
  21558. * <li>'f' - Filtering input</li>
  21559. * <li>'t' - The table!</li>
  21560. * <li>'i' - Information</li>
  21561. * <li>'p' - Pagination</li>
  21562. * <li>'r' - pRocessing</li>
  21563. * </ul>
  21564. * @type array
  21565. * @default []
  21566. */
  21567. "aanFeatures": [],
  21568. /**
  21569. * Store data information - see {@link DataTable.models.oRow} for detailed
  21570. * information.
  21571. * @type array
  21572. * @default []
  21573. */
  21574. "aoData": [],
  21575. /**
  21576. * Array of indexes which are in the current display (after filtering etc)
  21577. * @type array
  21578. * @default []
  21579. */
  21580. "aiDisplay": [],
  21581. /**
  21582. * Array of indexes for display - no filtering
  21583. * @type array
  21584. * @default []
  21585. */
  21586. "aiDisplayMaster": [],
  21587. /**
  21588. * Map of row ids to data indexes
  21589. * @type object
  21590. * @default {}
  21591. */
  21592. "aIds": {},
  21593. /**
  21594. * Store information about each column that is in use
  21595. * @type array
  21596. * @default []
  21597. */
  21598. "aoColumns": [],
  21599. /**
  21600. * Store information about the table's header
  21601. * @type array
  21602. * @default []
  21603. */
  21604. "aoHeader": [],
  21605. /**
  21606. * Store information about the table's footer
  21607. * @type array
  21608. * @default []
  21609. */
  21610. "aoFooter": [],
  21611. /**
  21612. * Store the applied global search information in case we want to force a
  21613. * research or compare the old search to a new one.
  21614. * Note that this parameter will be set by the initialisation routine. To
  21615. * set a default use {@link DataTable.defaults}.
  21616. * @namespace
  21617. * @extends DataTable.models.oSearch
  21618. */
  21619. "oPreviousSearch": {},
  21620. /**
  21621. * Store the applied search for each column - see
  21622. * {@link DataTable.models.oSearch} for the format that is used for the
  21623. * filtering information for each column.
  21624. * @type array
  21625. * @default []
  21626. */
  21627. "aoPreSearchCols": [],
  21628. /**
  21629. * Sorting that is applied to the table. Note that the inner arrays are
  21630. * used in the following manner:
  21631. * <ul>
  21632. * <li>Index 0 - column number</li>
  21633. * <li>Index 1 - current sorting direction</li>
  21634. * </ul>
  21635. * Note that this parameter will be set by the initialisation routine. To
  21636. * set a default use {@link DataTable.defaults}.
  21637. * @type array
  21638. * @todo These inner arrays should really be objects
  21639. */
  21640. "aaSorting": null,
  21641. /**
  21642. * Sorting that is always applied to the table (i.e. prefixed in front of
  21643. * aaSorting).
  21644. * Note that this parameter will be set by the initialisation routine. To
  21645. * set a default use {@link DataTable.defaults}.
  21646. * @type array
  21647. * @default []
  21648. */
  21649. "aaSortingFixed": [],
  21650. /**
  21651. * Classes to use for the striping of a table.
  21652. * Note that this parameter will be set by the initialisation routine. To
  21653. * set a default use {@link DataTable.defaults}.
  21654. * @type array
  21655. * @default []
  21656. */
  21657. "asStripeClasses": null,
  21658. /**
  21659. * If restoring a table - we should restore its striping classes as well
  21660. * @type array
  21661. * @default []
  21662. */
  21663. "asDestroyStripes": [],
  21664. /**
  21665. * If restoring a table - we should restore its width
  21666. * @type int
  21667. * @default 0
  21668. */
  21669. "sDestroyWidth": 0,
  21670. /**
  21671. * Callback functions array for every time a row is inserted (i.e. on a draw).
  21672. * @type array
  21673. * @default []
  21674. */
  21675. "aoRowCallback": [],
  21676. /**
  21677. * Callback functions for the header on each draw.
  21678. * @type array
  21679. * @default []
  21680. */
  21681. "aoHeaderCallback": [],
  21682. /**
  21683. * Callback function for the footer on each draw.
  21684. * @type array
  21685. * @default []
  21686. */
  21687. "aoFooterCallback": [],
  21688. /**
  21689. * Array of callback functions for draw callback functions
  21690. * @type array
  21691. * @default []
  21692. */
  21693. "aoDrawCallback": [],
  21694. /**
  21695. * Array of callback functions for row created function
  21696. * @type array
  21697. * @default []
  21698. */
  21699. "aoRowCreatedCallback": [],
  21700. /**
  21701. * Callback functions for just before the table is redrawn. A return of
  21702. * false will be used to cancel the draw.
  21703. * @type array
  21704. * @default []
  21705. */
  21706. "aoPreDrawCallback": [],
  21707. /**
  21708. * Callback functions for when the table has been initialised.
  21709. * @type array
  21710. * @default []
  21711. */
  21712. "aoInitComplete": [],
  21713. /**
  21714. * Callbacks for modifying the settings to be stored for state saving, prior to
  21715. * saving state.
  21716. * @type array
  21717. * @default []
  21718. */
  21719. "aoStateSaveParams": [],
  21720. /**
  21721. * Callbacks for modifying the settings that have been stored for state saving
  21722. * prior to using the stored values to restore the state.
  21723. * @type array
  21724. * @default []
  21725. */
  21726. "aoStateLoadParams": [],
  21727. /**
  21728. * Callbacks for operating on the settings object once the saved state has been
  21729. * loaded
  21730. * @type array
  21731. * @default []
  21732. */
  21733. "aoStateLoaded": [],
  21734. /**
  21735. * Cache the table ID for quick access
  21736. * @type string
  21737. * @default <i>Empty string</i>
  21738. */
  21739. "sTableId": "",
  21740. /**
  21741. * The TABLE node for the main table
  21742. * @type node
  21743. * @default null
  21744. */
  21745. "nTable": null,
  21746. /**
  21747. * Permanent ref to the thead element
  21748. * @type node
  21749. * @default null
  21750. */
  21751. "nTHead": null,
  21752. /**
  21753. * Permanent ref to the tfoot element - if it exists
  21754. * @type node
  21755. * @default null
  21756. */
  21757. "nTFoot": null,
  21758. /**
  21759. * Permanent ref to the tbody element
  21760. * @type node
  21761. * @default null
  21762. */
  21763. "nTBody": null,
  21764. /**
  21765. * Cache the wrapper node (contains all DataTables controlled elements)
  21766. * @type node
  21767. * @default null
  21768. */
  21769. "nTableWrapper": null,
  21770. /**
  21771. * Indicate if when using server-side processing the loading of data
  21772. * should be deferred until the second draw.
  21773. * Note that this parameter will be set by the initialisation routine. To
  21774. * set a default use {@link DataTable.defaults}.
  21775. * @type boolean
  21776. * @default false
  21777. */
  21778. "bDeferLoading": false,
  21779. /**
  21780. * Indicate if all required information has been read in
  21781. * @type boolean
  21782. * @default false
  21783. */
  21784. "bInitialised": false,
  21785. /**
  21786. * Information about open rows. Each object in the array has the parameters
  21787. * 'nTr' and 'nParent'
  21788. * @type array
  21789. * @default []
  21790. */
  21791. "aoOpenRows": [],
  21792. /**
  21793. * Dictate the positioning of DataTables' control elements - see
  21794. * {@link DataTable.model.oInit.sDom}.
  21795. * Note that this parameter will be set by the initialisation routine. To
  21796. * set a default use {@link DataTable.defaults}.
  21797. * @type string
  21798. * @default null
  21799. */
  21800. "sDom": null,
  21801. /**
  21802. * Search delay (in mS)
  21803. * @type integer
  21804. * @default null
  21805. */
  21806. "searchDelay": null,
  21807. /**
  21808. * Which type of pagination should be used.
  21809. * Note that this parameter will be set by the initialisation routine. To
  21810. * set a default use {@link DataTable.defaults}.
  21811. * @type string
  21812. * @default two_button
  21813. */
  21814. "sPaginationType": "two_button",
  21815. /**
  21816. * The state duration (for `stateSave`) in seconds.
  21817. * Note that this parameter will be set by the initialisation routine. To
  21818. * set a default use {@link DataTable.defaults}.
  21819. * @type int
  21820. * @default 0
  21821. */
  21822. "iStateDuration": 0,
  21823. /**
  21824. * Array of callback functions for state saving. Each array element is an
  21825. * object with the following parameters:
  21826. * <ul>
  21827. * <li>function:fn - function to call. Takes two parameters, oSettings
  21828. * and the JSON string to save that has been thus far created. Returns
  21829. * a JSON string to be inserted into a json object
  21830. * (i.e. '"param": [ 0, 1, 2]')</li>
  21831. * <li>string:sName - name of callback</li>
  21832. * </ul>
  21833. * @type array
  21834. * @default []
  21835. */
  21836. "aoStateSave": [],
  21837. /**
  21838. * Array of callback functions for state loading. Each array element is an
  21839. * object with the following parameters:
  21840. * <ul>
  21841. * <li>function:fn - function to call. Takes two parameters, oSettings
  21842. * and the object stored. May return false to cancel state loading</li>
  21843. * <li>string:sName - name of callback</li>
  21844. * </ul>
  21845. * @type array
  21846. * @default []
  21847. */
  21848. "aoStateLoad": [],
  21849. /**
  21850. * State that was saved. Useful for back reference
  21851. * @type object
  21852. * @default null
  21853. */
  21854. "oSavedState": null,
  21855. /**
  21856. * State that was loaded. Useful for back reference
  21857. * @type object
  21858. * @default null
  21859. */
  21860. "oLoadedState": null,
  21861. /**
  21862. * Source url for AJAX data for the table.
  21863. * Note that this parameter will be set by the initialisation routine. To
  21864. * set a default use {@link DataTable.defaults}.
  21865. * @type string
  21866. * @default null
  21867. */
  21868. "sAjaxSource": null,
  21869. /**
  21870. * Property from a given object from which to read the table data from. This
  21871. * can be an empty string (when not server-side processing), in which case
  21872. * it is assumed an an array is given directly.
  21873. * Note that this parameter will be set by the initialisation routine. To
  21874. * set a default use {@link DataTable.defaults}.
  21875. * @type string
  21876. */
  21877. "sAjaxDataProp": null,
  21878. /**
  21879. * Note if draw should be blocked while getting data
  21880. * @type boolean
  21881. * @default true
  21882. */
  21883. "bAjaxDataGet": true,
  21884. /**
  21885. * The last jQuery XHR object that was used for server-side data gathering.
  21886. * This can be used for working with the XHR information in one of the
  21887. * callbacks
  21888. * @type object
  21889. * @default null
  21890. */
  21891. "jqXHR": null,
  21892. /**
  21893. * JSON returned from the server in the last Ajax request
  21894. * @type object
  21895. * @default undefined
  21896. */
  21897. "json": undefined,
  21898. /**
  21899. * Data submitted as part of the last Ajax request
  21900. * @type object
  21901. * @default undefined
  21902. */
  21903. "oAjaxData": undefined,
  21904. /**
  21905. * Function to get the server-side data.
  21906. * Note that this parameter will be set by the initialisation routine. To
  21907. * set a default use {@link DataTable.defaults}.
  21908. * @type function
  21909. */
  21910. "fnServerData": null,
  21911. /**
  21912. * Functions which are called prior to sending an Ajax request so extra
  21913. * parameters can easily be sent to the server
  21914. * @type array
  21915. * @default []
  21916. */
  21917. "aoServerParams": [],
  21918. /**
  21919. * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
  21920. * required).
  21921. * Note that this parameter will be set by the initialisation routine. To
  21922. * set a default use {@link DataTable.defaults}.
  21923. * @type string
  21924. */
  21925. "sServerMethod": null,
  21926. /**
  21927. * Format numbers for display.
  21928. * Note that this parameter will be set by the initialisation routine. To
  21929. * set a default use {@link DataTable.defaults}.
  21930. * @type function
  21931. */
  21932. "fnFormatNumber": null,
  21933. /**
  21934. * List of options that can be used for the user selectable length menu.
  21935. * Note that this parameter will be set by the initialisation routine. To
  21936. * set a default use {@link DataTable.defaults}.
  21937. * @type array
  21938. * @default []
  21939. */
  21940. "aLengthMenu": null,
  21941. /**
  21942. * Counter for the draws that the table does. Also used as a tracker for
  21943. * server-side processing
  21944. * @type int
  21945. * @default 0
  21946. */
  21947. "iDraw": 0,
  21948. /**
  21949. * Indicate if a redraw is being done - useful for Ajax
  21950. * @type boolean
  21951. * @default false
  21952. */
  21953. "bDrawing": false,
  21954. /**
  21955. * Draw index (iDraw) of the last error when parsing the returned data
  21956. * @type int
  21957. * @default -1
  21958. */
  21959. "iDrawError": -1,
  21960. /**
  21961. * Paging display length
  21962. * @type int
  21963. * @default 10
  21964. */
  21965. "_iDisplayLength": 10,
  21966. /**
  21967. * Paging start point - aiDisplay index
  21968. * @type int
  21969. * @default 0
  21970. */
  21971. "_iDisplayStart": 0,
  21972. /**
  21973. * Server-side processing - number of records in the result set
  21974. * (i.e. before filtering), Use fnRecordsTotal rather than
  21975. * this property to get the value of the number of records, regardless of
  21976. * the server-side processing setting.
  21977. * @type int
  21978. * @default 0
  21979. * @private
  21980. */
  21981. "_iRecordsTotal": 0,
  21982. /**
  21983. * Server-side processing - number of records in the current display set
  21984. * (i.e. after filtering). Use fnRecordsDisplay rather than
  21985. * this property to get the value of the number of records, regardless of
  21986. * the server-side processing setting.
  21987. * @type boolean
  21988. * @default 0
  21989. * @private
  21990. */
  21991. "_iRecordsDisplay": 0,
  21992. /**
  21993. * Flag to indicate if jQuery UI marking and classes should be used.
  21994. * Note that this parameter will be set by the initialisation routine. To
  21995. * set a default use {@link DataTable.defaults}.
  21996. * @type boolean
  21997. */
  21998. "bJUI": null,
  21999. /**
  22000. * The classes to use for the table
  22001. * @type object
  22002. * @default {}
  22003. */
  22004. "oClasses": {},
  22005. /**
  22006. * Flag attached to the settings object so you can check in the draw
  22007. * callback if filtering has been done in the draw. Deprecated in favour of
  22008. * events.
  22009. * @type boolean
  22010. * @default false
  22011. * @deprecated
  22012. */
  22013. "bFiltered": false,
  22014. /**
  22015. * Flag attached to the settings object so you can check in the draw
  22016. * callback if sorting has been done in the draw. Deprecated in favour of
  22017. * events.
  22018. * @type boolean
  22019. * @default false
  22020. * @deprecated
  22021. */
  22022. "bSorted": false,
  22023. /**
  22024. * Indicate that if multiple rows are in the header and there is more than
  22025. * one unique cell per column, if the top one (true) or bottom one (false)
  22026. * should be used for sorting / title by DataTables.
  22027. * Note that this parameter will be set by the initialisation routine. To
  22028. * set a default use {@link DataTable.defaults}.
  22029. * @type boolean
  22030. */
  22031. "bSortCellsTop": null,
  22032. /**
  22033. * Initialisation object that is used for the table
  22034. * @type object
  22035. * @default null
  22036. */
  22037. "oInit": null,
  22038. /**
  22039. * Destroy callback functions - for plug-ins to attach themselves to the
  22040. * destroy so they can clean up markup and events.
  22041. * @type array
  22042. * @default []
  22043. */
  22044. "aoDestroyCallback": [],
  22045. /**
  22046. * Get the number of records in the current record set, before filtering
  22047. * @type function
  22048. */
  22049. "fnRecordsTotal": function ()
  22050. {
  22051. return _fnDataSource( this ) == 'ssp' ?
  22052. this._iRecordsTotal * 1 :
  22053. this.aiDisplayMaster.length;
  22054. },
  22055. /**
  22056. * Get the number of records in the current record set, after filtering
  22057. * @type function
  22058. */
  22059. "fnRecordsDisplay": function ()
  22060. {
  22061. return _fnDataSource( this ) == 'ssp' ?
  22062. this._iRecordsDisplay * 1 :
  22063. this.aiDisplay.length;
  22064. },
  22065. /**
  22066. * Get the display end point - aiDisplay index
  22067. * @type function
  22068. */
  22069. "fnDisplayEnd": function ()
  22070. {
  22071. var
  22072. len = this._iDisplayLength,
  22073. start = this._iDisplayStart,
  22074. calc = start + len,
  22075. records = this.aiDisplay.length,
  22076. features = this.oFeatures,
  22077. paginate = features.bPaginate;
  22078. if ( features.bServerSide ) {
  22079. return paginate === false || len === -1 ?
  22080. start + records :
  22081. Math.min( start+len, this._iRecordsDisplay );
  22082. }
  22083. else {
  22084. return ! paginate || calc>records || len===-1 ?
  22085. records :
  22086. calc;
  22087. }
  22088. },
  22089. /**
  22090. * The DataTables object for this table
  22091. * @type object
  22092. * @default null
  22093. */
  22094. "oInstance": null,
  22095. /**
  22096. * Unique identifier for each instance of the DataTables object. If there
  22097. * is an ID on the table node, then it takes that value, otherwise an
  22098. * incrementing internal counter is used.
  22099. * @type string
  22100. * @default null
  22101. */
  22102. "sInstance": null,
  22103. /**
  22104. * tabindex attribute value that is added to DataTables control elements, allowing
  22105. * keyboard navigation of the table and its controls.
  22106. */
  22107. "iTabIndex": 0,
  22108. /**
  22109. * DIV container for the footer scrolling table if scrolling
  22110. */
  22111. "nScrollHead": null,
  22112. /**
  22113. * DIV container for the footer scrolling table if scrolling
  22114. */
  22115. "nScrollFoot": null,
  22116. /**
  22117. * Last applied sort
  22118. * @type array
  22119. * @default []
  22120. */
  22121. "aLastSort": [],
  22122. /**
  22123. * Stored plug-in instances
  22124. * @type object
  22125. * @default {}
  22126. */
  22127. "oPlugins": {},
  22128. /**
  22129. * Function used to get a row's id from the row's data
  22130. * @type function
  22131. * @default null
  22132. */
  22133. "rowIdFn": null,
  22134. /**
  22135. * Data location where to store a row's id
  22136. * @type string
  22137. * @default null
  22138. */
  22139. "rowId": null
  22140. };
  22141. /**
  22142. * Extension object for DataTables that is used to provide all extension
  22143. * options.
  22144. *
  22145. * Note that the `DataTable.ext` object is available through
  22146. * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is
  22147. * also aliased to `jQuery.fn.dataTableExt` for historic reasons.
  22148. * @namespace
  22149. * @extends DataTable.models.ext
  22150. */
  22151. /**
  22152. * DataTables extensions
  22153. *
  22154. * This namespace acts as a collection area for plug-ins that can be used to
  22155. * extend DataTables capabilities. Indeed many of the build in methods
  22156. * use this method to provide their own capabilities (sorting methods for
  22157. * example).
  22158. *
  22159. * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
  22160. * reasons
  22161. *
  22162. * @namespace
  22163. */
  22164. DataTable.ext = _ext = {
  22165. /**
  22166. * Buttons. For use with the Buttons extension for DataTables. This is
  22167. * defined here so other extensions can define buttons regardless of load
  22168. * order. It is _not_ used by DataTables core.
  22169. *
  22170. * @type object
  22171. * @default {}
  22172. */
  22173. buttons: {},
  22174. /**
  22175. * Element class names
  22176. *
  22177. * @type object
  22178. * @default {}
  22179. */
  22180. classes: {},
  22181. /**
  22182. * DataTables build type (expanded by the download builder)
  22183. *
  22184. * @type string
  22185. */
  22186. builder: "-source-",
  22187. /**
  22188. * Error reporting.
  22189. *
  22190. * How should DataTables report an error. Can take the value 'alert',
  22191. * 'throw', 'none' or a function.
  22192. *
  22193. * @type string|function
  22194. * @default alert
  22195. */
  22196. errMode: "alert",
  22197. /**
  22198. * Feature plug-ins.
  22199. *
  22200. * This is an array of objects which describe the feature plug-ins that are
  22201. * available to DataTables. These feature plug-ins are then available for
  22202. * use through the `dom` initialisation option.
  22203. *
  22204. * Each feature plug-in is described by an object which must have the
  22205. * following properties:
  22206. *
  22207. * * `fnInit` - function that is used to initialise the plug-in,
  22208. * * `cFeature` - a character so the feature can be enabled by the `dom`
  22209. * instillation option. This is case sensitive.
  22210. *
  22211. * The `fnInit` function has the following input parameters:
  22212. *
  22213. * 1. `{object}` DataTables settings object: see
  22214. * {@link DataTable.models.oSettings}
  22215. *
  22216. * And the following return is expected:
  22217. *
  22218. * * {node|null} The element which contains your feature. Note that the
  22219. * return may also be void if your plug-in does not require to inject any
  22220. * DOM elements into DataTables control (`dom`) - for example this might
  22221. * be useful when developing a plug-in which allows table control via
  22222. * keyboard entry
  22223. *
  22224. * @type array
  22225. *
  22226. * @example
  22227. * $.fn.dataTable.ext.features.push( {
  22228. * "fnInit": function( oSettings ) {
  22229. * return new TableTools( { "oDTSettings": oSettings } );
  22230. * },
  22231. * "cFeature": "T"
  22232. * } );
  22233. */
  22234. feature: [],
  22235. /**
  22236. * Row searching.
  22237. *
  22238. * This method of searching is complimentary to the default type based
  22239. * searching, and a lot more comprehensive as it allows you complete control
  22240. * over the searching logic. Each element in this array is a function
  22241. * (parameters described below) that is called for every row in the table,
  22242. * and your logic decides if it should be included in the searching data set
  22243. * or not.
  22244. *
  22245. * Searching functions have the following input parameters:
  22246. *
  22247. * 1. `{object}` DataTables settings object: see
  22248. * {@link DataTable.models.oSettings}
  22249. * 2. `{array|object}` Data for the row to be processed (same as the
  22250. * original format that was passed in as the data source, or an array
  22251. * from a DOM data source
  22252. * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
  22253. * can be useful to retrieve the `TR` element if you need DOM interaction.
  22254. *
  22255. * And the following return is expected:
  22256. *
  22257. * * {boolean} Include the row in the searched result set (true) or not
  22258. * (false)
  22259. *
  22260. * Note that as with the main search ability in DataTables, technically this
  22261. * is "filtering", since it is subtractive. However, for consistency in
  22262. * naming we call it searching here.
  22263. *
  22264. * @type array
  22265. * @default []
  22266. *
  22267. * @example
  22268. * // The following example shows custom search being applied to the
  22269. * // fourth column (i.e. the data[3] index) based on two input values
  22270. * // from the end-user, matching the data in a certain range.
  22271. * $.fn.dataTable.ext.search.push(
  22272. * function( settings, data, dataIndex ) {
  22273. * var min = document.getElementById('min').value * 1;
  22274. * var max = document.getElementById('max').value * 1;
  22275. * var version = data[3] == "-" ? 0 : data[3]*1;
  22276. *
  22277. * if ( min == "" && max == "" ) {
  22278. * return true;
  22279. * }
  22280. * else if ( min == "" && version < max ) {
  22281. * return true;
  22282. * }
  22283. * else if ( min < version && "" == max ) {
  22284. * return true;
  22285. * }
  22286. * else if ( min < version && version < max ) {
  22287. * return true;
  22288. * }
  22289. * return false;
  22290. * }
  22291. * );
  22292. */
  22293. search: [],
  22294. /**
  22295. * Selector extensions
  22296. *
  22297. * The `selector` option can be used to extend the options available for the
  22298. * selector modifier options (`selector-modifier` object data type) that
  22299. * each of the three built in selector types offer (row, column and cell +
  22300. * their plural counterparts). For example the Select extension uses this
  22301. * mechanism to provide an option to select only rows, columns and cells
  22302. * that have been marked as selected by the end user (`{selected: true}`),
  22303. * which can be used in conjunction with the existing built in selector
  22304. * options.
  22305. *
  22306. * Each property is an array to which functions can be pushed. The functions
  22307. * take three attributes:
  22308. *
  22309. * * Settings object for the host table
  22310. * * Options object (`selector-modifier` object type)
  22311. * * Array of selected item indexes
  22312. *
  22313. * The return is an array of the resulting item indexes after the custom
  22314. * selector has been applied.
  22315. *
  22316. * @type object
  22317. */
  22318. selector: {
  22319. cell: [],
  22320. column: [],
  22321. row: []
  22322. },
  22323. /**
  22324. * Internal functions, exposed for used in plug-ins.
  22325. *
  22326. * Please note that you should not need to use the internal methods for
  22327. * anything other than a plug-in (and even then, try to avoid if possible).
  22328. * The internal function may change between releases.
  22329. *
  22330. * @type object
  22331. * @default {}
  22332. */
  22333. internal: {},
  22334. /**
  22335. * Legacy configuration options. Enable and disable legacy options that
  22336. * are available in DataTables.
  22337. *
  22338. * @type object
  22339. */
  22340. legacy: {
  22341. /**
  22342. * Enable / disable DataTables 1.9 compatible server-side processing
  22343. * requests
  22344. *
  22345. * @type boolean
  22346. * @default null
  22347. */
  22348. ajax: null
  22349. },
  22350. /**
  22351. * Pagination plug-in methods.
  22352. *
  22353. * Each entry in this object is a function and defines which buttons should
  22354. * be shown by the pagination rendering method that is used for the table:
  22355. * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
  22356. * buttons are displayed in the document, while the functions here tell it
  22357. * what buttons to display. This is done by returning an array of button
  22358. * descriptions (what each button will do).
  22359. *
  22360. * Pagination types (the four built in options and any additional plug-in
  22361. * options defined here) can be used through the `paginationType`
  22362. * initialisation parameter.
  22363. *
  22364. * The functions defined take two parameters:
  22365. *
  22366. * 1. `{int} page` The current page index
  22367. * 2. `{int} pages` The number of pages in the table
  22368. *
  22369. * Each function is expected to return an array where each element of the
  22370. * array can be one of:
  22371. *
  22372. * * `first` - Jump to first page when activated
  22373. * * `last` - Jump to last page when activated
  22374. * * `previous` - Show previous page when activated
  22375. * * `next` - Show next page when activated
  22376. * * `{int}` - Show page of the index given
  22377. * * `{array}` - A nested array containing the above elements to add a
  22378. * containing 'DIV' element (might be useful for styling).
  22379. *
  22380. * Note that DataTables v1.9- used this object slightly differently whereby
  22381. * an object with two functions would be defined for each plug-in. That
  22382. * ability is still supported by DataTables 1.10+ to provide backwards
  22383. * compatibility, but this option of use is now decremented and no longer
  22384. * documented in DataTables 1.10+.
  22385. *
  22386. * @type object
  22387. * @default {}
  22388. *
  22389. * @example
  22390. * // Show previous, next and current page buttons only
  22391. * $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
  22392. * return [ 'previous', page, 'next' ];
  22393. * };
  22394. */
  22395. pager: {},
  22396. renderer: {
  22397. pageButton: {},
  22398. header: {}
  22399. },
  22400. /**
  22401. * Ordering plug-ins - custom data source
  22402. *
  22403. * The extension options for ordering of data available here is complimentary
  22404. * to the default type based ordering that DataTables typically uses. It
  22405. * allows much greater control over the the data that is being used to
  22406. * order a column, but is necessarily therefore more complex.
  22407. *
  22408. * This type of ordering is useful if you want to do ordering based on data
  22409. * live from the DOM (for example the contents of an 'input' element) rather
  22410. * than just the static string that DataTables knows of.
  22411. *
  22412. * The way these plug-ins work is that you create an array of the values you
  22413. * wish to be ordering for the column in question and then return that
  22414. * array. The data in the array much be in the index order of the rows in
  22415. * the table (not the currently ordering order!). Which order data gathering
  22416. * function is run here depends on the `dt-init columns.orderDataType`
  22417. * parameter that is used for the column (if any).
  22418. *
  22419. * The functions defined take two parameters:
  22420. *
  22421. * 1. `{object}` DataTables settings object: see
  22422. * {@link DataTable.models.oSettings}
  22423. * 2. `{int}` Target column index
  22424. *
  22425. * Each function is expected to return an array:
  22426. *
  22427. * * `{array}` Data for the column to be ordering upon
  22428. *
  22429. * @type array
  22430. *
  22431. * @example
  22432. * // Ordering using `input` node values
  22433. * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )
  22434. * {
  22435. * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
  22436. * return $('input', td).val();
  22437. * } );
  22438. * }
  22439. */
  22440. order: {},
  22441. /**
  22442. * Type based plug-ins.
  22443. *
  22444. * Each column in DataTables has a type assigned to it, either by automatic
  22445. * detection or by direct assignment using the `type` option for the column.
  22446. * The type of a column will effect how it is ordering and search (plug-ins
  22447. * can also make use of the column type if required).
  22448. *
  22449. * @namespace
  22450. */
  22451. type: {
  22452. /**
  22453. * Type detection functions.
  22454. *
  22455. * The functions defined in this object are used to automatically detect
  22456. * a column's type, making initialisation of DataTables super easy, even
  22457. * when complex data is in the table.
  22458. *
  22459. * The functions defined take two parameters:
  22460. *
  22461. * 1. `{*}` Data from the column cell to be analysed
  22462. * 2. `{settings}` DataTables settings object. This can be used to
  22463. * perform context specific type detection - for example detection
  22464. * based on language settings such as using a comma for a decimal
  22465. * place. Generally speaking the options from the settings will not
  22466. * be required
  22467. *
  22468. * Each function is expected to return:
  22469. *
  22470. * * `{string|null}` Data type detected, or null if unknown (and thus
  22471. * pass it on to the other type detection functions.
  22472. *
  22473. * @type array
  22474. *
  22475. * @example
  22476. * // Currency type detection plug-in:
  22477. * $.fn.dataTable.ext.type.detect.push(
  22478. * function ( data, settings ) {
  22479. * // Check the numeric part
  22480. * if ( ! $.isNumeric( data.substring(1) ) ) {
  22481. * return null;
  22482. * }
  22483. *
  22484. * // Check prefixed by currency
  22485. * if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {
  22486. * return 'currency';
  22487. * }
  22488. * return null;
  22489. * }
  22490. * );
  22491. */
  22492. detect: [],
  22493. /**
  22494. * Type based search formatting.
  22495. *
  22496. * The type based searching functions can be used to pre-format the
  22497. * data to be search on. For example, it can be used to strip HTML
  22498. * tags or to de-format telephone numbers for numeric only searching.
  22499. *
  22500. * Note that is a search is not defined for a column of a given type,
  22501. * no search formatting will be performed.
  22502. *
  22503. * Pre-processing of searching data plug-ins - When you assign the sType
  22504. * for a column (or have it automatically detected for you by DataTables
  22505. * or a type detection plug-in), you will typically be using this for
  22506. * custom sorting, but it can also be used to provide custom searching
  22507. * by allowing you to pre-processing the data and returning the data in
  22508. * the format that should be searched upon. This is done by adding
  22509. * functions this object with a parameter name which matches the sType
  22510. * for that target column. This is the corollary of <i>afnSortData</i>
  22511. * for searching data.
  22512. *
  22513. * The functions defined take a single parameter:
  22514. *
  22515. * 1. `{*}` Data from the column cell to be prepared for searching
  22516. *
  22517. * Each function is expected to return:
  22518. *
  22519. * * `{string|null}` Formatted string that will be used for the searching.
  22520. *
  22521. * @type object
  22522. * @default {}
  22523. *
  22524. * @example
  22525. * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
  22526. * return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
  22527. * }
  22528. */
  22529. search: {},
  22530. /**
  22531. * Type based ordering.
  22532. *
  22533. * The column type tells DataTables what ordering to apply to the table
  22534. * when a column is sorted upon. The order for each type that is defined,
  22535. * is defined by the functions available in this object.
  22536. *
  22537. * Each ordering option can be described by three properties added to
  22538. * this object:
  22539. *
  22540. * * `{type}-pre` - Pre-formatting function
  22541. * * `{type}-asc` - Ascending order function
  22542. * * `{type}-desc` - Descending order function
  22543. *
  22544. * All three can be used together, only `{type}-pre` or only
  22545. * `{type}-asc` and `{type}-desc` together. It is generally recommended
  22546. * that only `{type}-pre` is used, as this provides the optimal
  22547. * implementation in terms of speed, although the others are provided
  22548. * for compatibility with existing Javascript sort functions.
  22549. *
  22550. * `{type}-pre`: Functions defined take a single parameter:
  22551. *
  22552. * 1. `{*}` Data from the column cell to be prepared for ordering
  22553. *
  22554. * And return:
  22555. *
  22556. * * `{*}` Data to be sorted upon
  22557. *
  22558. * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
  22559. * functions, taking two parameters:
  22560. *
  22561. * 1. `{*}` Data to compare to the second parameter
  22562. * 2. `{*}` Data to compare to the first parameter
  22563. *
  22564. * And returning:
  22565. *
  22566. * * `{*}` Ordering match: <0 if first parameter should be sorted lower
  22567. * than the second parameter, ===0 if the two parameters are equal and
  22568. * >0 if the first parameter should be sorted height than the second
  22569. * parameter.
  22570. *
  22571. * @type object
  22572. * @default {}
  22573. *
  22574. * @example
  22575. * // Numeric ordering of formatted numbers with a pre-formatter
  22576. * $.extend( $.fn.dataTable.ext.type.order, {
  22577. * "string-pre": function(x) {
  22578. * a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
  22579. * return parseFloat( a );
  22580. * }
  22581. * } );
  22582. *
  22583. * @example
  22584. * // Case-sensitive string ordering, with no pre-formatting method
  22585. * $.extend( $.fn.dataTable.ext.order, {
  22586. * "string-case-asc": function(x,y) {
  22587. * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
  22588. * },
  22589. * "string-case-desc": function(x,y) {
  22590. * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
  22591. * }
  22592. * } );
  22593. */
  22594. order: {}
  22595. },
  22596. /**
  22597. * Unique DataTables instance counter
  22598. *
  22599. * @type int
  22600. * @private
  22601. */
  22602. _unique: 0,
  22603. //
  22604. // Depreciated
  22605. // The following properties are retained for backwards compatiblity only.
  22606. // The should not be used in new projects and will be removed in a future
  22607. // version
  22608. //
  22609. /**
  22610. * Version check function.
  22611. * @type function
  22612. * @depreciated Since 1.10
  22613. */
  22614. fnVersionCheck: DataTable.fnVersionCheck,
  22615. /**
  22616. * Index for what 'this' index API functions should use
  22617. * @type int
  22618. * @deprecated Since v1.10
  22619. */
  22620. iApiIndex: 0,
  22621. /**
  22622. * jQuery UI class container
  22623. * @type object
  22624. * @deprecated Since v1.10
  22625. */
  22626. oJUIClasses: {},
  22627. /**
  22628. * Software version
  22629. * @type string
  22630. * @deprecated Since v1.10
  22631. */
  22632. sVersion: DataTable.version
  22633. };
  22634. //
  22635. // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
  22636. //
  22637. $.extend( _ext, {
  22638. afnFiltering: _ext.search,
  22639. aTypes: _ext.type.detect,
  22640. ofnSearch: _ext.type.search,
  22641. oSort: _ext.type.order,
  22642. afnSortData: _ext.order,
  22643. aoFeatures: _ext.feature,
  22644. oApi: _ext.internal,
  22645. oStdClasses: _ext.classes,
  22646. oPagination: _ext.pager
  22647. } );
  22648. $.extend( DataTable.ext.classes, {
  22649. "sTable": "dataTable",
  22650. "sNoFooter": "no-footer",
  22651. /* Paging buttons */
  22652. "sPageButton": "paginate_button",
  22653. "sPageButtonActive": "current",
  22654. "sPageButtonDisabled": "disabled",
  22655. /* Striping classes */
  22656. "sStripeOdd": "odd",
  22657. "sStripeEven": "even",
  22658. /* Empty row */
  22659. "sRowEmpty": "dataTables_empty",
  22660. /* Features */
  22661. "sWrapper": "dataTables_wrapper",
  22662. "sFilter": "dataTables_filter",
  22663. "sInfo": "dataTables_info",
  22664. "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
  22665. "sLength": "dataTables_length",
  22666. "sProcessing": "dataTables_processing",
  22667. /* Sorting */
  22668. "sSortAsc": "sorting_asc",
  22669. "sSortDesc": "sorting_desc",
  22670. "sSortable": "sorting", /* Sortable in both directions */
  22671. "sSortableAsc": "sorting_asc_disabled",
  22672. "sSortableDesc": "sorting_desc_disabled",
  22673. "sSortableNone": "sorting_disabled",
  22674. "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
  22675. /* Filtering */
  22676. "sFilterInput": "",
  22677. /* Page length */
  22678. "sLengthSelect": "",
  22679. /* Scrolling */
  22680. "sScrollWrapper": "dataTables_scroll",
  22681. "sScrollHead": "dataTables_scrollHead",
  22682. "sScrollHeadInner": "dataTables_scrollHeadInner",
  22683. "sScrollBody": "dataTables_scrollBody",
  22684. "sScrollFoot": "dataTables_scrollFoot",
  22685. "sScrollFootInner": "dataTables_scrollFootInner",
  22686. /* Misc */
  22687. "sHeaderTH": "",
  22688. "sFooterTH": "",
  22689. // Deprecated
  22690. "sSortJUIAsc": "",
  22691. "sSortJUIDesc": "",
  22692. "sSortJUI": "",
  22693. "sSortJUIAscAllowed": "",
  22694. "sSortJUIDescAllowed": "",
  22695. "sSortJUIWrapper": "",
  22696. "sSortIcon": "",
  22697. "sJUIHeader": "",
  22698. "sJUIFooter": ""
  22699. } );
  22700. (function() {
  22701. // Reused strings for better compression. Closure compiler appears to have a
  22702. // weird edge case where it is trying to expand strings rather than use the
  22703. // variable version. This results in about 200 bytes being added, for very
  22704. // little preference benefit since it this run on script load only.
  22705. var _empty = '';
  22706. _empty = '';
  22707. var _stateDefault = _empty + 'ui-state-default';
  22708. var _sortIcon = _empty + 'css_right ui-icon ui-icon-';
  22709. var _headerFooter = _empty + 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix';
  22710. $.extend( DataTable.ext.oJUIClasses, DataTable.ext.classes, {
  22711. /* Full numbers paging buttons */
  22712. "sPageButton": "fg-button ui-button "+_stateDefault,
  22713. "sPageButtonActive": "ui-state-disabled",
  22714. "sPageButtonDisabled": "ui-state-disabled",
  22715. /* Features */
  22716. "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+
  22717. "ui-buttonset-multi paging_", /* Note that the type is postfixed */
  22718. /* Sorting */
  22719. "sSortAsc": _stateDefault+" sorting_asc",
  22720. "sSortDesc": _stateDefault+" sorting_desc",
  22721. "sSortable": _stateDefault+" sorting",
  22722. "sSortableAsc": _stateDefault+" sorting_asc_disabled",
  22723. "sSortableDesc": _stateDefault+" sorting_desc_disabled",
  22724. "sSortableNone": _stateDefault+" sorting_disabled",
  22725. "sSortJUIAsc": _sortIcon+"triangle-1-n",
  22726. "sSortJUIDesc": _sortIcon+"triangle-1-s",
  22727. "sSortJUI": _sortIcon+"carat-2-n-s",
  22728. "sSortJUIAscAllowed": _sortIcon+"carat-1-n",
  22729. "sSortJUIDescAllowed": _sortIcon+"carat-1-s",
  22730. "sSortJUIWrapper": "DataTables_sort_wrapper",
  22731. "sSortIcon": "DataTables_sort_icon",
  22732. /* Scrolling */
  22733. "sScrollHead": "dataTables_scrollHead "+_stateDefault,
  22734. "sScrollFoot": "dataTables_scrollFoot "+_stateDefault,
  22735. /* Misc */
  22736. "sHeaderTH": _stateDefault,
  22737. "sFooterTH": _stateDefault,
  22738. "sJUIHeader": _headerFooter+" ui-corner-tl ui-corner-tr",
  22739. "sJUIFooter": _headerFooter+" ui-corner-bl ui-corner-br"
  22740. } );
  22741. }());
  22742. var extPagination = DataTable.ext.pager;
  22743. function _numbers ( page, pages ) {
  22744. var
  22745. numbers = [],
  22746. buttons = extPagination.numbers_length,
  22747. half = Math.floor( buttons / 2 ),
  22748. i = 1;
  22749. if ( pages <= buttons ) {
  22750. numbers = _range( 0, pages );
  22751. }
  22752. else if ( page <= half ) {
  22753. numbers = _range( 0, buttons-2 );
  22754. numbers.push( 'ellipsis' );
  22755. numbers.push( pages-1 );
  22756. }
  22757. else if ( page >= pages - 1 - half ) {
  22758. numbers = _range( pages-(buttons-2), pages );
  22759. numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6
  22760. numbers.splice( 0, 0, 0 );
  22761. }
  22762. else {
  22763. numbers = _range( page-half+2, page+half-1 );
  22764. numbers.push( 'ellipsis' );
  22765. numbers.push( pages-1 );
  22766. numbers.splice( 0, 0, 'ellipsis' );
  22767. numbers.splice( 0, 0, 0 );
  22768. }
  22769. numbers.DT_el = 'span';
  22770. return numbers;
  22771. }
  22772. $.extend( extPagination, {
  22773. simple: function ( page, pages ) {
  22774. return [ 'previous', 'next' ];
  22775. },
  22776. full: function ( page, pages ) {
  22777. return [ 'first', 'previous', 'next', 'last' ];
  22778. },
  22779. numbers: function ( page, pages ) {
  22780. return [ _numbers(page, pages) ];
  22781. },
  22782. simple_numbers: function ( page, pages ) {
  22783. return [ 'previous', _numbers(page, pages), 'next' ];
  22784. },
  22785. full_numbers: function ( page, pages ) {
  22786. return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];
  22787. },
  22788. first_last_numbers: function (page, pages) {
  22789. return ['first', _numbers(page, pages), 'last'];
  22790. },
  22791. // For testing and plug-ins to use
  22792. _numbers: _numbers,
  22793. // Number of number buttons (including ellipsis) to show. _Must be odd!_
  22794. numbers_length: 7
  22795. } );
  22796. $.extend( true, DataTable.ext.renderer, {
  22797. pageButton: {
  22798. _: function ( settings, host, idx, buttons, page, pages ) {
  22799. var classes = settings.oClasses;
  22800. var lang = settings.oLanguage.oPaginate;
  22801. var aria = settings.oLanguage.oAria.paginate || {};
  22802. var btnDisplay, btnClass, counter=0;
  22803. var attach = function( container, buttons ) {
  22804. var i, ien, node, button;
  22805. var clickHandler = function ( e ) {
  22806. _fnPageChange( settings, e.data.action, true );
  22807. };
  22808. for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
  22809. button = buttons[i];
  22810. if ( $.isArray( button ) ) {
  22811. var inner = $( '<'+(button.DT_el || 'div')+'/>' )
  22812. .appendTo( container );
  22813. attach( inner, button );
  22814. }
  22815. else {
  22816. btnDisplay = null;
  22817. btnClass = '';
  22818. switch ( button ) {
  22819. case 'ellipsis':
  22820. container.append('<span class="ellipsis">&#x2026;</span>');
  22821. break;
  22822. case 'first':
  22823. btnDisplay = lang.sFirst;
  22824. btnClass = button + (page > 0 ?
  22825. '' : ' '+classes.sPageButtonDisabled);
  22826. break;
  22827. case 'previous':
  22828. btnDisplay = lang.sPrevious;
  22829. btnClass = button + (page > 0 ?
  22830. '' : ' '+classes.sPageButtonDisabled);
  22831. break;
  22832. case 'next':
  22833. btnDisplay = lang.sNext;
  22834. btnClass = button + (page < pages-1 ?
  22835. '' : ' '+classes.sPageButtonDisabled);
  22836. break;
  22837. case 'last':
  22838. btnDisplay = lang.sLast;
  22839. btnClass = button + (page < pages-1 ?
  22840. '' : ' '+classes.sPageButtonDisabled);
  22841. break;
  22842. default:
  22843. btnDisplay = button + 1;
  22844. btnClass = page === button ?
  22845. classes.sPageButtonActive : '';
  22846. break;
  22847. }
  22848. if ( btnDisplay !== null ) {
  22849. node = $('<a>', {
  22850. 'class': classes.sPageButton+' '+btnClass,
  22851. 'aria-controls': settings.sTableId,
  22852. 'aria-label': aria[ button ],
  22853. 'data-dt-idx': counter,
  22854. 'tabindex': settings.iTabIndex,
  22855. 'id': idx === 0 && typeof button === 'string' ?
  22856. settings.sTableId +'_'+ button :
  22857. null
  22858. } )
  22859. .html( btnDisplay )
  22860. .appendTo( container );
  22861. _fnBindAction(
  22862. node, {action: button}, clickHandler
  22863. );
  22864. counter++;
  22865. }
  22866. }
  22867. }
  22868. };
  22869. // IE9 throws an 'unknown error' if document.activeElement is used
  22870. // inside an iframe or frame. Try / catch the error. Not good for
  22871. // accessibility, but neither are frames.
  22872. var activeEl;
  22873. try {
  22874. // Because this approach is destroying and recreating the paging
  22875. // elements, focus is lost on the select button which is bad for
  22876. // accessibility. So we want to restore focus once the draw has
  22877. // completed
  22878. activeEl = $(host).find(document.activeElement).data('dt-idx');
  22879. }
  22880. catch (e) {}
  22881. attach( $(host).empty(), buttons );
  22882. if ( activeEl !== undefined ) {
  22883. $(host).find( '[data-dt-idx='+activeEl+']' ).focus();
  22884. }
  22885. }
  22886. }
  22887. } );
  22888. // Built in type detection. See model.ext.aTypes for information about
  22889. // what is required from this methods.
  22890. $.extend( DataTable.ext.type.detect, [
  22891. // Plain numbers - first since V8 detects some plain numbers as dates
  22892. // e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).
  22893. function ( d, settings )
  22894. {
  22895. var decimal = settings.oLanguage.sDecimal;
  22896. return _isNumber( d, decimal ) ? 'num'+decimal : null;
  22897. },
  22898. // Dates (only those recognised by the browser's Date.parse)
  22899. function ( d, settings )
  22900. {
  22901. // V8 tries _very_ hard to make a string passed into `Date.parse()`
  22902. // valid, so we need to use a regex to restrict date formats. Use a
  22903. // plug-in for anything other than ISO8601 style strings
  22904. if ( d && !(d instanceof Date) && ! _re_date.test(d) ) {
  22905. return null;
  22906. }
  22907. var parsed = Date.parse(d);
  22908. return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;
  22909. },
  22910. // Formatted numbers
  22911. function ( d, settings )
  22912. {
  22913. var decimal = settings.oLanguage.sDecimal;
  22914. return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;
  22915. },
  22916. // HTML numeric
  22917. function ( d, settings )
  22918. {
  22919. var decimal = settings.oLanguage.sDecimal;
  22920. return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;
  22921. },
  22922. // HTML numeric, formatted
  22923. function ( d, settings )
  22924. {
  22925. var decimal = settings.oLanguage.sDecimal;
  22926. return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;
  22927. },
  22928. // HTML (this is strict checking - there must be html)
  22929. function ( d, settings )
  22930. {
  22931. return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
  22932. 'html' : null;
  22933. }
  22934. ] );
  22935. // Filter formatting functions. See model.ext.ofnSearch for information about
  22936. // what is required from these methods.
  22937. //
  22938. // Note that additional search methods are added for the html numbers and
  22939. // html formatted numbers by `_addNumericSort()` when we know what the decimal
  22940. // place is
  22941. $.extend( DataTable.ext.type.search, {
  22942. html: function ( data ) {
  22943. return _empty(data) ?
  22944. data :
  22945. typeof data === 'string' ?
  22946. data
  22947. .replace( _re_new_lines, " " )
  22948. .replace( _re_html, "" ) :
  22949. '';
  22950. },
  22951. string: function ( data ) {
  22952. return _empty(data) ?
  22953. data :
  22954. typeof data === 'string' ?
  22955. data.replace( _re_new_lines, " " ) :
  22956. data;
  22957. }
  22958. } );
  22959. var __numericReplace = function ( d, decimalPlace, re1, re2 ) {
  22960. if ( d !== 0 && (!d || d === '-') ) {
  22961. return -Infinity;
  22962. }
  22963. // If a decimal place other than `.` is used, it needs to be given to the
  22964. // function so we can detect it and replace with a `.` which is the only
  22965. // decimal place Javascript recognises - it is not locale aware.
  22966. if ( decimalPlace ) {
  22967. d = _numToDecimal( d, decimalPlace );
  22968. }
  22969. if ( d.replace ) {
  22970. if ( re1 ) {
  22971. d = d.replace( re1, '' );
  22972. }
  22973. if ( re2 ) {
  22974. d = d.replace( re2, '' );
  22975. }
  22976. }
  22977. return d * 1;
  22978. };
  22979. // Add the numeric 'deformatting' functions for sorting and search. This is done
  22980. // in a function to provide an easy ability for the language options to add
  22981. // additional methods if a non-period decimal place is used.
  22982. function _addNumericSort ( decimalPlace ) {
  22983. $.each(
  22984. {
  22985. // Plain numbers
  22986. "num": function ( d ) {
  22987. return __numericReplace( d, decimalPlace );
  22988. },
  22989. // Formatted numbers
  22990. "num-fmt": function ( d ) {
  22991. return __numericReplace( d, decimalPlace, _re_formatted_numeric );
  22992. },
  22993. // HTML numeric
  22994. "html-num": function ( d ) {
  22995. return __numericReplace( d, decimalPlace, _re_html );
  22996. },
  22997. // HTML numeric, formatted
  22998. "html-num-fmt": function ( d ) {
  22999. return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );
  23000. }
  23001. },
  23002. function ( key, fn ) {
  23003. // Add the ordering method
  23004. _ext.type.order[ key+decimalPlace+'-pre' ] = fn;
  23005. // For HTML types add a search formatter that will strip the HTML
  23006. if ( key.match(/^html\-/) ) {
  23007. _ext.type.search[ key+decimalPlace ] = _ext.type.search.html;
  23008. }
  23009. }
  23010. );
  23011. }
  23012. // Default sort methods
  23013. $.extend( _ext.type.order, {
  23014. // Dates
  23015. "date-pre": function ( d ) {
  23016. return Date.parse( d ) || -Infinity;
  23017. },
  23018. // html
  23019. "html-pre": function ( a ) {
  23020. return _empty(a) ?
  23021. '' :
  23022. a.replace ?
  23023. a.replace( /<.*?>/g, "" ).toLowerCase() :
  23024. a+'';
  23025. },
  23026. // string
  23027. "string-pre": function ( a ) {
  23028. // This is a little complex, but faster than always calling toString,
  23029. // http://jsperf.com/tostring-v-check
  23030. return _empty(a) ?
  23031. '' :
  23032. typeof a === 'string' ?
  23033. a.toLowerCase() :
  23034. ! a.toString ?
  23035. '' :
  23036. a.toString();
  23037. },
  23038. // string-asc and -desc are retained only for compatibility with the old
  23039. // sort methods
  23040. "string-asc": function ( x, y ) {
  23041. return ((x < y) ? -1 : ((x > y) ? 1 : 0));
  23042. },
  23043. "string-desc": function ( x, y ) {
  23044. return ((x < y) ? 1 : ((x > y) ? -1 : 0));
  23045. }
  23046. } );
  23047. // Numeric sorting types - order doesn't matter here
  23048. _addNumericSort( '' );
  23049. $.extend( true, DataTable.ext.renderer, {
  23050. header: {
  23051. _: function ( settings, cell, column, classes ) {
  23052. // No additional mark-up required
  23053. // Attach a sort listener to update on sort - note that using the
  23054. // `DT` namespace will allow the event to be removed automatically
  23055. // on destroy, while the `dt` namespaced event is the one we are
  23056. // listening for
  23057. $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
  23058. if ( settings !== ctx ) { // need to check this this is the host
  23059. return; // table, not a nested one
  23060. }
  23061. var colIdx = column.idx;
  23062. cell
  23063. .removeClass(
  23064. column.sSortingClass +' '+
  23065. classes.sSortAsc +' '+
  23066. classes.sSortDesc
  23067. )
  23068. .addClass( columns[ colIdx ] == 'asc' ?
  23069. classes.sSortAsc : columns[ colIdx ] == 'desc' ?
  23070. classes.sSortDesc :
  23071. column.sSortingClass
  23072. );
  23073. } );
  23074. },
  23075. jqueryui: function ( settings, cell, column, classes ) {
  23076. $('<div/>')
  23077. .addClass( classes.sSortJUIWrapper )
  23078. .append( cell.contents() )
  23079. .append( $('<span/>')
  23080. .addClass( classes.sSortIcon+' '+column.sSortingClassJUI )
  23081. )
  23082. .appendTo( cell );
  23083. // Attach a sort listener to update on sort
  23084. $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
  23085. if ( settings !== ctx ) {
  23086. return;
  23087. }
  23088. var colIdx = column.idx;
  23089. cell
  23090. .removeClass( classes.sSortAsc +" "+classes.sSortDesc )
  23091. .addClass( columns[ colIdx ] == 'asc' ?
  23092. classes.sSortAsc : columns[ colIdx ] == 'desc' ?
  23093. classes.sSortDesc :
  23094. column.sSortingClass
  23095. );
  23096. cell
  23097. .find( 'span.'+classes.sSortIcon )
  23098. .removeClass(
  23099. classes.sSortJUIAsc +" "+
  23100. classes.sSortJUIDesc +" "+
  23101. classes.sSortJUI +" "+
  23102. classes.sSortJUIAscAllowed +" "+
  23103. classes.sSortJUIDescAllowed
  23104. )
  23105. .addClass( columns[ colIdx ] == 'asc' ?
  23106. classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ?
  23107. classes.sSortJUIDesc :
  23108. column.sSortingClassJUI
  23109. );
  23110. } );
  23111. }
  23112. }
  23113. } );
  23114. /*
  23115. * Public helper functions. These aren't used internally by DataTables, or
  23116. * called by any of the options passed into DataTables, but they can be used
  23117. * externally by developers working with DataTables. They are helper functions
  23118. * to make working with DataTables a little bit easier.
  23119. */
  23120. var __htmlEscapeEntities = function ( d ) {
  23121. return typeof d === 'string' ?
  23122. d.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;') :
  23123. d;
  23124. };
  23125. /**
  23126. * Helpers for `columns.render`.
  23127. *
  23128. * The options defined here can be used with the `columns.render` initialisation
  23129. * option to provide a display renderer. The following functions are defined:
  23130. *
  23131. * * `number` - Will format numeric data (defined by `columns.data`) for
  23132. * display, retaining the original unformatted data for sorting and filtering.
  23133. * It takes 5 parameters:
  23134. * * `string` - Thousands grouping separator
  23135. * * `string` - Decimal point indicator
  23136. * * `integer` - Number of decimal points to show
  23137. * * `string` (optional) - Prefix.
  23138. * * `string` (optional) - Postfix (/suffix).
  23139. * * `text` - Escape HTML to help prevent XSS attacks. It has no optional
  23140. * parameters.
  23141. *
  23142. * @example
  23143. * // Column definition using the number renderer
  23144. * {
  23145. * data: "salary",
  23146. * render: $.fn.dataTable.render.number( '\'', '.', 0, '$' )
  23147. * }
  23148. *
  23149. * @namespace
  23150. */
  23151. DataTable.render = {
  23152. number: function ( thousands, decimal, precision, prefix, postfix ) {
  23153. return {
  23154. display: function ( d ) {
  23155. if ( typeof d !== 'number' && typeof d !== 'string' ) {
  23156. return d;
  23157. }
  23158. var negative = d < 0 ? '-' : '';
  23159. var flo = parseFloat( d );
  23160. // If NaN then there isn't much formatting that we can do - just
  23161. // return immediately, escaping any HTML (this was supposed to
  23162. // be a number after all)
  23163. if ( isNaN( flo ) ) {
  23164. return __htmlEscapeEntities( d );
  23165. }
  23166. flo = flo.toFixed( precision );
  23167. d = Math.abs( flo );
  23168. var intPart = parseInt( d, 10 );
  23169. var floatPart = precision ?
  23170. decimal+(d - intPart).toFixed( precision ).substring( 2 ):
  23171. '';
  23172. return negative + (prefix||'') +
  23173. intPart.toString().replace(
  23174. /\B(?=(\d{3})+(?!\d))/g, thousands
  23175. ) +
  23176. floatPart +
  23177. (postfix||'');
  23178. }
  23179. };
  23180. },
  23181. text: function () {
  23182. return {
  23183. display: __htmlEscapeEntities
  23184. };
  23185. }
  23186. };
  23187. /*
  23188. * This is really a good bit rubbish this method of exposing the internal methods
  23189. * publicly... - To be fixed in 2.0 using methods on the prototype
  23190. */
  23191. /**
  23192. * Create a wrapper function for exporting an internal functions to an external API.
  23193. * @param {string} fn API function name
  23194. * @returns {function} wrapped function
  23195. * @memberof DataTable#internal
  23196. */
  23197. function _fnExternApiFunc (fn)
  23198. {
  23199. return function() {
  23200. var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(
  23201. Array.prototype.slice.call(arguments)
  23202. );
  23203. return DataTable.ext.internal[fn].apply( this, args );
  23204. };
  23205. }
  23206. /**
  23207. * Reference to internal functions for use by plug-in developers. Note that
  23208. * these methods are references to internal functions and are considered to be
  23209. * private. If you use these methods, be aware that they are liable to change
  23210. * between versions.
  23211. * @namespace
  23212. */
  23213. $.extend( DataTable.ext.internal, {
  23214. _fnExternApiFunc: _fnExternApiFunc,
  23215. _fnBuildAjax: _fnBuildAjax,
  23216. _fnAjaxUpdate: _fnAjaxUpdate,
  23217. _fnAjaxParameters: _fnAjaxParameters,
  23218. _fnAjaxUpdateDraw: _fnAjaxUpdateDraw,
  23219. _fnAjaxDataSrc: _fnAjaxDataSrc,
  23220. _fnAddColumn: _fnAddColumn,
  23221. _fnColumnOptions: _fnColumnOptions,
  23222. _fnAdjustColumnSizing: _fnAdjustColumnSizing,
  23223. _fnVisibleToColumnIndex: _fnVisibleToColumnIndex,
  23224. _fnColumnIndexToVisible: _fnColumnIndexToVisible,
  23225. _fnVisbleColumns: _fnVisbleColumns,
  23226. _fnGetColumns: _fnGetColumns,
  23227. _fnColumnTypes: _fnColumnTypes,
  23228. _fnApplyColumnDefs: _fnApplyColumnDefs,
  23229. _fnHungarianMap: _fnHungarianMap,
  23230. _fnCamelToHungarian: _fnCamelToHungarian,
  23231. _fnLanguageCompat: _fnLanguageCompat,
  23232. _fnBrowserDetect: _fnBrowserDetect,
  23233. _fnAddData: _fnAddData,
  23234. _fnAddTr: _fnAddTr,
  23235. _fnNodeToDataIndex: _fnNodeToDataIndex,
  23236. _fnNodeToColumnIndex: _fnNodeToColumnIndex,
  23237. _fnGetCellData: _fnGetCellData,
  23238. _fnSetCellData: _fnSetCellData,
  23239. _fnSplitObjNotation: _fnSplitObjNotation,
  23240. _fnGetObjectDataFn: _fnGetObjectDataFn,
  23241. _fnSetObjectDataFn: _fnSetObjectDataFn,
  23242. _fnGetDataMaster: _fnGetDataMaster,
  23243. _fnClearTable: _fnClearTable,
  23244. _fnDeleteIndex: _fnDeleteIndex,
  23245. _fnInvalidate: _fnInvalidate,
  23246. _fnGetRowElements: _fnGetRowElements,
  23247. _fnCreateTr: _fnCreateTr,
  23248. _fnBuildHead: _fnBuildHead,
  23249. _fnDrawHead: _fnDrawHead,
  23250. _fnDraw: _fnDraw,
  23251. _fnReDraw: _fnReDraw,
  23252. _fnAddOptionsHtml: _fnAddOptionsHtml,
  23253. _fnDetectHeader: _fnDetectHeader,
  23254. _fnGetUniqueThs: _fnGetUniqueThs,
  23255. _fnFeatureHtmlFilter: _fnFeatureHtmlFilter,
  23256. _fnFilterComplete: _fnFilterComplete,
  23257. _fnFilterCustom: _fnFilterCustom,
  23258. _fnFilterColumn: _fnFilterColumn,
  23259. _fnFilter: _fnFilter,
  23260. _fnFilterCreateSearch: _fnFilterCreateSearch,
  23261. _fnEscapeRegex: _fnEscapeRegex,
  23262. _fnFilterData: _fnFilterData,
  23263. _fnFeatureHtmlInfo: _fnFeatureHtmlInfo,
  23264. _fnUpdateInfo: _fnUpdateInfo,
  23265. _fnInfoMacros: _fnInfoMacros,
  23266. _fnInitialise: _fnInitialise,
  23267. _fnInitComplete: _fnInitComplete,
  23268. _fnLengthChange: _fnLengthChange,
  23269. _fnFeatureHtmlLength: _fnFeatureHtmlLength,
  23270. _fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,
  23271. _fnPageChange: _fnPageChange,
  23272. _fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,
  23273. _fnProcessingDisplay: _fnProcessingDisplay,
  23274. _fnFeatureHtmlTable: _fnFeatureHtmlTable,
  23275. _fnScrollDraw: _fnScrollDraw,
  23276. _fnApplyToChildren: _fnApplyToChildren,
  23277. _fnCalculateColumnWidths: _fnCalculateColumnWidths,
  23278. _fnThrottle: _fnThrottle,
  23279. _fnConvertToWidth: _fnConvertToWidth,
  23280. _fnGetWidestNode: _fnGetWidestNode,
  23281. _fnGetMaxLenString: _fnGetMaxLenString,
  23282. _fnStringToCss: _fnStringToCss,
  23283. _fnSortFlatten: _fnSortFlatten,
  23284. _fnSort: _fnSort,
  23285. _fnSortAria: _fnSortAria,
  23286. _fnSortListener: _fnSortListener,
  23287. _fnSortAttachListener: _fnSortAttachListener,
  23288. _fnSortingClasses: _fnSortingClasses,
  23289. _fnSortData: _fnSortData,
  23290. _fnSaveState: _fnSaveState,
  23291. _fnLoadState: _fnLoadState,
  23292. _fnSettingsFromNode: _fnSettingsFromNode,
  23293. _fnLog: _fnLog,
  23294. _fnMap: _fnMap,
  23295. _fnBindAction: _fnBindAction,
  23296. _fnCallbackReg: _fnCallbackReg,
  23297. _fnCallbackFire: _fnCallbackFire,
  23298. _fnLengthOverflow: _fnLengthOverflow,
  23299. _fnRenderer: _fnRenderer,
  23300. _fnDataSource: _fnDataSource,
  23301. _fnRowAttributes: _fnRowAttributes,
  23302. _fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
  23303. // in 1.10, so this dead-end function is
  23304. // added to prevent errors
  23305. } );
  23306. // jQuery access
  23307. $.fn.dataTable = DataTable;
  23308. // Provide access to the host jQuery object (circular reference)
  23309. DataTable.$ = $;
  23310. // Legacy aliases
  23311. $.fn.dataTableSettings = DataTable.settings;
  23312. $.fn.dataTableExt = DataTable.ext;
  23313. // With a capital `D` we return a DataTables API instance rather than a
  23314. // jQuery object
  23315. $.fn.DataTable = function ( opts ) {
  23316. return $(this).dataTable( opts ).api();
  23317. };
  23318. // All properties that are available to $.fn.dataTable should also be
  23319. // available on $.fn.DataTable
  23320. $.each( DataTable, function ( prop, val ) {
  23321. $.fn.DataTable[ prop ] = val;
  23322. } );
  23323. // Information about events fired by DataTables - for documentation.
  23324. /**
  23325. * Draw event, fired whenever the table is redrawn on the page, at the same
  23326. * point as fnDrawCallback. This may be useful for binding events or
  23327. * performing calculations when the table is altered at all.
  23328. * @name DataTable#draw.dt
  23329. * @event
  23330. * @param {event} e jQuery event object
  23331. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  23332. */
  23333. /**
  23334. * Search event, fired when the searching applied to the table (using the
  23335. * built-in global search, or column filters) is altered.
  23336. * @name DataTable#search.dt
  23337. * @event
  23338. * @param {event} e jQuery event object
  23339. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  23340. */
  23341. /**
  23342. * Page change event, fired when the paging of the table is altered.
  23343. * @name DataTable#page.dt
  23344. * @event
  23345. * @param {event} e jQuery event object
  23346. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  23347. */
  23348. /**
  23349. * Order event, fired when the ordering applied to the table is altered.
  23350. * @name DataTable#order.dt
  23351. * @event
  23352. * @param {event} e jQuery event object
  23353. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  23354. */
  23355. /**
  23356. * DataTables initialisation complete event, fired when the table is fully
  23357. * drawn, including Ajax data loaded, if Ajax data is required.
  23358. * @name DataTable#init.dt
  23359. * @event
  23360. * @param {event} e jQuery event object
  23361. * @param {object} oSettings DataTables settings object
  23362. * @param {object} json The JSON object request from the server - only
  23363. * present if client-side Ajax sourced data is used</li></ol>
  23364. */
  23365. /**
  23366. * State save event, fired when the table has changed state a new state save
  23367. * is required. This event allows modification of the state saving object
  23368. * prior to actually doing the save, including addition or other state
  23369. * properties (for plug-ins) or modification of a DataTables core property.
  23370. * @name DataTable#stateSaveParams.dt
  23371. * @event
  23372. * @param {event} e jQuery event object
  23373. * @param {object} oSettings DataTables settings object
  23374. * @param {object} json The state information to be saved
  23375. */
  23376. /**
  23377. * State load event, fired when the table is loading state from the stored
  23378. * data, but prior to the settings object being modified by the saved state
  23379. * - allowing modification of the saved state is required or loading of
  23380. * state for a plug-in.
  23381. * @name DataTable#stateLoadParams.dt
  23382. * @event
  23383. * @param {event} e jQuery event object
  23384. * @param {object} oSettings DataTables settings object
  23385. * @param {object} json The saved state information
  23386. */
  23387. /**
  23388. * State loaded event, fired when state has been loaded from stored data and
  23389. * the settings object has been modified by the loaded data.
  23390. * @name DataTable#stateLoaded.dt
  23391. * @event
  23392. * @param {event} e jQuery event object
  23393. * @param {object} oSettings DataTables settings object
  23394. * @param {object} json The saved state information
  23395. */
  23396. /**
  23397. * Processing event, fired when DataTables is doing some kind of processing
  23398. * (be it, order, searcg or anything else). It can be used to indicate to
  23399. * the end user that there is something happening, or that something has
  23400. * finished.
  23401. * @name DataTable#processing.dt
  23402. * @event
  23403. * @param {event} e jQuery event object
  23404. * @param {object} oSettings DataTables settings object
  23405. * @param {boolean} bShow Flag for if DataTables is doing processing or not
  23406. */
  23407. /**
  23408. * Ajax (XHR) event, fired whenever an Ajax request is completed from a
  23409. * request to made to the server for new data. This event is called before
  23410. * DataTables processed the returned data, so it can also be used to pre-
  23411. * process the data returned from the server, if needed.
  23412. *
  23413. * Note that this trigger is called in `fnServerData`, if you override
  23414. * `fnServerData` and which to use this event, you need to trigger it in you
  23415. * success function.
  23416. * @name DataTable#xhr.dt
  23417. * @event
  23418. * @param {event} e jQuery event object
  23419. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  23420. * @param {object} json JSON returned from the server
  23421. *
  23422. * @example
  23423. * // Use a custom property returned from the server in another DOM element
  23424. * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
  23425. * $('#status').html( json.status );
  23426. * } );
  23427. *
  23428. * @example
  23429. * // Pre-process the data returned from the server
  23430. * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
  23431. * for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {
  23432. * json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;
  23433. * }
  23434. * // Note no return - manipulate the data directly in the JSON object.
  23435. * } );
  23436. */
  23437. /**
  23438. * Destroy event, fired when the DataTable is destroyed by calling fnDestroy
  23439. * or passing the bDestroy:true parameter in the initialisation object. This
  23440. * can be used to remove bound events, added DOM nodes, etc.
  23441. * @name DataTable#destroy.dt
  23442. * @event
  23443. * @param {event} e jQuery event object
  23444. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  23445. */
  23446. /**
  23447. * Page length change event, fired when number of records to show on each
  23448. * page (the length) is changed.
  23449. * @name DataTable#length.dt
  23450. * @event
  23451. * @param {event} e jQuery event object
  23452. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  23453. * @param {integer} len New length
  23454. */
  23455. /**
  23456. * Column sizing has changed.
  23457. * @name DataTable#column-sizing.dt
  23458. * @event
  23459. * @param {event} e jQuery event object
  23460. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  23461. */
  23462. /**
  23463. * Column visibility has changed.
  23464. * @name DataTable#column-visibility.dt
  23465. * @event
  23466. * @param {event} e jQuery event object
  23467. * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
  23468. * @param {int} column Column index
  23469. * @param {bool} vis `false` if column now hidden, or `true` if visible
  23470. */
  23471. return $.fn.dataTable;
  23472. }));