semantic.js 713 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500
  1. /*
  2. * # Semantic UI - 2.2.6
  3. * https://github.com/Semantic-Org/Semantic-UI
  4. * http://www.semantic-ui.com/
  5. *
  6. * Copyright 2014 Contributors
  7. * Released under the MIT license
  8. * http://opensource.org/licenses/MIT
  9. *
  10. */
  11. /*!
  12. * # Semantic UI 2.2.6 - Site
  13. * http://github.com/semantic-org/semantic-ui/
  14. *
  15. *
  16. * Released under the MIT license
  17. * http://opensource.org/licenses/MIT
  18. *
  19. */
  20. ;(function ($, window, document, undefined) {
  21. $.site = $.fn.site = function(parameters) {
  22. var
  23. time = new Date().getTime(),
  24. performance = [],
  25. query = arguments[0],
  26. methodInvoked = (typeof query == 'string'),
  27. queryArguments = [].slice.call(arguments, 1),
  28. settings = ( $.isPlainObject(parameters) )
  29. ? $.extend(true, {}, $.site.settings, parameters)
  30. : $.extend({}, $.site.settings),
  31. namespace = settings.namespace,
  32. error = settings.error,
  33. eventNamespace = '.' + namespace,
  34. moduleNamespace = 'module-' + namespace,
  35. $document = $(document),
  36. $module = $document,
  37. element = this,
  38. instance = $module.data(moduleNamespace),
  39. module,
  40. returnedValue
  41. ;
  42. module = {
  43. initialize: function() {
  44. module.instantiate();
  45. },
  46. instantiate: function() {
  47. module.verbose('Storing instance of site', module);
  48. instance = module;
  49. $module
  50. .data(moduleNamespace, module)
  51. ;
  52. },
  53. normalize: function() {
  54. module.fix.console();
  55. module.fix.requestAnimationFrame();
  56. },
  57. fix: {
  58. console: function() {
  59. module.debug('Normalizing window.console');
  60. if (console === undefined || console.log === undefined) {
  61. module.verbose('Console not available, normalizing events');
  62. module.disable.console();
  63. }
  64. if (typeof console.group == 'undefined' || typeof console.groupEnd == 'undefined' || typeof console.groupCollapsed == 'undefined') {
  65. module.verbose('Console group not available, normalizing events');
  66. window.console.group = function() {};
  67. window.console.groupEnd = function() {};
  68. window.console.groupCollapsed = function() {};
  69. }
  70. if (typeof console.markTimeline == 'undefined') {
  71. module.verbose('Mark timeline not available, normalizing events');
  72. window.console.markTimeline = function() {};
  73. }
  74. },
  75. consoleClear: function() {
  76. module.debug('Disabling programmatic console clearing');
  77. window.console.clear = function() {};
  78. },
  79. requestAnimationFrame: function() {
  80. module.debug('Normalizing requestAnimationFrame');
  81. if(window.requestAnimationFrame === undefined) {
  82. module.debug('RequestAnimationFrame not available, normalizing event');
  83. window.requestAnimationFrame = window.requestAnimationFrame
  84. || window.mozRequestAnimationFrame
  85. || window.webkitRequestAnimationFrame
  86. || window.msRequestAnimationFrame
  87. || function(callback) { setTimeout(callback, 0); }
  88. ;
  89. }
  90. }
  91. },
  92. moduleExists: function(name) {
  93. return ($.fn[name] !== undefined && $.fn[name].settings !== undefined);
  94. },
  95. enabled: {
  96. modules: function(modules) {
  97. var
  98. enabledModules = []
  99. ;
  100. modules = modules || settings.modules;
  101. $.each(modules, function(index, name) {
  102. if(module.moduleExists(name)) {
  103. enabledModules.push(name);
  104. }
  105. });
  106. return enabledModules;
  107. }
  108. },
  109. disabled: {
  110. modules: function(modules) {
  111. var
  112. disabledModules = []
  113. ;
  114. modules = modules || settings.modules;
  115. $.each(modules, function(index, name) {
  116. if(!module.moduleExists(name)) {
  117. disabledModules.push(name);
  118. }
  119. });
  120. return disabledModules;
  121. }
  122. },
  123. change: {
  124. setting: function(setting, value, modules, modifyExisting) {
  125. modules = (typeof modules === 'string')
  126. ? (modules === 'all')
  127. ? settings.modules
  128. : [modules]
  129. : modules || settings.modules
  130. ;
  131. modifyExisting = (modifyExisting !== undefined)
  132. ? modifyExisting
  133. : true
  134. ;
  135. $.each(modules, function(index, name) {
  136. var
  137. namespace = (module.moduleExists(name))
  138. ? $.fn[name].settings.namespace || false
  139. : true,
  140. $existingModules
  141. ;
  142. if(module.moduleExists(name)) {
  143. module.verbose('Changing default setting', setting, value, name);
  144. $.fn[name].settings[setting] = value;
  145. if(modifyExisting && namespace) {
  146. $existingModules = $(':data(module-' + namespace + ')');
  147. if($existingModules.length > 0) {
  148. module.verbose('Modifying existing settings', $existingModules);
  149. $existingModules[name]('setting', setting, value);
  150. }
  151. }
  152. }
  153. });
  154. },
  155. settings: function(newSettings, modules, modifyExisting) {
  156. modules = (typeof modules === 'string')
  157. ? [modules]
  158. : modules || settings.modules
  159. ;
  160. modifyExisting = (modifyExisting !== undefined)
  161. ? modifyExisting
  162. : true
  163. ;
  164. $.each(modules, function(index, name) {
  165. var
  166. $existingModules
  167. ;
  168. if(module.moduleExists(name)) {
  169. module.verbose('Changing default setting', newSettings, name);
  170. $.extend(true, $.fn[name].settings, newSettings);
  171. if(modifyExisting && namespace) {
  172. $existingModules = $(':data(module-' + namespace + ')');
  173. if($existingModules.length > 0) {
  174. module.verbose('Modifying existing settings', $existingModules);
  175. $existingModules[name]('setting', newSettings);
  176. }
  177. }
  178. }
  179. });
  180. }
  181. },
  182. enable: {
  183. console: function() {
  184. module.console(true);
  185. },
  186. debug: function(modules, modifyExisting) {
  187. modules = modules || settings.modules;
  188. module.debug('Enabling debug for modules', modules);
  189. module.change.setting('debug', true, modules, modifyExisting);
  190. },
  191. verbose: function(modules, modifyExisting) {
  192. modules = modules || settings.modules;
  193. module.debug('Enabling verbose debug for modules', modules);
  194. module.change.setting('verbose', true, modules, modifyExisting);
  195. }
  196. },
  197. disable: {
  198. console: function() {
  199. module.console(false);
  200. },
  201. debug: function(modules, modifyExisting) {
  202. modules = modules || settings.modules;
  203. module.debug('Disabling debug for modules', modules);
  204. module.change.setting('debug', false, modules, modifyExisting);
  205. },
  206. verbose: function(modules, modifyExisting) {
  207. modules = modules || settings.modules;
  208. module.debug('Disabling verbose debug for modules', modules);
  209. module.change.setting('verbose', false, modules, modifyExisting);
  210. }
  211. },
  212. console: function(enable) {
  213. if(enable) {
  214. if(instance.cache.console === undefined) {
  215. module.error(error.console);
  216. return;
  217. }
  218. module.debug('Restoring console function');
  219. window.console = instance.cache.console;
  220. }
  221. else {
  222. module.debug('Disabling console function');
  223. instance.cache.console = window.console;
  224. window.console = {
  225. clear : function(){},
  226. error : function(){},
  227. group : function(){},
  228. groupCollapsed : function(){},
  229. groupEnd : function(){},
  230. info : function(){},
  231. log : function(){},
  232. markTimeline : function(){},
  233. warn : function(){}
  234. };
  235. }
  236. },
  237. destroy: function() {
  238. module.verbose('Destroying previous site for', $module);
  239. $module
  240. .removeData(moduleNamespace)
  241. ;
  242. },
  243. cache: {},
  244. setting: function(name, value) {
  245. if( $.isPlainObject(name) ) {
  246. $.extend(true, settings, name);
  247. }
  248. else if(value !== undefined) {
  249. settings[name] = value;
  250. }
  251. else {
  252. return settings[name];
  253. }
  254. },
  255. internal: function(name, value) {
  256. if( $.isPlainObject(name) ) {
  257. $.extend(true, module, name);
  258. }
  259. else if(value !== undefined) {
  260. module[name] = value;
  261. }
  262. else {
  263. return module[name];
  264. }
  265. },
  266. debug: function() {
  267. if(settings.debug) {
  268. if(settings.performance) {
  269. module.performance.log(arguments);
  270. }
  271. else {
  272. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  273. module.debug.apply(console, arguments);
  274. }
  275. }
  276. },
  277. verbose: function() {
  278. if(settings.verbose && settings.debug) {
  279. if(settings.performance) {
  280. module.performance.log(arguments);
  281. }
  282. else {
  283. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  284. module.verbose.apply(console, arguments);
  285. }
  286. }
  287. },
  288. error: function() {
  289. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  290. module.error.apply(console, arguments);
  291. },
  292. performance: {
  293. log: function(message) {
  294. var
  295. currentTime,
  296. executionTime,
  297. previousTime
  298. ;
  299. if(settings.performance) {
  300. currentTime = new Date().getTime();
  301. previousTime = time || currentTime;
  302. executionTime = currentTime - previousTime;
  303. time = currentTime;
  304. performance.push({
  305. 'Element' : element,
  306. 'Name' : message[0],
  307. 'Arguments' : [].slice.call(message, 1) || '',
  308. 'Execution Time' : executionTime
  309. });
  310. }
  311. clearTimeout(module.performance.timer);
  312. module.performance.timer = setTimeout(module.performance.display, 500);
  313. },
  314. display: function() {
  315. var
  316. title = settings.name + ':',
  317. totalTime = 0
  318. ;
  319. time = false;
  320. clearTimeout(module.performance.timer);
  321. $.each(performance, function(index, data) {
  322. totalTime += data['Execution Time'];
  323. });
  324. title += ' ' + totalTime + 'ms';
  325. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  326. console.groupCollapsed(title);
  327. if(console.table) {
  328. console.table(performance);
  329. }
  330. else {
  331. $.each(performance, function(index, data) {
  332. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  333. });
  334. }
  335. console.groupEnd();
  336. }
  337. performance = [];
  338. }
  339. },
  340. invoke: function(query, passedArguments, context) {
  341. var
  342. object = instance,
  343. maxDepth,
  344. found,
  345. response
  346. ;
  347. passedArguments = passedArguments || queryArguments;
  348. context = element || context;
  349. if(typeof query == 'string' && object !== undefined) {
  350. query = query.split(/[\. ]/);
  351. maxDepth = query.length - 1;
  352. $.each(query, function(depth, value) {
  353. var camelCaseValue = (depth != maxDepth)
  354. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  355. : query
  356. ;
  357. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  358. object = object[camelCaseValue];
  359. }
  360. else if( object[camelCaseValue] !== undefined ) {
  361. found = object[camelCaseValue];
  362. return false;
  363. }
  364. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  365. object = object[value];
  366. }
  367. else if( object[value] !== undefined ) {
  368. found = object[value];
  369. return false;
  370. }
  371. else {
  372. module.error(error.method, query);
  373. return false;
  374. }
  375. });
  376. }
  377. if ( $.isFunction( found ) ) {
  378. response = found.apply(context, passedArguments);
  379. }
  380. else if(found !== undefined) {
  381. response = found;
  382. }
  383. if($.isArray(returnedValue)) {
  384. returnedValue.push(response);
  385. }
  386. else if(returnedValue !== undefined) {
  387. returnedValue = [returnedValue, response];
  388. }
  389. else if(response !== undefined) {
  390. returnedValue = response;
  391. }
  392. return found;
  393. }
  394. };
  395. if(methodInvoked) {
  396. if(instance === undefined) {
  397. module.initialize();
  398. }
  399. module.invoke(query);
  400. }
  401. else {
  402. if(instance !== undefined) {
  403. module.destroy();
  404. }
  405. module.initialize();
  406. }
  407. return (returnedValue !== undefined)
  408. ? returnedValue
  409. : this
  410. ;
  411. };
  412. $.site.settings = {
  413. name : 'Site',
  414. namespace : 'site',
  415. error : {
  416. console : 'Console cannot be restored, most likely it was overwritten outside of module',
  417. method : 'The method you called is not defined.'
  418. },
  419. debug : false,
  420. verbose : false,
  421. performance : true,
  422. modules: [
  423. 'accordion',
  424. 'api',
  425. 'checkbox',
  426. 'dimmer',
  427. 'dropdown',
  428. 'embed',
  429. 'form',
  430. 'modal',
  431. 'nag',
  432. 'popup',
  433. 'rating',
  434. 'shape',
  435. 'sidebar',
  436. 'state',
  437. 'sticky',
  438. 'tab',
  439. 'transition',
  440. 'visit',
  441. 'visibility'
  442. ],
  443. siteNamespace : 'site',
  444. namespaceStub : {
  445. cache : {},
  446. config : {},
  447. sections : {},
  448. section : {},
  449. utilities : {}
  450. }
  451. };
  452. // allows for selection of elements with data attributes
  453. $.extend($.expr[ ":" ], {
  454. data: ($.expr.createPseudo)
  455. ? $.expr.createPseudo(function(dataName) {
  456. return function(elem) {
  457. return !!$.data(elem, dataName);
  458. };
  459. })
  460. : function(elem, i, match) {
  461. // support: jQuery < 1.8
  462. return !!$.data(elem, match[ 3 ]);
  463. }
  464. });
  465. })( jQuery, window, document );
  466. /*!
  467. * # Semantic UI 2.2.6 - Form Validation
  468. * http://github.com/semantic-org/semantic-ui/
  469. *
  470. *
  471. * Released under the MIT license
  472. * http://opensource.org/licenses/MIT
  473. *
  474. */
  475. ;(function ($, window, document, undefined) {
  476. "use strict";
  477. window = (typeof window != 'undefined' && window.Math == Math)
  478. ? window
  479. : (typeof self != 'undefined' && self.Math == Math)
  480. ? self
  481. : Function('return this')()
  482. ;
  483. $.fn.form = function(parameters) {
  484. var
  485. $allModules = $(this),
  486. moduleSelector = $allModules.selector || '',
  487. time = new Date().getTime(),
  488. performance = [],
  489. query = arguments[0],
  490. legacyParameters = arguments[1],
  491. methodInvoked = (typeof query == 'string'),
  492. queryArguments = [].slice.call(arguments, 1),
  493. returnedValue
  494. ;
  495. $allModules
  496. .each(function() {
  497. var
  498. $module = $(this),
  499. element = this,
  500. formErrors = [],
  501. keyHeldDown = false,
  502. // set at run-time
  503. $field,
  504. $group,
  505. $message,
  506. $prompt,
  507. $submit,
  508. $clear,
  509. $reset,
  510. settings,
  511. validation,
  512. metadata,
  513. selector,
  514. className,
  515. error,
  516. namespace,
  517. moduleNamespace,
  518. eventNamespace,
  519. instance,
  520. module
  521. ;
  522. module = {
  523. initialize: function() {
  524. // settings grabbed at run time
  525. module.get.settings();
  526. if(methodInvoked) {
  527. if(instance === undefined) {
  528. module.instantiate();
  529. }
  530. module.invoke(query);
  531. }
  532. else {
  533. if(instance !== undefined) {
  534. instance.invoke('destroy');
  535. }
  536. module.verbose('Initializing form validation', $module, settings);
  537. module.bindEvents();
  538. module.set.defaults();
  539. module.instantiate();
  540. }
  541. },
  542. instantiate: function() {
  543. module.verbose('Storing instance of module', module);
  544. instance = module;
  545. $module
  546. .data(moduleNamespace, module)
  547. ;
  548. },
  549. destroy: function() {
  550. module.verbose('Destroying previous module', instance);
  551. module.removeEvents();
  552. $module
  553. .removeData(moduleNamespace)
  554. ;
  555. },
  556. refresh: function() {
  557. module.verbose('Refreshing selector cache');
  558. $field = $module.find(selector.field);
  559. $group = $module.find(selector.group);
  560. $message = $module.find(selector.message);
  561. $prompt = $module.find(selector.prompt);
  562. $submit = $module.find(selector.submit);
  563. $clear = $module.find(selector.clear);
  564. $reset = $module.find(selector.reset);
  565. },
  566. submit: function() {
  567. module.verbose('Submitting form', $module);
  568. $module
  569. .submit()
  570. ;
  571. },
  572. attachEvents: function(selector, action) {
  573. action = action || 'submit';
  574. $(selector)
  575. .on('click' + eventNamespace, function(event) {
  576. module[action]();
  577. event.preventDefault();
  578. })
  579. ;
  580. },
  581. bindEvents: function() {
  582. module.verbose('Attaching form events');
  583. $module
  584. .on('submit' + eventNamespace, module.validate.form)
  585. .on('blur' + eventNamespace, selector.field, module.event.field.blur)
  586. .on('click' + eventNamespace, selector.submit, module.submit)
  587. .on('click' + eventNamespace, selector.reset, module.reset)
  588. .on('click' + eventNamespace, selector.clear, module.clear)
  589. ;
  590. if(settings.keyboardShortcuts) {
  591. $module
  592. .on('keydown' + eventNamespace, selector.field, module.event.field.keydown)
  593. ;
  594. }
  595. $field
  596. .each(function() {
  597. var
  598. $input = $(this),
  599. type = $input.prop('type'),
  600. inputEvent = module.get.changeEvent(type, $input)
  601. ;
  602. $(this)
  603. .on(inputEvent + eventNamespace, module.event.field.change)
  604. ;
  605. })
  606. ;
  607. },
  608. clear: function() {
  609. $field
  610. .each(function () {
  611. var
  612. $field = $(this),
  613. $element = $field.parent(),
  614. $fieldGroup = $field.closest($group),
  615. $prompt = $fieldGroup.find(selector.prompt),
  616. defaultValue = $field.data(metadata.defaultValue) || '',
  617. isCheckbox = $element.is(selector.uiCheckbox),
  618. isDropdown = $element.is(selector.uiDropdown),
  619. isErrored = $fieldGroup.hasClass(className.error)
  620. ;
  621. if(isErrored) {
  622. module.verbose('Resetting error on field', $fieldGroup);
  623. $fieldGroup.removeClass(className.error);
  624. $prompt.remove();
  625. }
  626. if(isDropdown) {
  627. module.verbose('Resetting dropdown value', $element, defaultValue);
  628. $element.dropdown('clear');
  629. }
  630. else if(isCheckbox) {
  631. $field.prop('checked', false);
  632. }
  633. else {
  634. module.verbose('Resetting field value', $field, defaultValue);
  635. $field.val('');
  636. }
  637. })
  638. ;
  639. },
  640. reset: function() {
  641. $field
  642. .each(function () {
  643. var
  644. $field = $(this),
  645. $element = $field.parent(),
  646. $fieldGroup = $field.closest($group),
  647. $prompt = $fieldGroup.find(selector.prompt),
  648. defaultValue = $field.data(metadata.defaultValue),
  649. isCheckbox = $element.is(selector.uiCheckbox),
  650. isDropdown = $element.is(selector.uiDropdown),
  651. isErrored = $fieldGroup.hasClass(className.error)
  652. ;
  653. if(defaultValue === undefined) {
  654. return;
  655. }
  656. if(isErrored) {
  657. module.verbose('Resetting error on field', $fieldGroup);
  658. $fieldGroup.removeClass(className.error);
  659. $prompt.remove();
  660. }
  661. if(isDropdown) {
  662. module.verbose('Resetting dropdown value', $element, defaultValue);
  663. $element.dropdown('restore defaults');
  664. }
  665. else if(isCheckbox) {
  666. module.verbose('Resetting checkbox value', $element, defaultValue);
  667. $field.prop('checked', defaultValue);
  668. }
  669. else {
  670. module.verbose('Resetting field value', $field, defaultValue);
  671. $field.val(defaultValue);
  672. }
  673. })
  674. ;
  675. },
  676. is: {
  677. bracketedRule: function(rule) {
  678. return (rule.type && rule.type.match(settings.regExp.bracket));
  679. },
  680. empty: function($field) {
  681. if(!$field || $field.length === 0) {
  682. return true;
  683. }
  684. else if($field.is('input[type="checkbox"]')) {
  685. return !$field.is(':checked');
  686. }
  687. else {
  688. return module.is.blank($field);
  689. }
  690. },
  691. blank: function($field) {
  692. return $.trim($field.val()) === '';
  693. },
  694. valid: function() {
  695. var
  696. allValid = true
  697. ;
  698. module.verbose('Checking if form is valid');
  699. $.each(validation, function(fieldName, field) {
  700. if( !( module.validate.field(field, fieldName) ) ) {
  701. allValid = false;
  702. }
  703. });
  704. return allValid;
  705. }
  706. },
  707. removeEvents: function() {
  708. $module
  709. .off(eventNamespace)
  710. ;
  711. $field
  712. .off(eventNamespace)
  713. ;
  714. $submit
  715. .off(eventNamespace)
  716. ;
  717. $field
  718. .off(eventNamespace)
  719. ;
  720. },
  721. event: {
  722. field: {
  723. keydown: function(event) {
  724. var
  725. $field = $(this),
  726. key = event.which,
  727. isInput = $field.is(selector.input),
  728. isCheckbox = $field.is(selector.checkbox),
  729. isInDropdown = ($field.closest(selector.uiDropdown).length > 0),
  730. keyCode = {
  731. enter : 13,
  732. escape : 27
  733. }
  734. ;
  735. if( key == keyCode.escape) {
  736. module.verbose('Escape key pressed blurring field');
  737. $field
  738. .blur()
  739. ;
  740. }
  741. if(!event.ctrlKey && key == keyCode.enter && isInput && !isInDropdown && !isCheckbox) {
  742. if(!keyHeldDown) {
  743. $field
  744. .one('keyup' + eventNamespace, module.event.field.keyup)
  745. ;
  746. module.submit();
  747. module.debug('Enter pressed on input submitting form');
  748. }
  749. keyHeldDown = true;
  750. }
  751. },
  752. keyup: function() {
  753. keyHeldDown = false;
  754. },
  755. blur: function(event) {
  756. var
  757. $field = $(this),
  758. $fieldGroup = $field.closest($group),
  759. validationRules = module.get.validation($field)
  760. ;
  761. if( $fieldGroup.hasClass(className.error) ) {
  762. module.debug('Revalidating field', $field, validationRules);
  763. if(validationRules) {
  764. module.validate.field( validationRules );
  765. }
  766. }
  767. else if(settings.on == 'blur' || settings.on == 'change') {
  768. if(validationRules) {
  769. module.validate.field( validationRules );
  770. }
  771. }
  772. },
  773. change: function(event) {
  774. var
  775. $field = $(this),
  776. $fieldGroup = $field.closest($group),
  777. validationRules = module.get.validation($field)
  778. ;
  779. if(settings.on == 'change' || ( $fieldGroup.hasClass(className.error) && settings.revalidate) ) {
  780. clearTimeout(module.timer);
  781. module.timer = setTimeout(function() {
  782. module.debug('Revalidating field', $field, module.get.validation($field));
  783. module.validate.field( validationRules );
  784. }, settings.delay);
  785. }
  786. }
  787. }
  788. },
  789. get: {
  790. ancillaryValue: function(rule) {
  791. if(!rule.type || (!rule.value && !module.is.bracketedRule(rule))) {
  792. return false;
  793. }
  794. return (rule.value !== undefined)
  795. ? rule.value
  796. : rule.type.match(settings.regExp.bracket)[1] + ''
  797. ;
  798. },
  799. ruleName: function(rule) {
  800. if( module.is.bracketedRule(rule) ) {
  801. return rule.type.replace(rule.type.match(settings.regExp.bracket)[0], '');
  802. }
  803. return rule.type;
  804. },
  805. changeEvent: function(type, $input) {
  806. if(type == 'checkbox' || type == 'radio' || type == 'hidden' || $input.is('select')) {
  807. return 'change';
  808. }
  809. else {
  810. return module.get.inputEvent();
  811. }
  812. },
  813. inputEvent: function() {
  814. return (document.createElement('input').oninput !== undefined)
  815. ? 'input'
  816. : (document.createElement('input').onpropertychange !== undefined)
  817. ? 'propertychange'
  818. : 'keyup'
  819. ;
  820. },
  821. prompt: function(rule, field) {
  822. var
  823. ruleName = module.get.ruleName(rule),
  824. ancillary = module.get.ancillaryValue(rule),
  825. prompt = rule.prompt || settings.prompt[ruleName] || settings.text.unspecifiedRule,
  826. requiresValue = (prompt.search('{value}') !== -1),
  827. requiresName = (prompt.search('{name}') !== -1),
  828. $label,
  829. $field,
  830. name
  831. ;
  832. if(requiresName || requiresValue) {
  833. $field = module.get.field(field.identifier);
  834. }
  835. if(requiresValue) {
  836. prompt = prompt.replace('{value}', $field.val());
  837. }
  838. if(requiresName) {
  839. $label = $field.closest(selector.group).find('label').eq(0);
  840. name = ($label.length == 1)
  841. ? $label.text()
  842. : $field.prop('placeholder') || settings.text.unspecifiedField
  843. ;
  844. prompt = prompt.replace('{name}', name);
  845. }
  846. prompt = prompt.replace('{identifier}', field.identifier);
  847. prompt = prompt.replace('{ruleValue}', ancillary);
  848. if(!rule.prompt) {
  849. module.verbose('Using default validation prompt for type', prompt, ruleName);
  850. }
  851. return prompt;
  852. },
  853. settings: function() {
  854. if($.isPlainObject(parameters)) {
  855. var
  856. keys = Object.keys(parameters),
  857. isLegacySettings = (keys.length > 0)
  858. ? (parameters[keys[0]].identifier !== undefined && parameters[keys[0]].rules !== undefined)
  859. : false,
  860. ruleKeys
  861. ;
  862. if(isLegacySettings) {
  863. // 1.x (ducktyped)
  864. settings = $.extend(true, {}, $.fn.form.settings, legacyParameters);
  865. validation = $.extend({}, $.fn.form.settings.defaults, parameters);
  866. module.error(settings.error.oldSyntax, element);
  867. module.verbose('Extending settings from legacy parameters', validation, settings);
  868. }
  869. else {
  870. // 2.x
  871. if(parameters.fields) {
  872. ruleKeys = Object.keys(parameters.fields);
  873. if( typeof parameters.fields[ruleKeys[0]] == 'string' || $.isArray(parameters.fields[ruleKeys[0]]) ) {
  874. $.each(parameters.fields, function(name, rules) {
  875. if(typeof rules == 'string') {
  876. rules = [rules];
  877. }
  878. parameters.fields[name] = {
  879. rules: []
  880. };
  881. $.each(rules, function(index, rule) {
  882. parameters.fields[name].rules.push({ type: rule });
  883. });
  884. });
  885. }
  886. }
  887. settings = $.extend(true, {}, $.fn.form.settings, parameters);
  888. validation = $.extend({}, $.fn.form.settings.defaults, settings.fields);
  889. module.verbose('Extending settings', validation, settings);
  890. }
  891. }
  892. else {
  893. settings = $.fn.form.settings;
  894. validation = $.fn.form.settings.defaults;
  895. module.verbose('Using default form validation', validation, settings);
  896. }
  897. // shorthand
  898. namespace = settings.namespace;
  899. metadata = settings.metadata;
  900. selector = settings.selector;
  901. className = settings.className;
  902. error = settings.error;
  903. moduleNamespace = 'module-' + namespace;
  904. eventNamespace = '.' + namespace;
  905. // grab instance
  906. instance = $module.data(moduleNamespace);
  907. // refresh selector cache
  908. module.refresh();
  909. },
  910. field: function(identifier) {
  911. module.verbose('Finding field with identifier', identifier);
  912. if( $field.filter('#' + identifier).length > 0 ) {
  913. return $field.filter('#' + identifier);
  914. }
  915. else if( $field.filter('[name="' + identifier +'"]').length > 0 ) {
  916. return $field.filter('[name="' + identifier +'"]');
  917. }
  918. else if( $field.filter('[name="' + identifier +'[]"]').length > 0 ) {
  919. return $field.filter('[name="' + identifier +'[]"]');
  920. }
  921. else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) {
  922. return $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]');
  923. }
  924. return $('<input/>');
  925. },
  926. fields: function(fields) {
  927. var
  928. $fields = $()
  929. ;
  930. $.each(fields, function(index, name) {
  931. $fields = $fields.add( module.get.field(name) );
  932. });
  933. return $fields;
  934. },
  935. validation: function($field) {
  936. var
  937. fieldValidation,
  938. identifier
  939. ;
  940. if(!validation) {
  941. return false;
  942. }
  943. $.each(validation, function(fieldName, field) {
  944. identifier = field.identifier || fieldName;
  945. if( module.get.field(identifier)[0] == $field[0] ) {
  946. field.identifier = identifier;
  947. fieldValidation = field;
  948. }
  949. });
  950. return fieldValidation || false;
  951. },
  952. value: function (field) {
  953. var
  954. fields = [],
  955. results
  956. ;
  957. fields.push(field);
  958. results = module.get.values.call(element, fields);
  959. return results[field];
  960. },
  961. values: function (fields) {
  962. var
  963. $fields = $.isArray(fields)
  964. ? module.get.fields(fields)
  965. : $field,
  966. values = {}
  967. ;
  968. $fields.each(function(index, field) {
  969. var
  970. $field = $(field),
  971. type = $field.prop('type'),
  972. name = $field.prop('name'),
  973. value = $field.val(),
  974. isCheckbox = $field.is(selector.checkbox),
  975. isRadio = $field.is(selector.radio),
  976. isMultiple = (name.indexOf('[]') !== -1),
  977. isChecked = (isCheckbox)
  978. ? $field.is(':checked')
  979. : false
  980. ;
  981. if(name) {
  982. if(isMultiple) {
  983. name = name.replace('[]', '');
  984. if(!values[name]) {
  985. values[name] = [];
  986. }
  987. if(isCheckbox) {
  988. if(isChecked) {
  989. values[name].push(value || true);
  990. }
  991. else {
  992. values[name].push(false);
  993. }
  994. }
  995. else {
  996. values[name].push(value);
  997. }
  998. }
  999. else {
  1000. if(isRadio) {
  1001. if(isChecked) {
  1002. values[name] = value;
  1003. }
  1004. }
  1005. else if(isCheckbox) {
  1006. if(isChecked) {
  1007. values[name] = value || true;
  1008. }
  1009. else {
  1010. values[name] = false;
  1011. }
  1012. }
  1013. else {
  1014. values[name] = value;
  1015. }
  1016. }
  1017. }
  1018. });
  1019. return values;
  1020. }
  1021. },
  1022. has: {
  1023. field: function(identifier) {
  1024. module.verbose('Checking for existence of a field with identifier', identifier);
  1025. if(typeof identifier !== 'string') {
  1026. module.error(error.identifier, identifier);
  1027. }
  1028. if( $field.filter('#' + identifier).length > 0 ) {
  1029. return true;
  1030. }
  1031. else if( $field.filter('[name="' + identifier +'"]').length > 0 ) {
  1032. return true;
  1033. }
  1034. else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) {
  1035. return true;
  1036. }
  1037. return false;
  1038. }
  1039. },
  1040. add: {
  1041. prompt: function(identifier, errors) {
  1042. var
  1043. $field = module.get.field(identifier),
  1044. $fieldGroup = $field.closest($group),
  1045. $prompt = $fieldGroup.children(selector.prompt),
  1046. promptExists = ($prompt.length !== 0)
  1047. ;
  1048. errors = (typeof errors == 'string')
  1049. ? [errors]
  1050. : errors
  1051. ;
  1052. module.verbose('Adding field error state', identifier);
  1053. $fieldGroup
  1054. .addClass(className.error)
  1055. ;
  1056. if(settings.inline) {
  1057. if(!promptExists) {
  1058. $prompt = settings.templates.prompt(errors);
  1059. $prompt
  1060. .appendTo($fieldGroup)
  1061. ;
  1062. }
  1063. $prompt
  1064. .html(errors[0])
  1065. ;
  1066. if(!promptExists) {
  1067. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  1068. module.verbose('Displaying error with css transition', settings.transition);
  1069. $prompt.transition(settings.transition + ' in', settings.duration);
  1070. }
  1071. else {
  1072. module.verbose('Displaying error with fallback javascript animation');
  1073. $prompt
  1074. .fadeIn(settings.duration)
  1075. ;
  1076. }
  1077. }
  1078. else {
  1079. module.verbose('Inline errors are disabled, no inline error added', identifier);
  1080. }
  1081. }
  1082. },
  1083. errors: function(errors) {
  1084. module.debug('Adding form error messages', errors);
  1085. module.set.error();
  1086. $message
  1087. .html( settings.templates.error(errors) )
  1088. ;
  1089. }
  1090. },
  1091. remove: {
  1092. prompt: function(identifier) {
  1093. var
  1094. $field = module.get.field(identifier),
  1095. $fieldGroup = $field.closest($group),
  1096. $prompt = $fieldGroup.children(selector.prompt)
  1097. ;
  1098. $fieldGroup
  1099. .removeClass(className.error)
  1100. ;
  1101. if(settings.inline && $prompt.is(':visible')) {
  1102. module.verbose('Removing prompt for field', identifier);
  1103. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  1104. $prompt.transition(settings.transition + ' out', settings.duration, function() {
  1105. $prompt.remove();
  1106. });
  1107. }
  1108. else {
  1109. $prompt
  1110. .fadeOut(settings.duration, function(){
  1111. $prompt.remove();
  1112. })
  1113. ;
  1114. }
  1115. }
  1116. }
  1117. },
  1118. set: {
  1119. success: function() {
  1120. $module
  1121. .removeClass(className.error)
  1122. .addClass(className.success)
  1123. ;
  1124. },
  1125. defaults: function () {
  1126. $field
  1127. .each(function () {
  1128. var
  1129. $field = $(this),
  1130. isCheckbox = ($field.filter(selector.checkbox).length > 0),
  1131. value = (isCheckbox)
  1132. ? $field.is(':checked')
  1133. : $field.val()
  1134. ;
  1135. $field.data(metadata.defaultValue, value);
  1136. })
  1137. ;
  1138. },
  1139. error: function() {
  1140. $module
  1141. .removeClass(className.success)
  1142. .addClass(className.error)
  1143. ;
  1144. },
  1145. value: function (field, value) {
  1146. var
  1147. fields = {}
  1148. ;
  1149. fields[field] = value;
  1150. return module.set.values.call(element, fields);
  1151. },
  1152. values: function (fields) {
  1153. if($.isEmptyObject(fields)) {
  1154. return;
  1155. }
  1156. $.each(fields, function(key, value) {
  1157. var
  1158. $field = module.get.field(key),
  1159. $element = $field.parent(),
  1160. isMultiple = $.isArray(value),
  1161. isCheckbox = $element.is(selector.uiCheckbox),
  1162. isDropdown = $element.is(selector.uiDropdown),
  1163. isRadio = ($field.is(selector.radio) && isCheckbox),
  1164. fieldExists = ($field.length > 0),
  1165. $multipleField
  1166. ;
  1167. if(fieldExists) {
  1168. if(isMultiple && isCheckbox) {
  1169. module.verbose('Selecting multiple', value, $field);
  1170. $element.checkbox('uncheck');
  1171. $.each(value, function(index, value) {
  1172. $multipleField = $field.filter('[value="' + value + '"]');
  1173. $element = $multipleField.parent();
  1174. if($multipleField.length > 0) {
  1175. $element.checkbox('check');
  1176. }
  1177. });
  1178. }
  1179. else if(isRadio) {
  1180. module.verbose('Selecting radio value', value, $field);
  1181. $field.filter('[value="' + value + '"]')
  1182. .parent(selector.uiCheckbox)
  1183. .checkbox('check')
  1184. ;
  1185. }
  1186. else if(isCheckbox) {
  1187. module.verbose('Setting checkbox value', value, $element);
  1188. if(value === true) {
  1189. $element.checkbox('check');
  1190. }
  1191. else {
  1192. $element.checkbox('uncheck');
  1193. }
  1194. }
  1195. else if(isDropdown) {
  1196. module.verbose('Setting dropdown value', value, $element);
  1197. $element.dropdown('set selected', value);
  1198. }
  1199. else {
  1200. module.verbose('Setting field value', value, $field);
  1201. $field.val(value);
  1202. }
  1203. }
  1204. });
  1205. }
  1206. },
  1207. validate: {
  1208. form: function(event, ignoreCallbacks) {
  1209. var
  1210. values = module.get.values(),
  1211. apiRequest
  1212. ;
  1213. // input keydown event will fire submit repeatedly by browser default
  1214. if(keyHeldDown) {
  1215. return false;
  1216. }
  1217. // reset errors
  1218. formErrors = [];
  1219. if( module.is.valid() ) {
  1220. module.debug('Form has no validation errors, submitting');
  1221. module.set.success();
  1222. if(ignoreCallbacks !== true) {
  1223. return settings.onSuccess.call(element, event, values);
  1224. }
  1225. }
  1226. else {
  1227. module.debug('Form has errors');
  1228. module.set.error();
  1229. if(!settings.inline) {
  1230. module.add.errors(formErrors);
  1231. }
  1232. // prevent ajax submit
  1233. if($module.data('moduleApi') !== undefined) {
  1234. event.stopImmediatePropagation();
  1235. }
  1236. if(ignoreCallbacks !== true) {
  1237. return settings.onFailure.call(element, formErrors, values);
  1238. }
  1239. }
  1240. },
  1241. // takes a validation object and returns whether field passes validation
  1242. field: function(field, fieldName) {
  1243. var
  1244. identifier = field.identifier || fieldName,
  1245. $field = module.get.field(identifier),
  1246. $dependsField = (field.depends)
  1247. ? module.get.field(field.depends)
  1248. : false,
  1249. fieldValid = true,
  1250. fieldErrors = []
  1251. ;
  1252. if(!field.identifier) {
  1253. module.debug('Using field name as identifier', identifier);
  1254. field.identifier = identifier;
  1255. }
  1256. if($field.prop('disabled')) {
  1257. module.debug('Field is disabled. Skipping', identifier);
  1258. fieldValid = true;
  1259. }
  1260. else if(field.optional && module.is.blank($field)){
  1261. module.debug('Field is optional and blank. Skipping', identifier);
  1262. fieldValid = true;
  1263. }
  1264. else if(field.depends && module.is.empty($dependsField)) {
  1265. module.debug('Field depends on another value that is not present or empty. Skipping', $dependsField);
  1266. fieldValid = true;
  1267. }
  1268. else if(field.rules !== undefined) {
  1269. $.each(field.rules, function(index, rule) {
  1270. if( module.has.field(identifier) && !( module.validate.rule(field, rule) ) ) {
  1271. module.debug('Field is invalid', identifier, rule.type);
  1272. fieldErrors.push(module.get.prompt(rule, field));
  1273. fieldValid = false;
  1274. }
  1275. });
  1276. }
  1277. if(fieldValid) {
  1278. module.remove.prompt(identifier, fieldErrors);
  1279. settings.onValid.call($field);
  1280. }
  1281. else {
  1282. formErrors = formErrors.concat(fieldErrors);
  1283. module.add.prompt(identifier, fieldErrors);
  1284. settings.onInvalid.call($field, fieldErrors);
  1285. return false;
  1286. }
  1287. return true;
  1288. },
  1289. // takes validation rule and returns whether field passes rule
  1290. rule: function(field, rule) {
  1291. var
  1292. $field = module.get.field(field.identifier),
  1293. type = rule.type,
  1294. value = $field.val(),
  1295. isValid = true,
  1296. ancillary = module.get.ancillaryValue(rule),
  1297. ruleName = module.get.ruleName(rule),
  1298. ruleFunction = settings.rules[ruleName]
  1299. ;
  1300. if( !$.isFunction(ruleFunction) ) {
  1301. module.error(error.noRule, ruleName);
  1302. return;
  1303. }
  1304. // cast to string avoiding encoding special values
  1305. value = (value === undefined || value === '' || value === null)
  1306. ? ''
  1307. : $.trim(value + '')
  1308. ;
  1309. return ruleFunction.call($field, value, ancillary);
  1310. }
  1311. },
  1312. setting: function(name, value) {
  1313. if( $.isPlainObject(name) ) {
  1314. $.extend(true, settings, name);
  1315. }
  1316. else if(value !== undefined) {
  1317. settings[name] = value;
  1318. }
  1319. else {
  1320. return settings[name];
  1321. }
  1322. },
  1323. internal: function(name, value) {
  1324. if( $.isPlainObject(name) ) {
  1325. $.extend(true, module, name);
  1326. }
  1327. else if(value !== undefined) {
  1328. module[name] = value;
  1329. }
  1330. else {
  1331. return module[name];
  1332. }
  1333. },
  1334. debug: function() {
  1335. if(!settings.silent && settings.debug) {
  1336. if(settings.performance) {
  1337. module.performance.log(arguments);
  1338. }
  1339. else {
  1340. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  1341. module.debug.apply(console, arguments);
  1342. }
  1343. }
  1344. },
  1345. verbose: function() {
  1346. if(!settings.silent && settings.verbose && settings.debug) {
  1347. if(settings.performance) {
  1348. module.performance.log(arguments);
  1349. }
  1350. else {
  1351. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  1352. module.verbose.apply(console, arguments);
  1353. }
  1354. }
  1355. },
  1356. error: function() {
  1357. if(!settings.silent) {
  1358. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  1359. module.error.apply(console, arguments);
  1360. }
  1361. },
  1362. performance: {
  1363. log: function(message) {
  1364. var
  1365. currentTime,
  1366. executionTime,
  1367. previousTime
  1368. ;
  1369. if(settings.performance) {
  1370. currentTime = new Date().getTime();
  1371. previousTime = time || currentTime;
  1372. executionTime = currentTime - previousTime;
  1373. time = currentTime;
  1374. performance.push({
  1375. 'Name' : message[0],
  1376. 'Arguments' : [].slice.call(message, 1) || '',
  1377. 'Element' : element,
  1378. 'Execution Time' : executionTime
  1379. });
  1380. }
  1381. clearTimeout(module.performance.timer);
  1382. module.performance.timer = setTimeout(module.performance.display, 500);
  1383. },
  1384. display: function() {
  1385. var
  1386. title = settings.name + ':',
  1387. totalTime = 0
  1388. ;
  1389. time = false;
  1390. clearTimeout(module.performance.timer);
  1391. $.each(performance, function(index, data) {
  1392. totalTime += data['Execution Time'];
  1393. });
  1394. title += ' ' + totalTime + 'ms';
  1395. if(moduleSelector) {
  1396. title += ' \'' + moduleSelector + '\'';
  1397. }
  1398. if($allModules.length > 1) {
  1399. title += ' ' + '(' + $allModules.length + ')';
  1400. }
  1401. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  1402. console.groupCollapsed(title);
  1403. if(console.table) {
  1404. console.table(performance);
  1405. }
  1406. else {
  1407. $.each(performance, function(index, data) {
  1408. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  1409. });
  1410. }
  1411. console.groupEnd();
  1412. }
  1413. performance = [];
  1414. }
  1415. },
  1416. invoke: function(query, passedArguments, context) {
  1417. var
  1418. object = instance,
  1419. maxDepth,
  1420. found,
  1421. response
  1422. ;
  1423. passedArguments = passedArguments || queryArguments;
  1424. context = element || context;
  1425. if(typeof query == 'string' && object !== undefined) {
  1426. query = query.split(/[\. ]/);
  1427. maxDepth = query.length - 1;
  1428. $.each(query, function(depth, value) {
  1429. var camelCaseValue = (depth != maxDepth)
  1430. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  1431. : query
  1432. ;
  1433. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  1434. object = object[camelCaseValue];
  1435. }
  1436. else if( object[camelCaseValue] !== undefined ) {
  1437. found = object[camelCaseValue];
  1438. return false;
  1439. }
  1440. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  1441. object = object[value];
  1442. }
  1443. else if( object[value] !== undefined ) {
  1444. found = object[value];
  1445. return false;
  1446. }
  1447. else {
  1448. return false;
  1449. }
  1450. });
  1451. }
  1452. if( $.isFunction( found ) ) {
  1453. response = found.apply(context, passedArguments);
  1454. }
  1455. else if(found !== undefined) {
  1456. response = found;
  1457. }
  1458. if($.isArray(returnedValue)) {
  1459. returnedValue.push(response);
  1460. }
  1461. else if(returnedValue !== undefined) {
  1462. returnedValue = [returnedValue, response];
  1463. }
  1464. else if(response !== undefined) {
  1465. returnedValue = response;
  1466. }
  1467. return found;
  1468. }
  1469. };
  1470. module.initialize();
  1471. })
  1472. ;
  1473. return (returnedValue !== undefined)
  1474. ? returnedValue
  1475. : this
  1476. ;
  1477. };
  1478. $.fn.form.settings = {
  1479. name : 'Form',
  1480. namespace : 'form',
  1481. debug : false,
  1482. verbose : false,
  1483. performance : true,
  1484. fields : false,
  1485. keyboardShortcuts : true,
  1486. on : 'submit',
  1487. inline : false,
  1488. delay : 200,
  1489. revalidate : true,
  1490. transition : 'scale',
  1491. duration : 200,
  1492. onValid : function() {},
  1493. onInvalid : function() {},
  1494. onSuccess : function() { return true; },
  1495. onFailure : function() { return false; },
  1496. metadata : {
  1497. defaultValue : 'default',
  1498. validate : 'validate'
  1499. },
  1500. regExp: {
  1501. bracket : /\[(.*)\]/i,
  1502. decimal : /^\d*(\.)\d+/,
  1503. email : /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,
  1504. escape : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,
  1505. flags : /^\/(.*)\/(.*)?/,
  1506. integer : /^\-?\d+$/,
  1507. number : /^\-?\d*(\.\d+)?$/,
  1508. url : /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/i
  1509. },
  1510. text: {
  1511. unspecifiedRule : 'Please enter a valid value',
  1512. unspecifiedField : 'This field'
  1513. },
  1514. prompt: {
  1515. empty : '{name} must have a value',
  1516. checked : '{name} must be checked',
  1517. email : '{name} must be a valid e-mail',
  1518. url : '{name} must be a valid url',
  1519. regExp : '{name} is not formatted correctly',
  1520. integer : '{name} must be an integer',
  1521. decimal : '{name} must be a decimal number',
  1522. number : '{name} must be set to a number',
  1523. is : '{name} must be "{ruleValue}"',
  1524. isExactly : '{name} must be exactly "{ruleValue}"',
  1525. not : '{name} cannot be set to "{ruleValue}"',
  1526. notExactly : '{name} cannot be set to exactly "{ruleValue}"',
  1527. contain : '{name} cannot contain "{ruleValue}"',
  1528. containExactly : '{name} cannot contain exactly "{ruleValue}"',
  1529. doesntContain : '{name} must contain "{ruleValue}"',
  1530. doesntContainExactly : '{name} must contain exactly "{ruleValue}"',
  1531. minLength : '{name} must be at least {ruleValue} characters',
  1532. length : '{name} must be at least {ruleValue} characters',
  1533. exactLength : '{name} must be exactly {ruleValue} characters',
  1534. maxLength : '{name} cannot be longer than {ruleValue} characters',
  1535. match : '{name} must match {ruleValue} field',
  1536. different : '{name} must have a different value than {ruleValue} field',
  1537. creditCard : '{name} must be a valid credit card number',
  1538. minCount : '{name} must have at least {ruleValue} choices',
  1539. exactCount : '{name} must have exactly {ruleValue} choices',
  1540. maxCount : '{name} must have {ruleValue} or less choices'
  1541. },
  1542. selector : {
  1543. checkbox : 'input[type="checkbox"], input[type="radio"]',
  1544. clear : '.clear',
  1545. field : 'input, textarea, select',
  1546. group : '.field',
  1547. input : 'input',
  1548. message : '.error.message',
  1549. prompt : '.prompt.label',
  1550. radio : 'input[type="radio"]',
  1551. reset : '.reset:not([type="reset"])',
  1552. submit : '.submit:not([type="submit"])',
  1553. uiCheckbox : '.ui.checkbox',
  1554. uiDropdown : '.ui.dropdown'
  1555. },
  1556. className : {
  1557. error : 'error',
  1558. label : 'ui prompt label',
  1559. pressed : 'down',
  1560. success : 'success'
  1561. },
  1562. error: {
  1563. identifier : 'You must specify a string identifier for each field',
  1564. method : 'The method you called is not defined.',
  1565. noRule : 'There is no rule matching the one you specified',
  1566. oldSyntax : 'Starting in 2.0 forms now only take a single settings object. Validation settings converted to new syntax automatically.'
  1567. },
  1568. templates: {
  1569. // template that produces error message
  1570. error: function(errors) {
  1571. var
  1572. html = '<ul class="list">'
  1573. ;
  1574. $.each(errors, function(index, value) {
  1575. html += '<li>' + value + '</li>';
  1576. });
  1577. html += '</ul>';
  1578. return $(html);
  1579. },
  1580. // template that produces label
  1581. prompt: function(errors) {
  1582. return $('<div/>')
  1583. .addClass('ui basic red pointing prompt label')
  1584. .html(errors[0])
  1585. ;
  1586. }
  1587. },
  1588. rules: {
  1589. // is not empty or blank string
  1590. empty: function(value) {
  1591. return !(value === undefined || '' === value || $.isArray(value) && value.length === 0);
  1592. },
  1593. // checkbox checked
  1594. checked: function() {
  1595. return ($(this).filter(':checked').length > 0);
  1596. },
  1597. // is most likely an email
  1598. email: function(value){
  1599. return $.fn.form.settings.regExp.email.test(value);
  1600. },
  1601. // value is most likely url
  1602. url: function(value) {
  1603. return $.fn.form.settings.regExp.url.test(value);
  1604. },
  1605. // matches specified regExp
  1606. regExp: function(value, regExp) {
  1607. if(regExp instanceof RegExp) {
  1608. return value.match(regExp);
  1609. }
  1610. var
  1611. regExpParts = regExp.match($.fn.form.settings.regExp.flags),
  1612. flags
  1613. ;
  1614. // regular expression specified as /baz/gi (flags)
  1615. if(regExpParts) {
  1616. regExp = (regExpParts.length >= 2)
  1617. ? regExpParts[1]
  1618. : regExp
  1619. ;
  1620. flags = (regExpParts.length >= 3)
  1621. ? regExpParts[2]
  1622. : ''
  1623. ;
  1624. }
  1625. return value.match( new RegExp(regExp, flags) );
  1626. },
  1627. // is valid integer or matches range
  1628. integer: function(value, range) {
  1629. var
  1630. intRegExp = $.fn.form.settings.regExp.integer,
  1631. min,
  1632. max,
  1633. parts
  1634. ;
  1635. if( !range || ['', '..'].indexOf(range) !== -1) {
  1636. // do nothing
  1637. }
  1638. else if(range.indexOf('..') == -1) {
  1639. if(intRegExp.test(range)) {
  1640. min = max = range - 0;
  1641. }
  1642. }
  1643. else {
  1644. parts = range.split('..', 2);
  1645. if(intRegExp.test(parts[0])) {
  1646. min = parts[0] - 0;
  1647. }
  1648. if(intRegExp.test(parts[1])) {
  1649. max = parts[1] - 0;
  1650. }
  1651. }
  1652. return (
  1653. intRegExp.test(value) &&
  1654. (min === undefined || value >= min) &&
  1655. (max === undefined || value <= max)
  1656. );
  1657. },
  1658. // is valid number (with decimal)
  1659. decimal: function(value) {
  1660. return $.fn.form.settings.regExp.decimal.test(value);
  1661. },
  1662. // is valid number
  1663. number: function(value) {
  1664. return $.fn.form.settings.regExp.number.test(value);
  1665. },
  1666. // is value (case insensitive)
  1667. is: function(value, text) {
  1668. text = (typeof text == 'string')
  1669. ? text.toLowerCase()
  1670. : text
  1671. ;
  1672. value = (typeof value == 'string')
  1673. ? value.toLowerCase()
  1674. : value
  1675. ;
  1676. return (value == text);
  1677. },
  1678. // is value
  1679. isExactly: function(value, text) {
  1680. return (value == text);
  1681. },
  1682. // value is not another value (case insensitive)
  1683. not: function(value, notValue) {
  1684. value = (typeof value == 'string')
  1685. ? value.toLowerCase()
  1686. : value
  1687. ;
  1688. notValue = (typeof notValue == 'string')
  1689. ? notValue.toLowerCase()
  1690. : notValue
  1691. ;
  1692. return (value != notValue);
  1693. },
  1694. // value is not another value (case sensitive)
  1695. notExactly: function(value, notValue) {
  1696. return (value != notValue);
  1697. },
  1698. // value contains text (insensitive)
  1699. contains: function(value, text) {
  1700. // escape regex characters
  1701. text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
  1702. return (value.search( new RegExp(text, 'i') ) !== -1);
  1703. },
  1704. // value contains text (case sensitive)
  1705. containsExactly: function(value, text) {
  1706. // escape regex characters
  1707. text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
  1708. return (value.search( new RegExp(text) ) !== -1);
  1709. },
  1710. // value contains text (insensitive)
  1711. doesntContain: function(value, text) {
  1712. // escape regex characters
  1713. text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
  1714. return (value.search( new RegExp(text, 'i') ) === -1);
  1715. },
  1716. // value contains text (case sensitive)
  1717. doesntContainExactly: function(value, text) {
  1718. // escape regex characters
  1719. text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
  1720. return (value.search( new RegExp(text) ) === -1);
  1721. },
  1722. // is at least string length
  1723. minLength: function(value, requiredLength) {
  1724. return (value !== undefined)
  1725. ? (value.length >= requiredLength)
  1726. : false
  1727. ;
  1728. },
  1729. // see rls notes for 2.0.6 (this is a duplicate of minLength)
  1730. length: function(value, requiredLength) {
  1731. return (value !== undefined)
  1732. ? (value.length >= requiredLength)
  1733. : false
  1734. ;
  1735. },
  1736. // is exactly length
  1737. exactLength: function(value, requiredLength) {
  1738. return (value !== undefined)
  1739. ? (value.length == requiredLength)
  1740. : false
  1741. ;
  1742. },
  1743. // is less than length
  1744. maxLength: function(value, maxLength) {
  1745. return (value !== undefined)
  1746. ? (value.length <= maxLength)
  1747. : false
  1748. ;
  1749. },
  1750. // matches another field
  1751. match: function(value, identifier) {
  1752. var
  1753. $form = $(this),
  1754. matchingValue
  1755. ;
  1756. if( $('[data-validate="'+ identifier +'"]').length > 0 ) {
  1757. matchingValue = $('[data-validate="'+ identifier +'"]').val();
  1758. }
  1759. else if($('#' + identifier).length > 0) {
  1760. matchingValue = $('#' + identifier).val();
  1761. }
  1762. else if($('[name="' + identifier +'"]').length > 0) {
  1763. matchingValue = $('[name="' + identifier + '"]').val();
  1764. }
  1765. else if( $('[name="' + identifier +'[]"]').length > 0 ) {
  1766. matchingValue = $('[name="' + identifier +'[]"]');
  1767. }
  1768. return (matchingValue !== undefined)
  1769. ? ( value.toString() == matchingValue.toString() )
  1770. : false
  1771. ;
  1772. },
  1773. // different than another field
  1774. different: function(value, identifier) {
  1775. // use either id or name of field
  1776. var
  1777. $form = $(this),
  1778. matchingValue
  1779. ;
  1780. if( $('[data-validate="'+ identifier +'"]').length > 0 ) {
  1781. matchingValue = $('[data-validate="'+ identifier +'"]').val();
  1782. }
  1783. else if($('#' + identifier).length > 0) {
  1784. matchingValue = $('#' + identifier).val();
  1785. }
  1786. else if($('[name="' + identifier +'"]').length > 0) {
  1787. matchingValue = $('[name="' + identifier + '"]').val();
  1788. }
  1789. else if( $('[name="' + identifier +'[]"]').length > 0 ) {
  1790. matchingValue = $('[name="' + identifier +'[]"]');
  1791. }
  1792. return (matchingValue !== undefined)
  1793. ? ( value.toString() !== matchingValue.toString() )
  1794. : false
  1795. ;
  1796. },
  1797. creditCard: function(cardNumber, cardTypes) {
  1798. var
  1799. cards = {
  1800. visa: {
  1801. pattern : /^4/,
  1802. length : [16]
  1803. },
  1804. amex: {
  1805. pattern : /^3[47]/,
  1806. length : [15]
  1807. },
  1808. mastercard: {
  1809. pattern : /^5[1-5]/,
  1810. length : [16]
  1811. },
  1812. discover: {
  1813. pattern : /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/,
  1814. length : [16]
  1815. },
  1816. unionPay: {
  1817. pattern : /^(62|88)/,
  1818. length : [16, 17, 18, 19]
  1819. },
  1820. jcb: {
  1821. pattern : /^35(2[89]|[3-8][0-9])/,
  1822. length : [16]
  1823. },
  1824. maestro: {
  1825. pattern : /^(5018|5020|5038|6304|6759|676[1-3])/,
  1826. length : [12, 13, 14, 15, 16, 17, 18, 19]
  1827. },
  1828. dinersClub: {
  1829. pattern : /^(30[0-5]|^36)/,
  1830. length : [14]
  1831. },
  1832. laser: {
  1833. pattern : /^(6304|670[69]|6771)/,
  1834. length : [16, 17, 18, 19]
  1835. },
  1836. visaElectron: {
  1837. pattern : /^(4026|417500|4508|4844|491(3|7))/,
  1838. length : [16]
  1839. }
  1840. },
  1841. valid = {},
  1842. validCard = false,
  1843. requiredTypes = (typeof cardTypes == 'string')
  1844. ? cardTypes.split(',')
  1845. : false,
  1846. unionPay,
  1847. validation
  1848. ;
  1849. if(typeof cardNumber !== 'string' || cardNumber.length === 0) {
  1850. return;
  1851. }
  1852. // verify card types
  1853. if(requiredTypes) {
  1854. $.each(requiredTypes, function(index, type){
  1855. // verify each card type
  1856. validation = cards[type];
  1857. if(validation) {
  1858. valid = {
  1859. length : ($.inArray(cardNumber.length, validation.length) !== -1),
  1860. pattern : (cardNumber.search(validation.pattern) !== -1)
  1861. };
  1862. if(valid.length && valid.pattern) {
  1863. validCard = true;
  1864. }
  1865. }
  1866. });
  1867. if(!validCard) {
  1868. return false;
  1869. }
  1870. }
  1871. // skip luhn for UnionPay
  1872. unionPay = {
  1873. number : ($.inArray(cardNumber.length, cards.unionPay.length) !== -1),
  1874. pattern : (cardNumber.search(cards.unionPay.pattern) !== -1)
  1875. };
  1876. if(unionPay.number && unionPay.pattern) {
  1877. return true;
  1878. }
  1879. // verify luhn, adapted from <https://gist.github.com/2134376>
  1880. var
  1881. length = cardNumber.length,
  1882. multiple = 0,
  1883. producedValue = [
  1884. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
  1885. [0, 2, 4, 6, 8, 1, 3, 5, 7, 9]
  1886. ],
  1887. sum = 0
  1888. ;
  1889. while (length--) {
  1890. sum += producedValue[multiple][parseInt(cardNumber.charAt(length), 10)];
  1891. multiple ^= 1;
  1892. }
  1893. return (sum % 10 === 0 && sum > 0);
  1894. },
  1895. minCount: function(value, minCount) {
  1896. if(minCount == 0) {
  1897. return true;
  1898. }
  1899. if(minCount == 1) {
  1900. return (value !== '');
  1901. }
  1902. return (value.split(',').length >= minCount);
  1903. },
  1904. exactCount: function(value, exactCount) {
  1905. if(exactCount == 0) {
  1906. return (value === '');
  1907. }
  1908. if(exactCount == 1) {
  1909. return (value !== '' && value.search(',') === -1);
  1910. }
  1911. return (value.split(',').length == exactCount);
  1912. },
  1913. maxCount: function(value, maxCount) {
  1914. if(maxCount == 0) {
  1915. return false;
  1916. }
  1917. if(maxCount == 1) {
  1918. return (value.search(',') === -1);
  1919. }
  1920. return (value.split(',').length <= maxCount);
  1921. }
  1922. }
  1923. };
  1924. })( jQuery, window, document );
  1925. /*!
  1926. * # Semantic UI 2.2.6 - Accordion
  1927. * http://github.com/semantic-org/semantic-ui/
  1928. *
  1929. *
  1930. * Released under the MIT license
  1931. * http://opensource.org/licenses/MIT
  1932. *
  1933. */
  1934. ;(function ($, window, document, undefined) {
  1935. "use strict";
  1936. window = (typeof window != 'undefined' && window.Math == Math)
  1937. ? window
  1938. : (typeof self != 'undefined' && self.Math == Math)
  1939. ? self
  1940. : Function('return this')()
  1941. ;
  1942. $.fn.accordion = function(parameters) {
  1943. var
  1944. $allModules = $(this),
  1945. time = new Date().getTime(),
  1946. performance = [],
  1947. query = arguments[0],
  1948. methodInvoked = (typeof query == 'string'),
  1949. queryArguments = [].slice.call(arguments, 1),
  1950. requestAnimationFrame = window.requestAnimationFrame
  1951. || window.mozRequestAnimationFrame
  1952. || window.webkitRequestAnimationFrame
  1953. || window.msRequestAnimationFrame
  1954. || function(callback) { setTimeout(callback, 0); },
  1955. returnedValue
  1956. ;
  1957. $allModules
  1958. .each(function() {
  1959. var
  1960. settings = ( $.isPlainObject(parameters) )
  1961. ? $.extend(true, {}, $.fn.accordion.settings, parameters)
  1962. : $.extend({}, $.fn.accordion.settings),
  1963. className = settings.className,
  1964. namespace = settings.namespace,
  1965. selector = settings.selector,
  1966. error = settings.error,
  1967. eventNamespace = '.' + namespace,
  1968. moduleNamespace = 'module-' + namespace,
  1969. moduleSelector = $allModules.selector || '',
  1970. $module = $(this),
  1971. $title = $module.find(selector.title),
  1972. $content = $module.find(selector.content),
  1973. element = this,
  1974. instance = $module.data(moduleNamespace),
  1975. observer,
  1976. module
  1977. ;
  1978. module = {
  1979. initialize: function() {
  1980. module.debug('Initializing', $module);
  1981. module.bind.events();
  1982. if(settings.observeChanges) {
  1983. module.observeChanges();
  1984. }
  1985. module.instantiate();
  1986. },
  1987. instantiate: function() {
  1988. instance = module;
  1989. $module
  1990. .data(moduleNamespace, module)
  1991. ;
  1992. },
  1993. destroy: function() {
  1994. module.debug('Destroying previous instance', $module);
  1995. $module
  1996. .off(eventNamespace)
  1997. .removeData(moduleNamespace)
  1998. ;
  1999. },
  2000. refresh: function() {
  2001. $title = $module.find(selector.title);
  2002. $content = $module.find(selector.content);
  2003. },
  2004. observeChanges: function() {
  2005. if('MutationObserver' in window) {
  2006. observer = new MutationObserver(function(mutations) {
  2007. module.debug('DOM tree modified, updating selector cache');
  2008. module.refresh();
  2009. });
  2010. observer.observe(element, {
  2011. childList : true,
  2012. subtree : true
  2013. });
  2014. module.debug('Setting up mutation observer', observer);
  2015. }
  2016. },
  2017. bind: {
  2018. events: function() {
  2019. module.debug('Binding delegated events');
  2020. $module
  2021. .on(settings.on + eventNamespace, selector.trigger, module.event.click)
  2022. ;
  2023. }
  2024. },
  2025. event: {
  2026. click: function() {
  2027. module.toggle.call(this);
  2028. }
  2029. },
  2030. toggle: function(query) {
  2031. var
  2032. $activeTitle = (query !== undefined)
  2033. ? (typeof query === 'number')
  2034. ? $title.eq(query)
  2035. : $(query).closest(selector.title)
  2036. : $(this).closest(selector.title),
  2037. $activeContent = $activeTitle.next($content),
  2038. isAnimating = $activeContent.hasClass(className.animating),
  2039. isActive = $activeContent.hasClass(className.active),
  2040. isOpen = (isActive && !isAnimating),
  2041. isOpening = (!isActive && isAnimating)
  2042. ;
  2043. module.debug('Toggling visibility of content', $activeTitle);
  2044. if(isOpen || isOpening) {
  2045. if(settings.collapsible) {
  2046. module.close.call($activeTitle);
  2047. }
  2048. else {
  2049. module.debug('Cannot close accordion content collapsing is disabled');
  2050. }
  2051. }
  2052. else {
  2053. module.open.call($activeTitle);
  2054. }
  2055. },
  2056. open: function(query) {
  2057. var
  2058. $activeTitle = (query !== undefined)
  2059. ? (typeof query === 'number')
  2060. ? $title.eq(query)
  2061. : $(query).closest(selector.title)
  2062. : $(this).closest(selector.title),
  2063. $activeContent = $activeTitle.next($content),
  2064. isAnimating = $activeContent.hasClass(className.animating),
  2065. isActive = $activeContent.hasClass(className.active),
  2066. isOpen = (isActive || isAnimating)
  2067. ;
  2068. if(isOpen) {
  2069. module.debug('Accordion already open, skipping', $activeContent);
  2070. return;
  2071. }
  2072. module.debug('Opening accordion content', $activeTitle);
  2073. settings.onOpening.call($activeContent);
  2074. if(settings.exclusive) {
  2075. module.closeOthers.call($activeTitle);
  2076. }
  2077. $activeTitle
  2078. .addClass(className.active)
  2079. ;
  2080. $activeContent
  2081. .stop(true, true)
  2082. .addClass(className.animating)
  2083. ;
  2084. if(settings.animateChildren) {
  2085. if($.fn.transition !== undefined && $module.transition('is supported')) {
  2086. $activeContent
  2087. .children()
  2088. .transition({
  2089. animation : 'fade in',
  2090. queue : false,
  2091. useFailSafe : true,
  2092. debug : settings.debug,
  2093. verbose : settings.verbose,
  2094. duration : settings.duration
  2095. })
  2096. ;
  2097. }
  2098. else {
  2099. $activeContent
  2100. .children()
  2101. .stop(true, true)
  2102. .animate({
  2103. opacity: 1
  2104. }, settings.duration, module.resetOpacity)
  2105. ;
  2106. }
  2107. }
  2108. $activeContent
  2109. .slideDown(settings.duration, settings.easing, function() {
  2110. $activeContent
  2111. .removeClass(className.animating)
  2112. .addClass(className.active)
  2113. ;
  2114. module.reset.display.call(this);
  2115. settings.onOpen.call(this);
  2116. settings.onChange.call(this);
  2117. })
  2118. ;
  2119. },
  2120. close: function(query) {
  2121. var
  2122. $activeTitle = (query !== undefined)
  2123. ? (typeof query === 'number')
  2124. ? $title.eq(query)
  2125. : $(query).closest(selector.title)
  2126. : $(this).closest(selector.title),
  2127. $activeContent = $activeTitle.next($content),
  2128. isAnimating = $activeContent.hasClass(className.animating),
  2129. isActive = $activeContent.hasClass(className.active),
  2130. isOpening = (!isActive && isAnimating),
  2131. isClosing = (isActive && isAnimating)
  2132. ;
  2133. if((isActive || isOpening) && !isClosing) {
  2134. module.debug('Closing accordion content', $activeContent);
  2135. settings.onClosing.call($activeContent);
  2136. $activeTitle
  2137. .removeClass(className.active)
  2138. ;
  2139. $activeContent
  2140. .stop(true, true)
  2141. .addClass(className.animating)
  2142. ;
  2143. if(settings.animateChildren) {
  2144. if($.fn.transition !== undefined && $module.transition('is supported')) {
  2145. $activeContent
  2146. .children()
  2147. .transition({
  2148. animation : 'fade out',
  2149. queue : false,
  2150. useFailSafe : true,
  2151. debug : settings.debug,
  2152. verbose : settings.verbose,
  2153. duration : settings.duration
  2154. })
  2155. ;
  2156. }
  2157. else {
  2158. $activeContent
  2159. .children()
  2160. .stop(true, true)
  2161. .animate({
  2162. opacity: 0
  2163. }, settings.duration, module.resetOpacity)
  2164. ;
  2165. }
  2166. }
  2167. $activeContent
  2168. .slideUp(settings.duration, settings.easing, function() {
  2169. $activeContent
  2170. .removeClass(className.animating)
  2171. .removeClass(className.active)
  2172. ;
  2173. module.reset.display.call(this);
  2174. settings.onClose.call(this);
  2175. settings.onChange.call(this);
  2176. })
  2177. ;
  2178. }
  2179. },
  2180. closeOthers: function(index) {
  2181. var
  2182. $activeTitle = (index !== undefined)
  2183. ? $title.eq(index)
  2184. : $(this).closest(selector.title),
  2185. $parentTitles = $activeTitle.parents(selector.content).prev(selector.title),
  2186. $activeAccordion = $activeTitle.closest(selector.accordion),
  2187. activeSelector = selector.title + '.' + className.active + ':visible',
  2188. activeContent = selector.content + '.' + className.active + ':visible',
  2189. $openTitles,
  2190. $nestedTitles,
  2191. $openContents
  2192. ;
  2193. if(settings.closeNested) {
  2194. $openTitles = $activeAccordion.find(activeSelector).not($parentTitles);
  2195. $openContents = $openTitles.next($content);
  2196. }
  2197. else {
  2198. $openTitles = $activeAccordion.find(activeSelector).not($parentTitles);
  2199. $nestedTitles = $activeAccordion.find(activeContent).find(activeSelector).not($parentTitles);
  2200. $openTitles = $openTitles.not($nestedTitles);
  2201. $openContents = $openTitles.next($content);
  2202. }
  2203. if( ($openTitles.length > 0) ) {
  2204. module.debug('Exclusive enabled, closing other content', $openTitles);
  2205. $openTitles
  2206. .removeClass(className.active)
  2207. ;
  2208. $openContents
  2209. .removeClass(className.animating)
  2210. .stop(true, true)
  2211. ;
  2212. if(settings.animateChildren) {
  2213. if($.fn.transition !== undefined && $module.transition('is supported')) {
  2214. $openContents
  2215. .children()
  2216. .transition({
  2217. animation : 'fade out',
  2218. useFailSafe : true,
  2219. debug : settings.debug,
  2220. verbose : settings.verbose,
  2221. duration : settings.duration
  2222. })
  2223. ;
  2224. }
  2225. else {
  2226. $openContents
  2227. .children()
  2228. .stop(true, true)
  2229. .animate({
  2230. opacity: 0
  2231. }, settings.duration, module.resetOpacity)
  2232. ;
  2233. }
  2234. }
  2235. $openContents
  2236. .slideUp(settings.duration , settings.easing, function() {
  2237. $(this).removeClass(className.active);
  2238. module.reset.display.call(this);
  2239. })
  2240. ;
  2241. }
  2242. },
  2243. reset: {
  2244. display: function() {
  2245. module.verbose('Removing inline display from element', this);
  2246. $(this).css('display', '');
  2247. if( $(this).attr('style') === '') {
  2248. $(this)
  2249. .attr('style', '')
  2250. .removeAttr('style')
  2251. ;
  2252. }
  2253. },
  2254. opacity: function() {
  2255. module.verbose('Removing inline opacity from element', this);
  2256. $(this).css('opacity', '');
  2257. if( $(this).attr('style') === '') {
  2258. $(this)
  2259. .attr('style', '')
  2260. .removeAttr('style')
  2261. ;
  2262. }
  2263. },
  2264. },
  2265. setting: function(name, value) {
  2266. module.debug('Changing setting', name, value);
  2267. if( $.isPlainObject(name) ) {
  2268. $.extend(true, settings, name);
  2269. }
  2270. else if(value !== undefined) {
  2271. if($.isPlainObject(settings[name])) {
  2272. $.extend(true, settings[name], value);
  2273. }
  2274. else {
  2275. settings[name] = value;
  2276. }
  2277. }
  2278. else {
  2279. return settings[name];
  2280. }
  2281. },
  2282. internal: function(name, value) {
  2283. module.debug('Changing internal', name, value);
  2284. if(value !== undefined) {
  2285. if( $.isPlainObject(name) ) {
  2286. $.extend(true, module, name);
  2287. }
  2288. else {
  2289. module[name] = value;
  2290. }
  2291. }
  2292. else {
  2293. return module[name];
  2294. }
  2295. },
  2296. debug: function() {
  2297. if(!settings.silent && settings.debug) {
  2298. if(settings.performance) {
  2299. module.performance.log(arguments);
  2300. }
  2301. else {
  2302. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  2303. module.debug.apply(console, arguments);
  2304. }
  2305. }
  2306. },
  2307. verbose: function() {
  2308. if(!settings.silent && settings.verbose && settings.debug) {
  2309. if(settings.performance) {
  2310. module.performance.log(arguments);
  2311. }
  2312. else {
  2313. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  2314. module.verbose.apply(console, arguments);
  2315. }
  2316. }
  2317. },
  2318. error: function() {
  2319. if(!settings.silent) {
  2320. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  2321. module.error.apply(console, arguments);
  2322. }
  2323. },
  2324. performance: {
  2325. log: function(message) {
  2326. var
  2327. currentTime,
  2328. executionTime,
  2329. previousTime
  2330. ;
  2331. if(settings.performance) {
  2332. currentTime = new Date().getTime();
  2333. previousTime = time || currentTime;
  2334. executionTime = currentTime - previousTime;
  2335. time = currentTime;
  2336. performance.push({
  2337. 'Name' : message[0],
  2338. 'Arguments' : [].slice.call(message, 1) || '',
  2339. 'Element' : element,
  2340. 'Execution Time' : executionTime
  2341. });
  2342. }
  2343. clearTimeout(module.performance.timer);
  2344. module.performance.timer = setTimeout(module.performance.display, 500);
  2345. },
  2346. display: function() {
  2347. var
  2348. title = settings.name + ':',
  2349. totalTime = 0
  2350. ;
  2351. time = false;
  2352. clearTimeout(module.performance.timer);
  2353. $.each(performance, function(index, data) {
  2354. totalTime += data['Execution Time'];
  2355. });
  2356. title += ' ' + totalTime + 'ms';
  2357. if(moduleSelector) {
  2358. title += ' \'' + moduleSelector + '\'';
  2359. }
  2360. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  2361. console.groupCollapsed(title);
  2362. if(console.table) {
  2363. console.table(performance);
  2364. }
  2365. else {
  2366. $.each(performance, function(index, data) {
  2367. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  2368. });
  2369. }
  2370. console.groupEnd();
  2371. }
  2372. performance = [];
  2373. }
  2374. },
  2375. invoke: function(query, passedArguments, context) {
  2376. var
  2377. object = instance,
  2378. maxDepth,
  2379. found,
  2380. response
  2381. ;
  2382. passedArguments = passedArguments || queryArguments;
  2383. context = element || context;
  2384. if(typeof query == 'string' && object !== undefined) {
  2385. query = query.split(/[\. ]/);
  2386. maxDepth = query.length - 1;
  2387. $.each(query, function(depth, value) {
  2388. var camelCaseValue = (depth != maxDepth)
  2389. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  2390. : query
  2391. ;
  2392. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  2393. object = object[camelCaseValue];
  2394. }
  2395. else if( object[camelCaseValue] !== undefined ) {
  2396. found = object[camelCaseValue];
  2397. return false;
  2398. }
  2399. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  2400. object = object[value];
  2401. }
  2402. else if( object[value] !== undefined ) {
  2403. found = object[value];
  2404. return false;
  2405. }
  2406. else {
  2407. module.error(error.method, query);
  2408. return false;
  2409. }
  2410. });
  2411. }
  2412. if ( $.isFunction( found ) ) {
  2413. response = found.apply(context, passedArguments);
  2414. }
  2415. else if(found !== undefined) {
  2416. response = found;
  2417. }
  2418. if($.isArray(returnedValue)) {
  2419. returnedValue.push(response);
  2420. }
  2421. else if(returnedValue !== undefined) {
  2422. returnedValue = [returnedValue, response];
  2423. }
  2424. else if(response !== undefined) {
  2425. returnedValue = response;
  2426. }
  2427. return found;
  2428. }
  2429. };
  2430. if(methodInvoked) {
  2431. if(instance === undefined) {
  2432. module.initialize();
  2433. }
  2434. module.invoke(query);
  2435. }
  2436. else {
  2437. if(instance !== undefined) {
  2438. instance.invoke('destroy');
  2439. }
  2440. module.initialize();
  2441. }
  2442. })
  2443. ;
  2444. return (returnedValue !== undefined)
  2445. ? returnedValue
  2446. : this
  2447. ;
  2448. };
  2449. $.fn.accordion.settings = {
  2450. name : 'Accordion',
  2451. namespace : 'accordion',
  2452. silent : false,
  2453. debug : false,
  2454. verbose : false,
  2455. performance : true,
  2456. on : 'click', // event on title that opens accordion
  2457. observeChanges : true, // whether accordion should automatically refresh on DOM insertion
  2458. exclusive : true, // whether a single accordion content panel should be open at once
  2459. collapsible : true, // whether accordion content can be closed
  2460. closeNested : false, // whether nested content should be closed when a panel is closed
  2461. animateChildren : true, // whether children opacity should be animated
  2462. duration : 350, // duration of animation
  2463. easing : 'easeOutQuad', // easing equation for animation
  2464. onOpening : function(){}, // callback before open animation
  2465. onOpen : function(){}, // callback after open animation
  2466. onClosing : function(){}, // callback before closing animation
  2467. onClose : function(){}, // callback after closing animation
  2468. onChange : function(){}, // callback after closing or opening animation
  2469. error: {
  2470. method : 'The method you called is not defined'
  2471. },
  2472. className : {
  2473. active : 'active',
  2474. animating : 'animating'
  2475. },
  2476. selector : {
  2477. accordion : '.accordion',
  2478. title : '.title',
  2479. trigger : '.title',
  2480. content : '.content'
  2481. }
  2482. };
  2483. // Adds easing
  2484. $.extend( $.easing, {
  2485. easeOutQuad: function (x, t, b, c, d) {
  2486. return -c *(t/=d)*(t-2) + b;
  2487. }
  2488. });
  2489. })( jQuery, window, document );
  2490. /*!
  2491. * # Semantic UI 2.2.6 - Checkbox
  2492. * http://github.com/semantic-org/semantic-ui/
  2493. *
  2494. *
  2495. * Released under the MIT license
  2496. * http://opensource.org/licenses/MIT
  2497. *
  2498. */
  2499. ;(function ($, window, document, undefined) {
  2500. "use strict";
  2501. window = (typeof window != 'undefined' && window.Math == Math)
  2502. ? window
  2503. : (typeof self != 'undefined' && self.Math == Math)
  2504. ? self
  2505. : Function('return this')()
  2506. ;
  2507. $.fn.checkbox = function(parameters) {
  2508. var
  2509. $allModules = $(this),
  2510. moduleSelector = $allModules.selector || '',
  2511. time = new Date().getTime(),
  2512. performance = [],
  2513. query = arguments[0],
  2514. methodInvoked = (typeof query == 'string'),
  2515. queryArguments = [].slice.call(arguments, 1),
  2516. returnedValue
  2517. ;
  2518. $allModules
  2519. .each(function() {
  2520. var
  2521. settings = $.extend(true, {}, $.fn.checkbox.settings, parameters),
  2522. className = settings.className,
  2523. namespace = settings.namespace,
  2524. selector = settings.selector,
  2525. error = settings.error,
  2526. eventNamespace = '.' + namespace,
  2527. moduleNamespace = 'module-' + namespace,
  2528. $module = $(this),
  2529. $label = $(this).children(selector.label),
  2530. $input = $(this).children(selector.input),
  2531. input = $input[0],
  2532. initialLoad = false,
  2533. shortcutPressed = false,
  2534. instance = $module.data(moduleNamespace),
  2535. observer,
  2536. element = this,
  2537. module
  2538. ;
  2539. module = {
  2540. initialize: function() {
  2541. module.verbose('Initializing checkbox', settings);
  2542. module.create.label();
  2543. module.bind.events();
  2544. module.set.tabbable();
  2545. module.hide.input();
  2546. module.observeChanges();
  2547. module.instantiate();
  2548. module.setup();
  2549. },
  2550. instantiate: function() {
  2551. module.verbose('Storing instance of module', module);
  2552. instance = module;
  2553. $module
  2554. .data(moduleNamespace, module)
  2555. ;
  2556. },
  2557. destroy: function() {
  2558. module.verbose('Destroying module');
  2559. module.unbind.events();
  2560. module.show.input();
  2561. $module.removeData(moduleNamespace);
  2562. },
  2563. fix: {
  2564. reference: function() {
  2565. if( $module.is(selector.input) ) {
  2566. module.debug('Behavior called on <input> adjusting invoked element');
  2567. $module = $module.closest(selector.checkbox);
  2568. module.refresh();
  2569. }
  2570. }
  2571. },
  2572. setup: function() {
  2573. module.set.initialLoad();
  2574. if( module.is.indeterminate() ) {
  2575. module.debug('Initial value is indeterminate');
  2576. module.indeterminate();
  2577. }
  2578. else if( module.is.checked() ) {
  2579. module.debug('Initial value is checked');
  2580. module.check();
  2581. }
  2582. else {
  2583. module.debug('Initial value is unchecked');
  2584. module.uncheck();
  2585. }
  2586. module.remove.initialLoad();
  2587. },
  2588. refresh: function() {
  2589. $label = $module.children(selector.label);
  2590. $input = $module.children(selector.input);
  2591. input = $input[0];
  2592. },
  2593. hide: {
  2594. input: function() {
  2595. module.verbose('Modifying <input> z-index to be unselectable');
  2596. $input.addClass(className.hidden);
  2597. }
  2598. },
  2599. show: {
  2600. input: function() {
  2601. module.verbose('Modifying <input> z-index to be selectable');
  2602. $input.removeClass(className.hidden);
  2603. }
  2604. },
  2605. observeChanges: function() {
  2606. if('MutationObserver' in window) {
  2607. observer = new MutationObserver(function(mutations) {
  2608. module.debug('DOM tree modified, updating selector cache');
  2609. module.refresh();
  2610. });
  2611. observer.observe(element, {
  2612. childList : true,
  2613. subtree : true
  2614. });
  2615. module.debug('Setting up mutation observer', observer);
  2616. }
  2617. },
  2618. attachEvents: function(selector, event) {
  2619. var
  2620. $element = $(selector)
  2621. ;
  2622. event = $.isFunction(module[event])
  2623. ? module[event]
  2624. : module.toggle
  2625. ;
  2626. if($element.length > 0) {
  2627. module.debug('Attaching checkbox events to element', selector, event);
  2628. $element
  2629. .on('click' + eventNamespace, event)
  2630. ;
  2631. }
  2632. else {
  2633. module.error(error.notFound);
  2634. }
  2635. },
  2636. event: {
  2637. click: function(event) {
  2638. var
  2639. $target = $(event.target)
  2640. ;
  2641. if( $target.is(selector.input) ) {
  2642. module.verbose('Using default check action on initialized checkbox');
  2643. return;
  2644. }
  2645. if( $target.is(selector.link) ) {
  2646. module.debug('Clicking link inside checkbox, skipping toggle');
  2647. return;
  2648. }
  2649. module.toggle();
  2650. $input.focus();
  2651. event.preventDefault();
  2652. },
  2653. keydown: function(event) {
  2654. var
  2655. key = event.which,
  2656. keyCode = {
  2657. enter : 13,
  2658. space : 32,
  2659. escape : 27
  2660. }
  2661. ;
  2662. if(key == keyCode.escape) {
  2663. module.verbose('Escape key pressed blurring field');
  2664. $input.blur();
  2665. shortcutPressed = true;
  2666. }
  2667. else if(!event.ctrlKey && ( key == keyCode.space || key == keyCode.enter) ) {
  2668. module.verbose('Enter/space key pressed, toggling checkbox');
  2669. module.toggle();
  2670. shortcutPressed = true;
  2671. }
  2672. else {
  2673. shortcutPressed = false;
  2674. }
  2675. },
  2676. keyup: function(event) {
  2677. if(shortcutPressed) {
  2678. event.preventDefault();
  2679. }
  2680. }
  2681. },
  2682. check: function() {
  2683. if( !module.should.allowCheck() ) {
  2684. return;
  2685. }
  2686. module.debug('Checking checkbox', $input);
  2687. module.set.checked();
  2688. if( !module.should.ignoreCallbacks() ) {
  2689. settings.onChecked.call(input);
  2690. settings.onChange.call(input);
  2691. }
  2692. },
  2693. uncheck: function() {
  2694. if( !module.should.allowUncheck() ) {
  2695. return;
  2696. }
  2697. module.debug('Unchecking checkbox');
  2698. module.set.unchecked();
  2699. if( !module.should.ignoreCallbacks() ) {
  2700. settings.onUnchecked.call(input);
  2701. settings.onChange.call(input);
  2702. }
  2703. },
  2704. indeterminate: function() {
  2705. if( module.should.allowIndeterminate() ) {
  2706. module.debug('Checkbox is already indeterminate');
  2707. return;
  2708. }
  2709. module.debug('Making checkbox indeterminate');
  2710. module.set.indeterminate();
  2711. if( !module.should.ignoreCallbacks() ) {
  2712. settings.onIndeterminate.call(input);
  2713. settings.onChange.call(input);
  2714. }
  2715. },
  2716. determinate: function() {
  2717. if( module.should.allowDeterminate() ) {
  2718. module.debug('Checkbox is already determinate');
  2719. return;
  2720. }
  2721. module.debug('Making checkbox determinate');
  2722. module.set.determinate();
  2723. if( !module.should.ignoreCallbacks() ) {
  2724. settings.onDeterminate.call(input);
  2725. settings.onChange.call(input);
  2726. }
  2727. },
  2728. enable: function() {
  2729. if( module.is.enabled() ) {
  2730. module.debug('Checkbox is already enabled');
  2731. return;
  2732. }
  2733. module.debug('Enabling checkbox');
  2734. module.set.enabled();
  2735. settings.onEnable.call(input);
  2736. // preserve legacy callbacks
  2737. settings.onEnabled.call(input);
  2738. },
  2739. disable: function() {
  2740. if( module.is.disabled() ) {
  2741. module.debug('Checkbox is already disabled');
  2742. return;
  2743. }
  2744. module.debug('Disabling checkbox');
  2745. module.set.disabled();
  2746. settings.onDisable.call(input);
  2747. // preserve legacy callbacks
  2748. settings.onDisabled.call(input);
  2749. },
  2750. get: {
  2751. radios: function() {
  2752. var
  2753. name = module.get.name()
  2754. ;
  2755. return $('input[name="' + name + '"]').closest(selector.checkbox);
  2756. },
  2757. otherRadios: function() {
  2758. return module.get.radios().not($module);
  2759. },
  2760. name: function() {
  2761. return $input.attr('name');
  2762. }
  2763. },
  2764. is: {
  2765. initialLoad: function() {
  2766. return initialLoad;
  2767. },
  2768. radio: function() {
  2769. return ($input.hasClass(className.radio) || $input.attr('type') == 'radio');
  2770. },
  2771. indeterminate: function() {
  2772. return $input.prop('indeterminate') !== undefined && $input.prop('indeterminate');
  2773. },
  2774. checked: function() {
  2775. return $input.prop('checked') !== undefined && $input.prop('checked');
  2776. },
  2777. disabled: function() {
  2778. return $input.prop('disabled') !== undefined && $input.prop('disabled');
  2779. },
  2780. enabled: function() {
  2781. return !module.is.disabled();
  2782. },
  2783. determinate: function() {
  2784. return !module.is.indeterminate();
  2785. },
  2786. unchecked: function() {
  2787. return !module.is.checked();
  2788. }
  2789. },
  2790. should: {
  2791. allowCheck: function() {
  2792. if(module.is.determinate() && module.is.checked() && !module.should.forceCallbacks() ) {
  2793. module.debug('Should not allow check, checkbox is already checked');
  2794. return false;
  2795. }
  2796. if(settings.beforeChecked.apply(input) === false) {
  2797. module.debug('Should not allow check, beforeChecked cancelled');
  2798. return false;
  2799. }
  2800. return true;
  2801. },
  2802. allowUncheck: function() {
  2803. if(module.is.determinate() && module.is.unchecked() && !module.should.forceCallbacks() ) {
  2804. module.debug('Should not allow uncheck, checkbox is already unchecked');
  2805. return false;
  2806. }
  2807. if(settings.beforeUnchecked.apply(input) === false) {
  2808. module.debug('Should not allow uncheck, beforeUnchecked cancelled');
  2809. return false;
  2810. }
  2811. return true;
  2812. },
  2813. allowIndeterminate: function() {
  2814. if(module.is.indeterminate() && !module.should.forceCallbacks() ) {
  2815. module.debug('Should not allow indeterminate, checkbox is already indeterminate');
  2816. return false;
  2817. }
  2818. if(settings.beforeIndeterminate.apply(input) === false) {
  2819. module.debug('Should not allow indeterminate, beforeIndeterminate cancelled');
  2820. return false;
  2821. }
  2822. return true;
  2823. },
  2824. allowDeterminate: function() {
  2825. if(module.is.determinate() && !module.should.forceCallbacks() ) {
  2826. module.debug('Should not allow determinate, checkbox is already determinate');
  2827. return false;
  2828. }
  2829. if(settings.beforeDeterminate.apply(input) === false) {
  2830. module.debug('Should not allow determinate, beforeDeterminate cancelled');
  2831. return false;
  2832. }
  2833. return true;
  2834. },
  2835. forceCallbacks: function() {
  2836. return (module.is.initialLoad() && settings.fireOnInit);
  2837. },
  2838. ignoreCallbacks: function() {
  2839. return (initialLoad && !settings.fireOnInit);
  2840. }
  2841. },
  2842. can: {
  2843. change: function() {
  2844. return !( $module.hasClass(className.disabled) || $module.hasClass(className.readOnly) || $input.prop('disabled') || $input.prop('readonly') );
  2845. },
  2846. uncheck: function() {
  2847. return (typeof settings.uncheckable === 'boolean')
  2848. ? settings.uncheckable
  2849. : !module.is.radio()
  2850. ;
  2851. }
  2852. },
  2853. set: {
  2854. initialLoad: function() {
  2855. initialLoad = true;
  2856. },
  2857. checked: function() {
  2858. module.verbose('Setting class to checked');
  2859. $module
  2860. .removeClass(className.indeterminate)
  2861. .addClass(className.checked)
  2862. ;
  2863. if( module.is.radio() ) {
  2864. module.uncheckOthers();
  2865. }
  2866. if(!module.is.indeterminate() && module.is.checked()) {
  2867. module.debug('Input is already checked, skipping input property change');
  2868. return;
  2869. }
  2870. module.verbose('Setting state to checked', input);
  2871. $input
  2872. .prop('indeterminate', false)
  2873. .prop('checked', true)
  2874. ;
  2875. module.trigger.change();
  2876. },
  2877. unchecked: function() {
  2878. module.verbose('Removing checked class');
  2879. $module
  2880. .removeClass(className.indeterminate)
  2881. .removeClass(className.checked)
  2882. ;
  2883. if(!module.is.indeterminate() && module.is.unchecked() ) {
  2884. module.debug('Input is already unchecked');
  2885. return;
  2886. }
  2887. module.debug('Setting state to unchecked');
  2888. $input
  2889. .prop('indeterminate', false)
  2890. .prop('checked', false)
  2891. ;
  2892. module.trigger.change();
  2893. },
  2894. indeterminate: function() {
  2895. module.verbose('Setting class to indeterminate');
  2896. $module
  2897. .addClass(className.indeterminate)
  2898. ;
  2899. if( module.is.indeterminate() ) {
  2900. module.debug('Input is already indeterminate, skipping input property change');
  2901. return;
  2902. }
  2903. module.debug('Setting state to indeterminate');
  2904. $input
  2905. .prop('indeterminate', true)
  2906. ;
  2907. module.trigger.change();
  2908. },
  2909. determinate: function() {
  2910. module.verbose('Removing indeterminate class');
  2911. $module
  2912. .removeClass(className.indeterminate)
  2913. ;
  2914. if( module.is.determinate() ) {
  2915. module.debug('Input is already determinate, skipping input property change');
  2916. return;
  2917. }
  2918. module.debug('Setting state to determinate');
  2919. $input
  2920. .prop('indeterminate', false)
  2921. ;
  2922. },
  2923. disabled: function() {
  2924. module.verbose('Setting class to disabled');
  2925. $module
  2926. .addClass(className.disabled)
  2927. ;
  2928. if( module.is.disabled() ) {
  2929. module.debug('Input is already disabled, skipping input property change');
  2930. return;
  2931. }
  2932. module.debug('Setting state to disabled');
  2933. $input
  2934. .prop('disabled', 'disabled')
  2935. ;
  2936. module.trigger.change();
  2937. },
  2938. enabled: function() {
  2939. module.verbose('Removing disabled class');
  2940. $module.removeClass(className.disabled);
  2941. if( module.is.enabled() ) {
  2942. module.debug('Input is already enabled, skipping input property change');
  2943. return;
  2944. }
  2945. module.debug('Setting state to enabled');
  2946. $input
  2947. .prop('disabled', false)
  2948. ;
  2949. module.trigger.change();
  2950. },
  2951. tabbable: function() {
  2952. module.verbose('Adding tabindex to checkbox');
  2953. if( $input.attr('tabindex') === undefined) {
  2954. $input.attr('tabindex', 0);
  2955. }
  2956. }
  2957. },
  2958. remove: {
  2959. initialLoad: function() {
  2960. initialLoad = false;
  2961. }
  2962. },
  2963. trigger: {
  2964. change: function() {
  2965. var
  2966. events = document.createEvent('HTMLEvents'),
  2967. inputElement = $input[0]
  2968. ;
  2969. if(inputElement) {
  2970. module.verbose('Triggering native change event');
  2971. events.initEvent('change', true, false);
  2972. inputElement.dispatchEvent(events);
  2973. }
  2974. }
  2975. },
  2976. create: {
  2977. label: function() {
  2978. if($input.prevAll(selector.label).length > 0) {
  2979. $input.prev(selector.label).detach().insertAfter($input);
  2980. module.debug('Moving existing label', $label);
  2981. }
  2982. else if( !module.has.label() ) {
  2983. $label = $('<label>').insertAfter($input);
  2984. module.debug('Creating label', $label);
  2985. }
  2986. }
  2987. },
  2988. has: {
  2989. label: function() {
  2990. return ($label.length > 0);
  2991. }
  2992. },
  2993. bind: {
  2994. events: function() {
  2995. module.verbose('Attaching checkbox events');
  2996. $module
  2997. .on('click' + eventNamespace, module.event.click)
  2998. .on('keydown' + eventNamespace, selector.input, module.event.keydown)
  2999. .on('keyup' + eventNamespace, selector.input, module.event.keyup)
  3000. ;
  3001. }
  3002. },
  3003. unbind: {
  3004. events: function() {
  3005. module.debug('Removing events');
  3006. $module
  3007. .off(eventNamespace)
  3008. ;
  3009. }
  3010. },
  3011. uncheckOthers: function() {
  3012. var
  3013. $radios = module.get.otherRadios()
  3014. ;
  3015. module.debug('Unchecking other radios', $radios);
  3016. $radios.removeClass(className.checked);
  3017. },
  3018. toggle: function() {
  3019. if( !module.can.change() ) {
  3020. if(!module.is.radio()) {
  3021. module.debug('Checkbox is read-only or disabled, ignoring toggle');
  3022. }
  3023. return;
  3024. }
  3025. if( module.is.indeterminate() || module.is.unchecked() ) {
  3026. module.debug('Currently unchecked');
  3027. module.check();
  3028. }
  3029. else if( module.is.checked() && module.can.uncheck() ) {
  3030. module.debug('Currently checked');
  3031. module.uncheck();
  3032. }
  3033. },
  3034. setting: function(name, value) {
  3035. module.debug('Changing setting', name, value);
  3036. if( $.isPlainObject(name) ) {
  3037. $.extend(true, settings, name);
  3038. }
  3039. else if(value !== undefined) {
  3040. if($.isPlainObject(settings[name])) {
  3041. $.extend(true, settings[name], value);
  3042. }
  3043. else {
  3044. settings[name] = value;
  3045. }
  3046. }
  3047. else {
  3048. return settings[name];
  3049. }
  3050. },
  3051. internal: function(name, value) {
  3052. if( $.isPlainObject(name) ) {
  3053. $.extend(true, module, name);
  3054. }
  3055. else if(value !== undefined) {
  3056. module[name] = value;
  3057. }
  3058. else {
  3059. return module[name];
  3060. }
  3061. },
  3062. debug: function() {
  3063. if(!settings.silent && settings.debug) {
  3064. if(settings.performance) {
  3065. module.performance.log(arguments);
  3066. }
  3067. else {
  3068. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  3069. module.debug.apply(console, arguments);
  3070. }
  3071. }
  3072. },
  3073. verbose: function() {
  3074. if(!settings.silent && settings.verbose && settings.debug) {
  3075. if(settings.performance) {
  3076. module.performance.log(arguments);
  3077. }
  3078. else {
  3079. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  3080. module.verbose.apply(console, arguments);
  3081. }
  3082. }
  3083. },
  3084. error: function() {
  3085. if(!settings.silent) {
  3086. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  3087. module.error.apply(console, arguments);
  3088. }
  3089. },
  3090. performance: {
  3091. log: function(message) {
  3092. var
  3093. currentTime,
  3094. executionTime,
  3095. previousTime
  3096. ;
  3097. if(settings.performance) {
  3098. currentTime = new Date().getTime();
  3099. previousTime = time || currentTime;
  3100. executionTime = currentTime - previousTime;
  3101. time = currentTime;
  3102. performance.push({
  3103. 'Name' : message[0],
  3104. 'Arguments' : [].slice.call(message, 1) || '',
  3105. 'Element' : element,
  3106. 'Execution Time' : executionTime
  3107. });
  3108. }
  3109. clearTimeout(module.performance.timer);
  3110. module.performance.timer = setTimeout(module.performance.display, 500);
  3111. },
  3112. display: function() {
  3113. var
  3114. title = settings.name + ':',
  3115. totalTime = 0
  3116. ;
  3117. time = false;
  3118. clearTimeout(module.performance.timer);
  3119. $.each(performance, function(index, data) {
  3120. totalTime += data['Execution Time'];
  3121. });
  3122. title += ' ' + totalTime + 'ms';
  3123. if(moduleSelector) {
  3124. title += ' \'' + moduleSelector + '\'';
  3125. }
  3126. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  3127. console.groupCollapsed(title);
  3128. if(console.table) {
  3129. console.table(performance);
  3130. }
  3131. else {
  3132. $.each(performance, function(index, data) {
  3133. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  3134. });
  3135. }
  3136. console.groupEnd();
  3137. }
  3138. performance = [];
  3139. }
  3140. },
  3141. invoke: function(query, passedArguments, context) {
  3142. var
  3143. object = instance,
  3144. maxDepth,
  3145. found,
  3146. response
  3147. ;
  3148. passedArguments = passedArguments || queryArguments;
  3149. context = element || context;
  3150. if(typeof query == 'string' && object !== undefined) {
  3151. query = query.split(/[\. ]/);
  3152. maxDepth = query.length - 1;
  3153. $.each(query, function(depth, value) {
  3154. var camelCaseValue = (depth != maxDepth)
  3155. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  3156. : query
  3157. ;
  3158. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  3159. object = object[camelCaseValue];
  3160. }
  3161. else if( object[camelCaseValue] !== undefined ) {
  3162. found = object[camelCaseValue];
  3163. return false;
  3164. }
  3165. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  3166. object = object[value];
  3167. }
  3168. else if( object[value] !== undefined ) {
  3169. found = object[value];
  3170. return false;
  3171. }
  3172. else {
  3173. module.error(error.method, query);
  3174. return false;
  3175. }
  3176. });
  3177. }
  3178. if ( $.isFunction( found ) ) {
  3179. response = found.apply(context, passedArguments);
  3180. }
  3181. else if(found !== undefined) {
  3182. response = found;
  3183. }
  3184. if($.isArray(returnedValue)) {
  3185. returnedValue.push(response);
  3186. }
  3187. else if(returnedValue !== undefined) {
  3188. returnedValue = [returnedValue, response];
  3189. }
  3190. else if(response !== undefined) {
  3191. returnedValue = response;
  3192. }
  3193. return found;
  3194. }
  3195. };
  3196. if(methodInvoked) {
  3197. if(instance === undefined) {
  3198. module.initialize();
  3199. }
  3200. module.invoke(query);
  3201. }
  3202. else {
  3203. if(instance !== undefined) {
  3204. instance.invoke('destroy');
  3205. }
  3206. module.initialize();
  3207. }
  3208. })
  3209. ;
  3210. return (returnedValue !== undefined)
  3211. ? returnedValue
  3212. : this
  3213. ;
  3214. };
  3215. $.fn.checkbox.settings = {
  3216. name : 'Checkbox',
  3217. namespace : 'checkbox',
  3218. silent : false,
  3219. debug : false,
  3220. verbose : true,
  3221. performance : true,
  3222. // delegated event context
  3223. uncheckable : 'auto',
  3224. fireOnInit : false,
  3225. onChange : function(){},
  3226. beforeChecked : function(){},
  3227. beforeUnchecked : function(){},
  3228. beforeDeterminate : function(){},
  3229. beforeIndeterminate : function(){},
  3230. onChecked : function(){},
  3231. onUnchecked : function(){},
  3232. onDeterminate : function() {},
  3233. onIndeterminate : function() {},
  3234. onEnable : function(){},
  3235. onDisable : function(){},
  3236. // preserve misspelled callbacks (will be removed in 3.0)
  3237. onEnabled : function(){},
  3238. onDisabled : function(){},
  3239. className : {
  3240. checked : 'checked',
  3241. indeterminate : 'indeterminate',
  3242. disabled : 'disabled',
  3243. hidden : 'hidden',
  3244. radio : 'radio',
  3245. readOnly : 'read-only'
  3246. },
  3247. error : {
  3248. method : 'The method you called is not defined'
  3249. },
  3250. selector : {
  3251. checkbox : '.ui.checkbox',
  3252. label : 'label, .box',
  3253. input : 'input[type="checkbox"], input[type="radio"]',
  3254. link : 'a[href]'
  3255. }
  3256. };
  3257. })( jQuery, window, document );
  3258. /*!
  3259. * # Semantic UI 2.2.6 - Dimmer
  3260. * http://github.com/semantic-org/semantic-ui/
  3261. *
  3262. *
  3263. * Released under the MIT license
  3264. * http://opensource.org/licenses/MIT
  3265. *
  3266. */
  3267. ;(function ($, window, document, undefined) {
  3268. "use strict";
  3269. window = (typeof window != 'undefined' && window.Math == Math)
  3270. ? window
  3271. : (typeof self != 'undefined' && self.Math == Math)
  3272. ? self
  3273. : Function('return this')()
  3274. ;
  3275. $.fn.dimmer = function(parameters) {
  3276. var
  3277. $allModules = $(this),
  3278. time = new Date().getTime(),
  3279. performance = [],
  3280. query = arguments[0],
  3281. methodInvoked = (typeof query == 'string'),
  3282. queryArguments = [].slice.call(arguments, 1),
  3283. returnedValue
  3284. ;
  3285. $allModules
  3286. .each(function() {
  3287. var
  3288. settings = ( $.isPlainObject(parameters) )
  3289. ? $.extend(true, {}, $.fn.dimmer.settings, parameters)
  3290. : $.extend({}, $.fn.dimmer.settings),
  3291. selector = settings.selector,
  3292. namespace = settings.namespace,
  3293. className = settings.className,
  3294. error = settings.error,
  3295. eventNamespace = '.' + namespace,
  3296. moduleNamespace = 'module-' + namespace,
  3297. moduleSelector = $allModules.selector || '',
  3298. clickEvent = ('ontouchstart' in document.documentElement)
  3299. ? 'touchstart'
  3300. : 'click',
  3301. $module = $(this),
  3302. $dimmer,
  3303. $dimmable,
  3304. element = this,
  3305. instance = $module.data(moduleNamespace),
  3306. module
  3307. ;
  3308. module = {
  3309. preinitialize: function() {
  3310. if( module.is.dimmer() ) {
  3311. $dimmable = $module.parent();
  3312. $dimmer = $module;
  3313. }
  3314. else {
  3315. $dimmable = $module;
  3316. if( module.has.dimmer() ) {
  3317. if(settings.dimmerName) {
  3318. $dimmer = $dimmable.find(selector.dimmer).filter('.' + settings.dimmerName);
  3319. }
  3320. else {
  3321. $dimmer = $dimmable.find(selector.dimmer);
  3322. }
  3323. }
  3324. else {
  3325. $dimmer = module.create();
  3326. }
  3327. module.set.variation();
  3328. }
  3329. },
  3330. initialize: function() {
  3331. module.debug('Initializing dimmer', settings);
  3332. module.bind.events();
  3333. module.set.dimmable();
  3334. module.instantiate();
  3335. },
  3336. instantiate: function() {
  3337. module.verbose('Storing instance of module', module);
  3338. instance = module;
  3339. $module
  3340. .data(moduleNamespace, instance)
  3341. ;
  3342. },
  3343. destroy: function() {
  3344. module.verbose('Destroying previous module', $dimmer);
  3345. module.unbind.events();
  3346. module.remove.variation();
  3347. $dimmable
  3348. .off(eventNamespace)
  3349. ;
  3350. },
  3351. bind: {
  3352. events: function() {
  3353. if(settings.on == 'hover') {
  3354. $dimmable
  3355. .on('mouseenter' + eventNamespace, module.show)
  3356. .on('mouseleave' + eventNamespace, module.hide)
  3357. ;
  3358. }
  3359. else if(settings.on == 'click') {
  3360. $dimmable
  3361. .on(clickEvent + eventNamespace, module.toggle)
  3362. ;
  3363. }
  3364. if( module.is.page() ) {
  3365. module.debug('Setting as a page dimmer', $dimmable);
  3366. module.set.pageDimmer();
  3367. }
  3368. if( module.is.closable() ) {
  3369. module.verbose('Adding dimmer close event', $dimmer);
  3370. $dimmable
  3371. .on(clickEvent + eventNamespace, selector.dimmer, module.event.click)
  3372. ;
  3373. }
  3374. }
  3375. },
  3376. unbind: {
  3377. events: function() {
  3378. $module
  3379. .removeData(moduleNamespace)
  3380. ;
  3381. $dimmable
  3382. .off(eventNamespace)
  3383. ;
  3384. }
  3385. },
  3386. event: {
  3387. click: function(event) {
  3388. module.verbose('Determining if event occured on dimmer', event);
  3389. if( $dimmer.find(event.target).length === 0 || $(event.target).is(selector.content) ) {
  3390. module.hide();
  3391. event.stopImmediatePropagation();
  3392. }
  3393. }
  3394. },
  3395. addContent: function(element) {
  3396. var
  3397. $content = $(element)
  3398. ;
  3399. module.debug('Add content to dimmer', $content);
  3400. if($content.parent()[0] !== $dimmer[0]) {
  3401. $content.detach().appendTo($dimmer);
  3402. }
  3403. },
  3404. create: function() {
  3405. var
  3406. $element = $( settings.template.dimmer() )
  3407. ;
  3408. if(settings.dimmerName) {
  3409. module.debug('Creating named dimmer', settings.dimmerName);
  3410. $element.addClass(settings.dimmerName);
  3411. }
  3412. $element
  3413. .appendTo($dimmable)
  3414. ;
  3415. return $element;
  3416. },
  3417. show: function(callback) {
  3418. callback = $.isFunction(callback)
  3419. ? callback
  3420. : function(){}
  3421. ;
  3422. module.debug('Showing dimmer', $dimmer, settings);
  3423. if( (!module.is.dimmed() || module.is.animating()) && module.is.enabled() ) {
  3424. module.animate.show(callback);
  3425. settings.onShow.call(element);
  3426. settings.onChange.call(element);
  3427. }
  3428. else {
  3429. module.debug('Dimmer is already shown or disabled');
  3430. }
  3431. },
  3432. hide: function(callback) {
  3433. callback = $.isFunction(callback)
  3434. ? callback
  3435. : function(){}
  3436. ;
  3437. if( module.is.dimmed() || module.is.animating() ) {
  3438. module.debug('Hiding dimmer', $dimmer);
  3439. module.animate.hide(callback);
  3440. settings.onHide.call(element);
  3441. settings.onChange.call(element);
  3442. }
  3443. else {
  3444. module.debug('Dimmer is not visible');
  3445. }
  3446. },
  3447. toggle: function() {
  3448. module.verbose('Toggling dimmer visibility', $dimmer);
  3449. if( !module.is.dimmed() ) {
  3450. module.show();
  3451. }
  3452. else {
  3453. module.hide();
  3454. }
  3455. },
  3456. animate: {
  3457. show: function(callback) {
  3458. callback = $.isFunction(callback)
  3459. ? callback
  3460. : function(){}
  3461. ;
  3462. if(settings.useCSS && $.fn.transition !== undefined && $dimmer.transition('is supported')) {
  3463. if(settings.opacity !== 'auto') {
  3464. module.set.opacity();
  3465. }
  3466. $dimmer
  3467. .transition({
  3468. animation : settings.transition + ' in',
  3469. queue : false,
  3470. duration : module.get.duration(),
  3471. useFailSafe : true,
  3472. onStart : function() {
  3473. module.set.dimmed();
  3474. },
  3475. onComplete : function() {
  3476. module.set.active();
  3477. callback();
  3478. }
  3479. })
  3480. ;
  3481. }
  3482. else {
  3483. module.verbose('Showing dimmer animation with javascript');
  3484. module.set.dimmed();
  3485. if(settings.opacity == 'auto') {
  3486. settings.opacity = 0.8;
  3487. }
  3488. $dimmer
  3489. .stop()
  3490. .css({
  3491. opacity : 0,
  3492. width : '100%',
  3493. height : '100%'
  3494. })
  3495. .fadeTo(module.get.duration(), settings.opacity, function() {
  3496. $dimmer.removeAttr('style');
  3497. module.set.active();
  3498. callback();
  3499. })
  3500. ;
  3501. }
  3502. },
  3503. hide: function(callback) {
  3504. callback = $.isFunction(callback)
  3505. ? callback
  3506. : function(){}
  3507. ;
  3508. if(settings.useCSS && $.fn.transition !== undefined && $dimmer.transition('is supported')) {
  3509. module.verbose('Hiding dimmer with css');
  3510. $dimmer
  3511. .transition({
  3512. animation : settings.transition + ' out',
  3513. queue : false,
  3514. duration : module.get.duration(),
  3515. useFailSafe : true,
  3516. onStart : function() {
  3517. module.remove.dimmed();
  3518. },
  3519. onComplete : function() {
  3520. module.remove.active();
  3521. callback();
  3522. }
  3523. })
  3524. ;
  3525. }
  3526. else {
  3527. module.verbose('Hiding dimmer with javascript');
  3528. module.remove.dimmed();
  3529. $dimmer
  3530. .stop()
  3531. .fadeOut(module.get.duration(), function() {
  3532. module.remove.active();
  3533. $dimmer.removeAttr('style');
  3534. callback();
  3535. })
  3536. ;
  3537. }
  3538. }
  3539. },
  3540. get: {
  3541. dimmer: function() {
  3542. return $dimmer;
  3543. },
  3544. duration: function() {
  3545. if(typeof settings.duration == 'object') {
  3546. if( module.is.active() ) {
  3547. return settings.duration.hide;
  3548. }
  3549. else {
  3550. return settings.duration.show;
  3551. }
  3552. }
  3553. return settings.duration;
  3554. }
  3555. },
  3556. has: {
  3557. dimmer: function() {
  3558. if(settings.dimmerName) {
  3559. return ($module.find(selector.dimmer).filter('.' + settings.dimmerName).length > 0);
  3560. }
  3561. else {
  3562. return ( $module.find(selector.dimmer).length > 0 );
  3563. }
  3564. }
  3565. },
  3566. is: {
  3567. active: function() {
  3568. return $dimmer.hasClass(className.active);
  3569. },
  3570. animating: function() {
  3571. return ( $dimmer.is(':animated') || $dimmer.hasClass(className.animating) );
  3572. },
  3573. closable: function() {
  3574. if(settings.closable == 'auto') {
  3575. if(settings.on == 'hover') {
  3576. return false;
  3577. }
  3578. return true;
  3579. }
  3580. return settings.closable;
  3581. },
  3582. dimmer: function() {
  3583. return $module.hasClass(className.dimmer);
  3584. },
  3585. dimmable: function() {
  3586. return $module.hasClass(className.dimmable);
  3587. },
  3588. dimmed: function() {
  3589. return $dimmable.hasClass(className.dimmed);
  3590. },
  3591. disabled: function() {
  3592. return $dimmable.hasClass(className.disabled);
  3593. },
  3594. enabled: function() {
  3595. return !module.is.disabled();
  3596. },
  3597. page: function () {
  3598. return $dimmable.is('body');
  3599. },
  3600. pageDimmer: function() {
  3601. return $dimmer.hasClass(className.pageDimmer);
  3602. }
  3603. },
  3604. can: {
  3605. show: function() {
  3606. return !$dimmer.hasClass(className.disabled);
  3607. }
  3608. },
  3609. set: {
  3610. opacity: function(opacity) {
  3611. var
  3612. color = $dimmer.css('background-color'),
  3613. colorArray = color.split(','),
  3614. isRGB = (colorArray && colorArray.length == 3),
  3615. isRGBA = (colorArray && colorArray.length == 4)
  3616. ;
  3617. opacity = settings.opacity === 0 ? 0 : settings.opacity || opacity;
  3618. if(isRGB || isRGBA) {
  3619. colorArray[3] = opacity + ')';
  3620. color = colorArray.join(',');
  3621. }
  3622. else {
  3623. color = 'rgba(0, 0, 0, ' + opacity + ')';
  3624. }
  3625. module.debug('Setting opacity to', opacity);
  3626. $dimmer.css('background-color', color);
  3627. },
  3628. active: function() {
  3629. $dimmer.addClass(className.active);
  3630. },
  3631. dimmable: function() {
  3632. $dimmable.addClass(className.dimmable);
  3633. },
  3634. dimmed: function() {
  3635. $dimmable.addClass(className.dimmed);
  3636. },
  3637. pageDimmer: function() {
  3638. $dimmer.addClass(className.pageDimmer);
  3639. },
  3640. disabled: function() {
  3641. $dimmer.addClass(className.disabled);
  3642. },
  3643. variation: function(variation) {
  3644. variation = variation || settings.variation;
  3645. if(variation) {
  3646. $dimmer.addClass(variation);
  3647. }
  3648. }
  3649. },
  3650. remove: {
  3651. active: function() {
  3652. $dimmer
  3653. .removeClass(className.active)
  3654. ;
  3655. },
  3656. dimmed: function() {
  3657. $dimmable.removeClass(className.dimmed);
  3658. },
  3659. disabled: function() {
  3660. $dimmer.removeClass(className.disabled);
  3661. },
  3662. variation: function(variation) {
  3663. variation = variation || settings.variation;
  3664. if(variation) {
  3665. $dimmer.removeClass(variation);
  3666. }
  3667. }
  3668. },
  3669. setting: function(name, value) {
  3670. module.debug('Changing setting', name, value);
  3671. if( $.isPlainObject(name) ) {
  3672. $.extend(true, settings, name);
  3673. }
  3674. else if(value !== undefined) {
  3675. if($.isPlainObject(settings[name])) {
  3676. $.extend(true, settings[name], value);
  3677. }
  3678. else {
  3679. settings[name] = value;
  3680. }
  3681. }
  3682. else {
  3683. return settings[name];
  3684. }
  3685. },
  3686. internal: function(name, value) {
  3687. if( $.isPlainObject(name) ) {
  3688. $.extend(true, module, name);
  3689. }
  3690. else if(value !== undefined) {
  3691. module[name] = value;
  3692. }
  3693. else {
  3694. return module[name];
  3695. }
  3696. },
  3697. debug: function() {
  3698. if(!settings.silent && settings.debug) {
  3699. if(settings.performance) {
  3700. module.performance.log(arguments);
  3701. }
  3702. else {
  3703. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  3704. module.debug.apply(console, arguments);
  3705. }
  3706. }
  3707. },
  3708. verbose: function() {
  3709. if(!settings.silent && settings.verbose && settings.debug) {
  3710. if(settings.performance) {
  3711. module.performance.log(arguments);
  3712. }
  3713. else {
  3714. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  3715. module.verbose.apply(console, arguments);
  3716. }
  3717. }
  3718. },
  3719. error: function() {
  3720. if(!settings.silent) {
  3721. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  3722. module.error.apply(console, arguments);
  3723. }
  3724. },
  3725. performance: {
  3726. log: function(message) {
  3727. var
  3728. currentTime,
  3729. executionTime,
  3730. previousTime
  3731. ;
  3732. if(settings.performance) {
  3733. currentTime = new Date().getTime();
  3734. previousTime = time || currentTime;
  3735. executionTime = currentTime - previousTime;
  3736. time = currentTime;
  3737. performance.push({
  3738. 'Name' : message[0],
  3739. 'Arguments' : [].slice.call(message, 1) || '',
  3740. 'Element' : element,
  3741. 'Execution Time' : executionTime
  3742. });
  3743. }
  3744. clearTimeout(module.performance.timer);
  3745. module.performance.timer = setTimeout(module.performance.display, 500);
  3746. },
  3747. display: function() {
  3748. var
  3749. title = settings.name + ':',
  3750. totalTime = 0
  3751. ;
  3752. time = false;
  3753. clearTimeout(module.performance.timer);
  3754. $.each(performance, function(index, data) {
  3755. totalTime += data['Execution Time'];
  3756. });
  3757. title += ' ' + totalTime + 'ms';
  3758. if(moduleSelector) {
  3759. title += ' \'' + moduleSelector + '\'';
  3760. }
  3761. if($allModules.length > 1) {
  3762. title += ' ' + '(' + $allModules.length + ')';
  3763. }
  3764. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  3765. console.groupCollapsed(title);
  3766. if(console.table) {
  3767. console.table(performance);
  3768. }
  3769. else {
  3770. $.each(performance, function(index, data) {
  3771. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  3772. });
  3773. }
  3774. console.groupEnd();
  3775. }
  3776. performance = [];
  3777. }
  3778. },
  3779. invoke: function(query, passedArguments, context) {
  3780. var
  3781. object = instance,
  3782. maxDepth,
  3783. found,
  3784. response
  3785. ;
  3786. passedArguments = passedArguments || queryArguments;
  3787. context = element || context;
  3788. if(typeof query == 'string' && object !== undefined) {
  3789. query = query.split(/[\. ]/);
  3790. maxDepth = query.length - 1;
  3791. $.each(query, function(depth, value) {
  3792. var camelCaseValue = (depth != maxDepth)
  3793. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  3794. : query
  3795. ;
  3796. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  3797. object = object[camelCaseValue];
  3798. }
  3799. else if( object[camelCaseValue] !== undefined ) {
  3800. found = object[camelCaseValue];
  3801. return false;
  3802. }
  3803. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  3804. object = object[value];
  3805. }
  3806. else if( object[value] !== undefined ) {
  3807. found = object[value];
  3808. return false;
  3809. }
  3810. else {
  3811. module.error(error.method, query);
  3812. return false;
  3813. }
  3814. });
  3815. }
  3816. if ( $.isFunction( found ) ) {
  3817. response = found.apply(context, passedArguments);
  3818. }
  3819. else if(found !== undefined) {
  3820. response = found;
  3821. }
  3822. if($.isArray(returnedValue)) {
  3823. returnedValue.push(response);
  3824. }
  3825. else if(returnedValue !== undefined) {
  3826. returnedValue = [returnedValue, response];
  3827. }
  3828. else if(response !== undefined) {
  3829. returnedValue = response;
  3830. }
  3831. return found;
  3832. }
  3833. };
  3834. module.preinitialize();
  3835. if(methodInvoked) {
  3836. if(instance === undefined) {
  3837. module.initialize();
  3838. }
  3839. module.invoke(query);
  3840. }
  3841. else {
  3842. if(instance !== undefined) {
  3843. instance.invoke('destroy');
  3844. }
  3845. module.initialize();
  3846. }
  3847. })
  3848. ;
  3849. return (returnedValue !== undefined)
  3850. ? returnedValue
  3851. : this
  3852. ;
  3853. };
  3854. $.fn.dimmer.settings = {
  3855. name : 'Dimmer',
  3856. namespace : 'dimmer',
  3857. silent : false,
  3858. debug : false,
  3859. verbose : false,
  3860. performance : true,
  3861. // name to distinguish between multiple dimmers in context
  3862. dimmerName : false,
  3863. // whether to add a variation type
  3864. variation : false,
  3865. // whether to bind close events
  3866. closable : 'auto',
  3867. // whether to use css animations
  3868. useCSS : true,
  3869. // css animation to use
  3870. transition : 'fade',
  3871. // event to bind to
  3872. on : false,
  3873. // overriding opacity value
  3874. opacity : 'auto',
  3875. // transition durations
  3876. duration : {
  3877. show : 500,
  3878. hide : 500
  3879. },
  3880. onChange : function(){},
  3881. onShow : function(){},
  3882. onHide : function(){},
  3883. error : {
  3884. method : 'The method you called is not defined.'
  3885. },
  3886. className : {
  3887. active : 'active',
  3888. animating : 'animating',
  3889. dimmable : 'dimmable',
  3890. dimmed : 'dimmed',
  3891. dimmer : 'dimmer',
  3892. disabled : 'disabled',
  3893. hide : 'hide',
  3894. pageDimmer : 'page',
  3895. show : 'show'
  3896. },
  3897. selector: {
  3898. dimmer : '> .ui.dimmer',
  3899. content : '.ui.dimmer > .content, .ui.dimmer > .content > .center'
  3900. },
  3901. template: {
  3902. dimmer: function() {
  3903. return $('<div />').attr('class', 'ui dimmer');
  3904. }
  3905. }
  3906. };
  3907. })( jQuery, window, document );
  3908. /*!
  3909. * # Semantic UI 2.2.6 - Dropdown
  3910. * http://github.com/semantic-org/semantic-ui/
  3911. *
  3912. *
  3913. * Released under the MIT license
  3914. * http://opensource.org/licenses/MIT
  3915. *
  3916. */
  3917. ;(function ($, window, document, undefined) {
  3918. "use strict";
  3919. window = (typeof window != 'undefined' && window.Math == Math)
  3920. ? window
  3921. : (typeof self != 'undefined' && self.Math == Math)
  3922. ? self
  3923. : Function('return this')()
  3924. ;
  3925. $.fn.dropdown = function(parameters) {
  3926. var
  3927. $allModules = $(this),
  3928. $document = $(document),
  3929. moduleSelector = $allModules.selector || '',
  3930. hasTouch = ('ontouchstart' in document.documentElement),
  3931. time = new Date().getTime(),
  3932. performance = [],
  3933. query = arguments[0],
  3934. methodInvoked = (typeof query == 'string'),
  3935. queryArguments = [].slice.call(arguments, 1),
  3936. returnedValue
  3937. ;
  3938. $allModules
  3939. .each(function(elementIndex) {
  3940. var
  3941. settings = ( $.isPlainObject(parameters) )
  3942. ? $.extend(true, {}, $.fn.dropdown.settings, parameters)
  3943. : $.extend({}, $.fn.dropdown.settings),
  3944. className = settings.className,
  3945. message = settings.message,
  3946. fields = settings.fields,
  3947. keys = settings.keys,
  3948. metadata = settings.metadata,
  3949. namespace = settings.namespace,
  3950. regExp = settings.regExp,
  3951. selector = settings.selector,
  3952. error = settings.error,
  3953. templates = settings.templates,
  3954. eventNamespace = '.' + namespace,
  3955. moduleNamespace = 'module-' + namespace,
  3956. $module = $(this),
  3957. $context = $(settings.context),
  3958. $text = $module.find(selector.text),
  3959. $search = $module.find(selector.search),
  3960. $sizer = $module.find(selector.sizer),
  3961. $input = $module.find(selector.input),
  3962. $icon = $module.find(selector.icon),
  3963. $combo = ($module.prev().find(selector.text).length > 0)
  3964. ? $module.prev().find(selector.text)
  3965. : $module.prev(),
  3966. $menu = $module.children(selector.menu),
  3967. $item = $menu.find(selector.item),
  3968. activated = false,
  3969. itemActivated = false,
  3970. internalChange = false,
  3971. element = this,
  3972. instance = $module.data(moduleNamespace),
  3973. initialLoad,
  3974. pageLostFocus,
  3975. willRefocus,
  3976. elementNamespace,
  3977. id,
  3978. selectObserver,
  3979. menuObserver,
  3980. module
  3981. ;
  3982. module = {
  3983. initialize: function() {
  3984. module.debug('Initializing dropdown', settings);
  3985. if( module.is.alreadySetup() ) {
  3986. module.setup.reference();
  3987. }
  3988. else {
  3989. module.setup.layout();
  3990. module.refreshData();
  3991. module.save.defaults();
  3992. module.restore.selected();
  3993. module.create.id();
  3994. module.bind.events();
  3995. module.observeChanges();
  3996. module.instantiate();
  3997. }
  3998. },
  3999. instantiate: function() {
  4000. module.verbose('Storing instance of dropdown', module);
  4001. instance = module;
  4002. $module
  4003. .data(moduleNamespace, module)
  4004. ;
  4005. },
  4006. destroy: function() {
  4007. module.verbose('Destroying previous dropdown', $module);
  4008. module.remove.tabbable();
  4009. $module
  4010. .off(eventNamespace)
  4011. .removeData(moduleNamespace)
  4012. ;
  4013. $menu
  4014. .off(eventNamespace)
  4015. ;
  4016. $document
  4017. .off(elementNamespace)
  4018. ;
  4019. module.disconnect.menuObserver();
  4020. module.disconnect.selectObserver();
  4021. },
  4022. observeChanges: function() {
  4023. if('MutationObserver' in window) {
  4024. selectObserver = new MutationObserver(module.event.select.mutation);
  4025. menuObserver = new MutationObserver(module.event.menu.mutation);
  4026. module.debug('Setting up mutation observer', selectObserver, menuObserver);
  4027. module.observe.select();
  4028. module.observe.menu();
  4029. }
  4030. },
  4031. disconnect: {
  4032. menuObserver: function() {
  4033. if(menuObserver) {
  4034. menuObserver.disconnect();
  4035. }
  4036. },
  4037. selectObserver: function() {
  4038. if(selectObserver) {
  4039. selectObserver.disconnect();
  4040. }
  4041. }
  4042. },
  4043. observe: {
  4044. select: function() {
  4045. if(module.has.input()) {
  4046. selectObserver.observe($input[0], {
  4047. childList : true,
  4048. subtree : true
  4049. });
  4050. }
  4051. },
  4052. menu: function() {
  4053. if(module.has.menu()) {
  4054. menuObserver.observe($menu[0], {
  4055. childList : true,
  4056. subtree : true
  4057. });
  4058. }
  4059. }
  4060. },
  4061. create: {
  4062. id: function() {
  4063. id = (Math.random().toString(16) + '000000000').substr(2, 8);
  4064. elementNamespace = '.' + id;
  4065. module.verbose('Creating unique id for element', id);
  4066. },
  4067. userChoice: function(values) {
  4068. var
  4069. $userChoices,
  4070. $userChoice,
  4071. isUserValue,
  4072. html
  4073. ;
  4074. values = values || module.get.userValues();
  4075. if(!values) {
  4076. return false;
  4077. }
  4078. values = $.isArray(values)
  4079. ? values
  4080. : [values]
  4081. ;
  4082. $.each(values, function(index, value) {
  4083. if(module.get.item(value) === false) {
  4084. html = settings.templates.addition( module.add.variables(message.addResult, value) );
  4085. $userChoice = $('<div />')
  4086. .html(html)
  4087. .attr('data-' + metadata.value, value)
  4088. .attr('data-' + metadata.text, value)
  4089. .addClass(className.addition)
  4090. .addClass(className.item)
  4091. ;
  4092. if(settings.hideAdditions) {
  4093. $userChoice.addClass(className.hidden);
  4094. }
  4095. $userChoices = ($userChoices === undefined)
  4096. ? $userChoice
  4097. : $userChoices.add($userChoice)
  4098. ;
  4099. module.verbose('Creating user choices for value', value, $userChoice);
  4100. }
  4101. });
  4102. return $userChoices;
  4103. },
  4104. userLabels: function(value) {
  4105. var
  4106. userValues = module.get.userValues()
  4107. ;
  4108. if(userValues) {
  4109. module.debug('Adding user labels', userValues);
  4110. $.each(userValues, function(index, value) {
  4111. module.verbose('Adding custom user value');
  4112. module.add.label(value, value);
  4113. });
  4114. }
  4115. },
  4116. menu: function() {
  4117. $menu = $('<div />')
  4118. .addClass(className.menu)
  4119. .appendTo($module)
  4120. ;
  4121. },
  4122. sizer: function() {
  4123. $sizer = $('<span />')
  4124. .addClass(className.sizer)
  4125. .insertAfter($search)
  4126. ;
  4127. }
  4128. },
  4129. search: function(query) {
  4130. query = (query !== undefined)
  4131. ? query
  4132. : module.get.query()
  4133. ;
  4134. module.verbose('Searching for query', query);
  4135. if(module.has.minCharacters(query)) {
  4136. module.filter(query);
  4137. }
  4138. else {
  4139. module.hide();
  4140. }
  4141. },
  4142. select: {
  4143. firstUnfiltered: function() {
  4144. module.verbose('Selecting first non-filtered element');
  4145. module.remove.selectedItem();
  4146. $item
  4147. .not(selector.unselectable)
  4148. .not(selector.addition + selector.hidden)
  4149. .eq(0)
  4150. .addClass(className.selected)
  4151. ;
  4152. },
  4153. nextAvailable: function($selected) {
  4154. $selected = $selected.eq(0);
  4155. var
  4156. $nextAvailable = $selected.nextAll(selector.item).not(selector.unselectable).eq(0),
  4157. $prevAvailable = $selected.prevAll(selector.item).not(selector.unselectable).eq(0),
  4158. hasNext = ($nextAvailable.length > 0)
  4159. ;
  4160. if(hasNext) {
  4161. module.verbose('Moving selection to', $nextAvailable);
  4162. $nextAvailable.addClass(className.selected);
  4163. }
  4164. else {
  4165. module.verbose('Moving selection to', $prevAvailable);
  4166. $prevAvailable.addClass(className.selected);
  4167. }
  4168. }
  4169. },
  4170. setup: {
  4171. api: function() {
  4172. var
  4173. apiSettings = {
  4174. debug : settings.debug,
  4175. urlData : {
  4176. value : module.get.value(),
  4177. query : module.get.query()
  4178. },
  4179. on : false
  4180. }
  4181. ;
  4182. module.verbose('First request, initializing API');
  4183. $module
  4184. .api(apiSettings)
  4185. ;
  4186. },
  4187. layout: function() {
  4188. if( $module.is('select') ) {
  4189. module.setup.select();
  4190. module.setup.returnedObject();
  4191. }
  4192. if( !module.has.menu() ) {
  4193. module.create.menu();
  4194. }
  4195. if( module.is.search() && !module.has.search() ) {
  4196. module.verbose('Adding search input');
  4197. $search = $('<input />')
  4198. .addClass(className.search)
  4199. .prop('autocomplete', 'off')
  4200. .insertBefore($text)
  4201. ;
  4202. }
  4203. if( module.is.multiple() && module.is.searchSelection() && !module.has.sizer()) {
  4204. module.create.sizer();
  4205. }
  4206. if(settings.allowTab) {
  4207. module.set.tabbable();
  4208. }
  4209. },
  4210. select: function() {
  4211. var
  4212. selectValues = module.get.selectValues()
  4213. ;
  4214. module.debug('Dropdown initialized on a select', selectValues);
  4215. if( $module.is('select') ) {
  4216. $input = $module;
  4217. }
  4218. // see if select is placed correctly already
  4219. if($input.parent(selector.dropdown).length > 0) {
  4220. module.debug('UI dropdown already exists. Creating dropdown menu only');
  4221. $module = $input.closest(selector.dropdown);
  4222. if( !module.has.menu() ) {
  4223. module.create.menu();
  4224. }
  4225. $menu = $module.children(selector.menu);
  4226. module.setup.menu(selectValues);
  4227. }
  4228. else {
  4229. module.debug('Creating entire dropdown from select');
  4230. $module = $('<div />')
  4231. .attr('class', $input.attr('class') )
  4232. .addClass(className.selection)
  4233. .addClass(className.dropdown)
  4234. .html( templates.dropdown(selectValues) )
  4235. .insertBefore($input)
  4236. ;
  4237. if($input.hasClass(className.multiple) && $input.prop('multiple') === false) {
  4238. module.error(error.missingMultiple);
  4239. $input.prop('multiple', true);
  4240. }
  4241. if($input.is('[multiple]')) {
  4242. module.set.multiple();
  4243. }
  4244. if ($input.prop('disabled')) {
  4245. module.debug('Disabling dropdown');
  4246. $module.addClass(className.disabled);
  4247. }
  4248. $input
  4249. .removeAttr('class')
  4250. .detach()
  4251. .prependTo($module)
  4252. ;
  4253. }
  4254. module.refresh();
  4255. },
  4256. menu: function(values) {
  4257. $menu.html( templates.menu(values, fields));
  4258. $item = $menu.find(selector.item);
  4259. },
  4260. reference: function() {
  4261. module.debug('Dropdown behavior was called on select, replacing with closest dropdown');
  4262. // replace module reference
  4263. $module = $module.parent(selector.dropdown);
  4264. module.refresh();
  4265. module.setup.returnedObject();
  4266. // invoke method in context of current instance
  4267. if(methodInvoked) {
  4268. instance = module;
  4269. module.invoke(query);
  4270. }
  4271. },
  4272. returnedObject: function() {
  4273. var
  4274. $firstModules = $allModules.slice(0, elementIndex),
  4275. $lastModules = $allModules.slice(elementIndex + 1)
  4276. ;
  4277. // adjust all modules to use correct reference
  4278. $allModules = $firstModules.add($module).add($lastModules);
  4279. }
  4280. },
  4281. refresh: function() {
  4282. module.refreshSelectors();
  4283. module.refreshData();
  4284. },
  4285. refreshItems: function() {
  4286. $item = $menu.find(selector.item);
  4287. },
  4288. refreshSelectors: function() {
  4289. module.verbose('Refreshing selector cache');
  4290. $text = $module.find(selector.text);
  4291. $search = $module.find(selector.search);
  4292. $input = $module.find(selector.input);
  4293. $icon = $module.find(selector.icon);
  4294. $combo = ($module.prev().find(selector.text).length > 0)
  4295. ? $module.prev().find(selector.text)
  4296. : $module.prev()
  4297. ;
  4298. $menu = $module.children(selector.menu);
  4299. $item = $menu.find(selector.item);
  4300. },
  4301. refreshData: function() {
  4302. module.verbose('Refreshing cached metadata');
  4303. $item
  4304. .removeData(metadata.text)
  4305. .removeData(metadata.value)
  4306. ;
  4307. },
  4308. clearData: function() {
  4309. module.verbose('Clearing metadata');
  4310. $item
  4311. .removeData(metadata.text)
  4312. .removeData(metadata.value)
  4313. ;
  4314. $module
  4315. .removeData(metadata.defaultText)
  4316. .removeData(metadata.defaultValue)
  4317. .removeData(metadata.placeholderText)
  4318. ;
  4319. },
  4320. toggle: function() {
  4321. module.verbose('Toggling menu visibility');
  4322. if( !module.is.active() ) {
  4323. module.show();
  4324. }
  4325. else {
  4326. module.hide();
  4327. }
  4328. },
  4329. show: function(callback) {
  4330. callback = $.isFunction(callback)
  4331. ? callback
  4332. : function(){}
  4333. ;
  4334. if( module.can.show() && !module.is.active() ) {
  4335. module.debug('Showing dropdown');
  4336. if(module.has.message() && !(module.has.maxSelections() || module.has.allResultsFiltered()) ) {
  4337. module.remove.message();
  4338. }
  4339. if(module.is.allFiltered()) {
  4340. return true;
  4341. }
  4342. if(settings.onShow.call(element) !== false) {
  4343. module.animate.show(function() {
  4344. if( module.can.click() ) {
  4345. module.bind.intent();
  4346. }
  4347. if(module.has.menuSearch()) {
  4348. module.focusSearch();
  4349. }
  4350. module.set.visible();
  4351. callback.call(element);
  4352. });
  4353. }
  4354. }
  4355. },
  4356. hide: function(callback) {
  4357. callback = $.isFunction(callback)
  4358. ? callback
  4359. : function(){}
  4360. ;
  4361. if( module.is.active() ) {
  4362. module.debug('Hiding dropdown');
  4363. if(settings.onHide.call(element) !== false) {
  4364. module.animate.hide(function() {
  4365. module.remove.visible();
  4366. callback.call(element);
  4367. });
  4368. }
  4369. }
  4370. },
  4371. hideOthers: function() {
  4372. module.verbose('Finding other dropdowns to hide');
  4373. $allModules
  4374. .not($module)
  4375. .has(selector.menu + '.' + className.visible)
  4376. .dropdown('hide')
  4377. ;
  4378. },
  4379. hideMenu: function() {
  4380. module.verbose('Hiding menu instantaneously');
  4381. module.remove.active();
  4382. module.remove.visible();
  4383. $menu.transition('hide');
  4384. },
  4385. hideSubMenus: function() {
  4386. var
  4387. $subMenus = $menu.children(selector.item).find(selector.menu)
  4388. ;
  4389. module.verbose('Hiding sub menus', $subMenus);
  4390. $subMenus.transition('hide');
  4391. },
  4392. bind: {
  4393. events: function() {
  4394. if(hasTouch) {
  4395. module.bind.touchEvents();
  4396. }
  4397. module.bind.keyboardEvents();
  4398. module.bind.inputEvents();
  4399. module.bind.mouseEvents();
  4400. },
  4401. touchEvents: function() {
  4402. module.debug('Touch device detected binding additional touch events');
  4403. if( module.is.searchSelection() ) {
  4404. // do nothing special yet
  4405. }
  4406. else if( module.is.single() ) {
  4407. $module
  4408. .on('touchstart' + eventNamespace, module.event.test.toggle)
  4409. ;
  4410. }
  4411. $menu
  4412. .on('touchstart' + eventNamespace, selector.item, module.event.item.mouseenter)
  4413. ;
  4414. },
  4415. keyboardEvents: function() {
  4416. module.verbose('Binding keyboard events');
  4417. $module
  4418. .on('keydown' + eventNamespace, module.event.keydown)
  4419. ;
  4420. if( module.has.search() ) {
  4421. $module
  4422. .on(module.get.inputEvent() + eventNamespace, selector.search, module.event.input)
  4423. ;
  4424. }
  4425. if( module.is.multiple() ) {
  4426. $document
  4427. .on('keydown' + elementNamespace, module.event.document.keydown)
  4428. ;
  4429. }
  4430. },
  4431. inputEvents: function() {
  4432. module.verbose('Binding input change events');
  4433. $module
  4434. .on('change' + eventNamespace, selector.input, module.event.change)
  4435. ;
  4436. },
  4437. mouseEvents: function() {
  4438. module.verbose('Binding mouse events');
  4439. if(module.is.multiple()) {
  4440. $module
  4441. .on('click' + eventNamespace, selector.label, module.event.label.click)
  4442. .on('click' + eventNamespace, selector.remove, module.event.remove.click)
  4443. ;
  4444. }
  4445. if( module.is.searchSelection() ) {
  4446. $module
  4447. .on('mousedown' + eventNamespace, module.event.mousedown)
  4448. .on('mouseup' + eventNamespace, module.event.mouseup)
  4449. .on('mousedown' + eventNamespace, selector.menu, module.event.menu.mousedown)
  4450. .on('mouseup' + eventNamespace, selector.menu, module.event.menu.mouseup)
  4451. .on('click' + eventNamespace, selector.icon, module.event.icon.click)
  4452. .on('focus' + eventNamespace, selector.search, module.event.search.focus)
  4453. .on('click' + eventNamespace, selector.search, module.event.search.focus)
  4454. .on('blur' + eventNamespace, selector.search, module.event.search.blur)
  4455. .on('click' + eventNamespace, selector.text, module.event.text.focus)
  4456. ;
  4457. if(module.is.multiple()) {
  4458. $module
  4459. .on('click' + eventNamespace, module.event.click)
  4460. ;
  4461. }
  4462. }
  4463. else {
  4464. if(settings.on == 'click') {
  4465. $module
  4466. .on('click' + eventNamespace, selector.icon, module.event.icon.click)
  4467. .on('click' + eventNamespace, module.event.test.toggle)
  4468. ;
  4469. }
  4470. else if(settings.on == 'hover') {
  4471. $module
  4472. .on('mouseenter' + eventNamespace, module.delay.show)
  4473. .on('mouseleave' + eventNamespace, module.delay.hide)
  4474. ;
  4475. }
  4476. else {
  4477. $module
  4478. .on(settings.on + eventNamespace, module.toggle)
  4479. ;
  4480. }
  4481. $module
  4482. .on('mousedown' + eventNamespace, module.event.mousedown)
  4483. .on('mouseup' + eventNamespace, module.event.mouseup)
  4484. .on('focus' + eventNamespace, module.event.focus)
  4485. .on('blur' + eventNamespace, module.event.blur)
  4486. ;
  4487. }
  4488. $menu
  4489. .on('mouseenter' + eventNamespace, selector.item, module.event.item.mouseenter)
  4490. .on('mouseleave' + eventNamespace, selector.item, module.event.item.mouseleave)
  4491. .on('click' + eventNamespace, selector.item, module.event.item.click)
  4492. ;
  4493. },
  4494. intent: function() {
  4495. module.verbose('Binding hide intent event to document');
  4496. if(hasTouch) {
  4497. $document
  4498. .on('touchstart' + elementNamespace, module.event.test.touch)
  4499. .on('touchmove' + elementNamespace, module.event.test.touch)
  4500. ;
  4501. }
  4502. $document
  4503. .on('click' + elementNamespace, module.event.test.hide)
  4504. ;
  4505. }
  4506. },
  4507. unbind: {
  4508. intent: function() {
  4509. module.verbose('Removing hide intent event from document');
  4510. if(hasTouch) {
  4511. $document
  4512. .off('touchstart' + elementNamespace)
  4513. .off('touchmove' + elementNamespace)
  4514. ;
  4515. }
  4516. $document
  4517. .off('click' + elementNamespace)
  4518. ;
  4519. }
  4520. },
  4521. filter: function(query) {
  4522. var
  4523. searchTerm = (query !== undefined)
  4524. ? query
  4525. : module.get.query(),
  4526. afterFiltered = function() {
  4527. if(module.is.multiple()) {
  4528. module.filterActive();
  4529. }
  4530. module.select.firstUnfiltered();
  4531. if( module.has.allResultsFiltered() ) {
  4532. if( settings.onNoResults.call(element, searchTerm) ) {
  4533. if(settings.allowAdditions) {
  4534. if(settings.hideAdditions) {
  4535. module.verbose('User addition with no menu, setting empty style');
  4536. module.set.empty();
  4537. module.hideMenu();
  4538. }
  4539. }
  4540. else {
  4541. module.verbose('All items filtered, showing message', searchTerm);
  4542. module.add.message(message.noResults);
  4543. }
  4544. }
  4545. else {
  4546. module.verbose('All items filtered, hiding dropdown', searchTerm);
  4547. module.hideMenu();
  4548. }
  4549. }
  4550. else {
  4551. module.remove.empty();
  4552. module.remove.message();
  4553. }
  4554. if(settings.allowAdditions) {
  4555. module.add.userSuggestion(query);
  4556. }
  4557. if(module.is.searchSelection() && module.can.show() && module.is.focusedOnSearch() ) {
  4558. module.show();
  4559. }
  4560. }
  4561. ;
  4562. if(settings.useLabels && module.has.maxSelections()) {
  4563. return;
  4564. }
  4565. if(settings.apiSettings) {
  4566. if( module.can.useAPI() ) {
  4567. module.queryRemote(searchTerm, function() {
  4568. afterFiltered();
  4569. });
  4570. }
  4571. else {
  4572. module.error(error.noAPI);
  4573. }
  4574. }
  4575. else {
  4576. module.filterItems(searchTerm);
  4577. afterFiltered();
  4578. }
  4579. },
  4580. queryRemote: function(query, callback) {
  4581. var
  4582. apiSettings = {
  4583. errorDuration : false,
  4584. cache : 'local',
  4585. throttle : settings.throttle,
  4586. urlData : {
  4587. query: query
  4588. },
  4589. onError: function() {
  4590. module.add.message(message.serverError);
  4591. callback();
  4592. },
  4593. onFailure: function() {
  4594. module.add.message(message.serverError);
  4595. callback();
  4596. },
  4597. onSuccess : function(response) {
  4598. module.remove.message();
  4599. module.setup.menu({
  4600. values: response[fields.remoteValues]
  4601. });
  4602. callback();
  4603. }
  4604. }
  4605. ;
  4606. if( !$module.api('get request') ) {
  4607. module.setup.api();
  4608. }
  4609. apiSettings = $.extend(true, {}, apiSettings, settings.apiSettings);
  4610. $module
  4611. .api('setting', apiSettings)
  4612. .api('query')
  4613. ;
  4614. },
  4615. filterItems: function(query) {
  4616. var
  4617. searchTerm = (query !== undefined)
  4618. ? query
  4619. : module.get.query(),
  4620. results = null,
  4621. escapedTerm = module.escape.regExp(searchTerm),
  4622. beginsWithRegExp = new RegExp('^' + escapedTerm, 'igm')
  4623. ;
  4624. // avoid loop if we're matching nothing
  4625. if( module.has.query() ) {
  4626. results = [];
  4627. module.verbose('Searching for matching values', searchTerm);
  4628. $item
  4629. .each(function(){
  4630. var
  4631. $choice = $(this),
  4632. text,
  4633. value
  4634. ;
  4635. if(settings.match == 'both' || settings.match == 'text') {
  4636. text = String(module.get.choiceText($choice, false));
  4637. if(text.search(beginsWithRegExp) !== -1) {
  4638. results.push(this);
  4639. return true;
  4640. }
  4641. else if (settings.fullTextSearch === 'exact' && module.exactSearch(searchTerm, text)) {
  4642. results.push(this);
  4643. return true;
  4644. }
  4645. else if (settings.fullTextSearch === true && module.fuzzySearch(searchTerm, text)) {
  4646. results.push(this);
  4647. return true;
  4648. }
  4649. }
  4650. if(settings.match == 'both' || settings.match == 'value') {
  4651. value = String(module.get.choiceValue($choice, text));
  4652. if(value.search(beginsWithRegExp) !== -1) {
  4653. results.push(this);
  4654. return true;
  4655. }
  4656. else if(settings.fullTextSearch && module.fuzzySearch(searchTerm, value)) {
  4657. results.push(this);
  4658. return true;
  4659. }
  4660. }
  4661. })
  4662. ;
  4663. }
  4664. module.debug('Showing only matched items', searchTerm);
  4665. module.remove.filteredItem();
  4666. if(results) {
  4667. $item
  4668. .not(results)
  4669. .addClass(className.filtered)
  4670. ;
  4671. }
  4672. },
  4673. fuzzySearch: function(query, term) {
  4674. var
  4675. termLength = term.length,
  4676. queryLength = query.length
  4677. ;
  4678. query = query.toLowerCase();
  4679. term = term.toLowerCase();
  4680. if(queryLength > termLength) {
  4681. return false;
  4682. }
  4683. if(queryLength === termLength) {
  4684. return (query === term);
  4685. }
  4686. search: for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
  4687. var
  4688. queryCharacter = query.charCodeAt(characterIndex)
  4689. ;
  4690. while(nextCharacterIndex < termLength) {
  4691. if(term.charCodeAt(nextCharacterIndex++) === queryCharacter) {
  4692. continue search;
  4693. }
  4694. }
  4695. return false;
  4696. }
  4697. return true;
  4698. },
  4699. exactSearch: function (query, term) {
  4700. query = query.toLowerCase();
  4701. term = term.toLowerCase();
  4702. if(term.indexOf(query) > -1) {
  4703. return true;
  4704. }
  4705. return false;
  4706. },
  4707. filterActive: function() {
  4708. if(settings.useLabels) {
  4709. $item.filter('.' + className.active)
  4710. .addClass(className.filtered)
  4711. ;
  4712. }
  4713. },
  4714. focusSearch: function(skipHandler) {
  4715. if( module.has.search() && !module.is.focusedOnSearch() ) {
  4716. if(skipHandler) {
  4717. $module.off('focus' + eventNamespace, selector.search);
  4718. $search.focus();
  4719. $module.on('focus' + eventNamespace, selector.search, module.event.search.focus);
  4720. }
  4721. else {
  4722. $search.focus();
  4723. }
  4724. }
  4725. },
  4726. forceSelection: function() {
  4727. var
  4728. $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0),
  4729. $activeItem = $item.not(className.filtered).filter('.' + className.active).eq(0),
  4730. $selectedItem = ($currentlySelected.length > 0)
  4731. ? $currentlySelected
  4732. : $activeItem,
  4733. hasSelected = ($selectedItem.length > 0)
  4734. ;
  4735. if(hasSelected) {
  4736. module.debug('Forcing partial selection to selected item', $selectedItem);
  4737. module.event.item.click.call($selectedItem, {}, true);
  4738. return;
  4739. }
  4740. else {
  4741. if(settings.allowAdditions) {
  4742. module.set.selected(module.get.query());
  4743. module.remove.searchTerm();
  4744. }
  4745. else {
  4746. module.remove.searchTerm();
  4747. }
  4748. }
  4749. },
  4750. event: {
  4751. change: function() {
  4752. if(!internalChange) {
  4753. module.debug('Input changed, updating selection');
  4754. module.set.selected();
  4755. }
  4756. },
  4757. focus: function() {
  4758. if(settings.showOnFocus && !activated && module.is.hidden() && !pageLostFocus) {
  4759. module.show();
  4760. }
  4761. },
  4762. blur: function(event) {
  4763. pageLostFocus = (document.activeElement === this);
  4764. if(!activated && !pageLostFocus) {
  4765. module.remove.activeLabel();
  4766. module.hide();
  4767. }
  4768. },
  4769. mousedown: function() {
  4770. if(module.is.searchSelection()) {
  4771. // prevent menu hiding on immediate re-focus
  4772. willRefocus = true;
  4773. }
  4774. else {
  4775. // prevents focus callback from occurring on mousedown
  4776. activated = true;
  4777. }
  4778. },
  4779. mouseup: function() {
  4780. if(module.is.searchSelection()) {
  4781. // prevent menu hiding on immediate re-focus
  4782. willRefocus = false;
  4783. }
  4784. else {
  4785. activated = false;
  4786. }
  4787. },
  4788. click: function(event) {
  4789. var
  4790. $target = $(event.target)
  4791. ;
  4792. // focus search
  4793. if($target.is($module)) {
  4794. if(!module.is.focusedOnSearch()) {
  4795. module.focusSearch();
  4796. }
  4797. else {
  4798. module.show();
  4799. }
  4800. }
  4801. },
  4802. search: {
  4803. focus: function() {
  4804. activated = true;
  4805. if(module.is.multiple()) {
  4806. module.remove.activeLabel();
  4807. }
  4808. if(settings.showOnFocus) {
  4809. module.search();
  4810. }
  4811. },
  4812. blur: function(event) {
  4813. pageLostFocus = (document.activeElement === this);
  4814. if(!willRefocus) {
  4815. if(!itemActivated && !pageLostFocus) {
  4816. if(settings.forceSelection) {
  4817. module.forceSelection();
  4818. }
  4819. module.hide();
  4820. }
  4821. }
  4822. willRefocus = false;
  4823. }
  4824. },
  4825. icon: {
  4826. click: function(event) {
  4827. module.toggle();
  4828. }
  4829. },
  4830. text: {
  4831. focus: function(event) {
  4832. activated = true;
  4833. module.focusSearch();
  4834. }
  4835. },
  4836. input: function(event) {
  4837. if(module.is.multiple() || module.is.searchSelection()) {
  4838. module.set.filtered();
  4839. }
  4840. clearTimeout(module.timer);
  4841. module.timer = setTimeout(module.search, settings.delay.search);
  4842. },
  4843. label: {
  4844. click: function(event) {
  4845. var
  4846. $label = $(this),
  4847. $labels = $module.find(selector.label),
  4848. $activeLabels = $labels.filter('.' + className.active),
  4849. $nextActive = $label.nextAll('.' + className.active),
  4850. $prevActive = $label.prevAll('.' + className.active),
  4851. $range = ($nextActive.length > 0)
  4852. ? $label.nextUntil($nextActive).add($activeLabels).add($label)
  4853. : $label.prevUntil($prevActive).add($activeLabels).add($label)
  4854. ;
  4855. if(event.shiftKey) {
  4856. $activeLabels.removeClass(className.active);
  4857. $range.addClass(className.active);
  4858. }
  4859. else if(event.ctrlKey) {
  4860. $label.toggleClass(className.active);
  4861. }
  4862. else {
  4863. $activeLabels.removeClass(className.active);
  4864. $label.addClass(className.active);
  4865. }
  4866. settings.onLabelSelect.apply(this, $labels.filter('.' + className.active));
  4867. }
  4868. },
  4869. remove: {
  4870. click: function() {
  4871. var
  4872. $label = $(this).parent()
  4873. ;
  4874. if( $label.hasClass(className.active) ) {
  4875. // remove all selected labels
  4876. module.remove.activeLabels();
  4877. }
  4878. else {
  4879. // remove this label only
  4880. module.remove.activeLabels( $label );
  4881. }
  4882. }
  4883. },
  4884. test: {
  4885. toggle: function(event) {
  4886. var
  4887. toggleBehavior = (module.is.multiple())
  4888. ? module.show
  4889. : module.toggle
  4890. ;
  4891. if(module.is.bubbledLabelClick(event) || module.is.bubbledIconClick(event)) {
  4892. return;
  4893. }
  4894. if( module.determine.eventOnElement(event, toggleBehavior) ) {
  4895. event.preventDefault();
  4896. }
  4897. },
  4898. touch: function(event) {
  4899. module.determine.eventOnElement(event, function() {
  4900. if(event.type == 'touchstart') {
  4901. module.timer = setTimeout(function() {
  4902. module.hide();
  4903. }, settings.delay.touch);
  4904. }
  4905. else if(event.type == 'touchmove') {
  4906. clearTimeout(module.timer);
  4907. }
  4908. });
  4909. event.stopPropagation();
  4910. },
  4911. hide: function(event) {
  4912. module.determine.eventInModule(event, module.hide);
  4913. }
  4914. },
  4915. select: {
  4916. mutation: function(mutations) {
  4917. module.debug('<select> modified, recreating menu');
  4918. module.setup.select();
  4919. }
  4920. },
  4921. menu: {
  4922. mutation: function(mutations) {
  4923. var
  4924. mutation = mutations[0],
  4925. $addedNode = mutation.addedNodes
  4926. ? $(mutation.addedNodes[0])
  4927. : $(false),
  4928. $removedNode = mutation.removedNodes
  4929. ? $(mutation.removedNodes[0])
  4930. : $(false),
  4931. $changedNodes = $addedNode.add($removedNode),
  4932. isUserAddition = $changedNodes.is(selector.addition) || $changedNodes.closest(selector.addition).length > 0,
  4933. isMessage = $changedNodes.is(selector.message) || $changedNodes.closest(selector.message).length > 0
  4934. ;
  4935. if(isUserAddition || isMessage) {
  4936. module.debug('Updating item selector cache');
  4937. module.refreshItems();
  4938. }
  4939. else {
  4940. module.debug('Menu modified, updating selector cache');
  4941. module.refresh();
  4942. }
  4943. },
  4944. mousedown: function() {
  4945. itemActivated = true;
  4946. },
  4947. mouseup: function() {
  4948. itemActivated = false;
  4949. }
  4950. },
  4951. item: {
  4952. mouseenter: function(event) {
  4953. var
  4954. $target = $(event.target),
  4955. $item = $(this),
  4956. $subMenu = $item.children(selector.menu),
  4957. $otherMenus = $item.siblings(selector.item).children(selector.menu),
  4958. hasSubMenu = ($subMenu.length > 0),
  4959. isBubbledEvent = ($subMenu.find($target).length > 0)
  4960. ;
  4961. if( !isBubbledEvent && hasSubMenu ) {
  4962. clearTimeout(module.itemTimer);
  4963. module.itemTimer = setTimeout(function() {
  4964. module.verbose('Showing sub-menu', $subMenu);
  4965. $.each($otherMenus, function() {
  4966. module.animate.hide(false, $(this));
  4967. });
  4968. module.animate.show(false, $subMenu);
  4969. }, settings.delay.show);
  4970. event.preventDefault();
  4971. }
  4972. },
  4973. mouseleave: function(event) {
  4974. var
  4975. $subMenu = $(this).children(selector.menu)
  4976. ;
  4977. if($subMenu.length > 0) {
  4978. clearTimeout(module.itemTimer);
  4979. module.itemTimer = setTimeout(function() {
  4980. module.verbose('Hiding sub-menu', $subMenu);
  4981. module.animate.hide(false, $subMenu);
  4982. }, settings.delay.hide);
  4983. }
  4984. },
  4985. click: function (event, skipRefocus) {
  4986. var
  4987. $choice = $(this),
  4988. $target = (event)
  4989. ? $(event.target)
  4990. : $(''),
  4991. $subMenu = $choice.find(selector.menu),
  4992. text = module.get.choiceText($choice),
  4993. value = module.get.choiceValue($choice, text),
  4994. hasSubMenu = ($subMenu.length > 0),
  4995. isBubbledEvent = ($subMenu.find($target).length > 0)
  4996. ;
  4997. if(!isBubbledEvent && (!hasSubMenu || settings.allowCategorySelection)) {
  4998. if(module.is.searchSelection()) {
  4999. if(settings.allowAdditions) {
  5000. module.remove.userAddition();
  5001. }
  5002. module.remove.searchTerm();
  5003. if(!module.is.focusedOnSearch() && !(skipRefocus == true)) {
  5004. module.focusSearch(true);
  5005. }
  5006. }
  5007. if(!settings.useLabels) {
  5008. module.remove.filteredItem();
  5009. module.set.scrollPosition($choice);
  5010. }
  5011. module.determine.selectAction.call(this, text, value);
  5012. }
  5013. }
  5014. },
  5015. document: {
  5016. // label selection should occur even when element has no focus
  5017. keydown: function(event) {
  5018. var
  5019. pressedKey = event.which,
  5020. isShortcutKey = module.is.inObject(pressedKey, keys)
  5021. ;
  5022. if(isShortcutKey) {
  5023. var
  5024. $label = $module.find(selector.label),
  5025. $activeLabel = $label.filter('.' + className.active),
  5026. activeValue = $activeLabel.data(metadata.value),
  5027. labelIndex = $label.index($activeLabel),
  5028. labelCount = $label.length,
  5029. hasActiveLabel = ($activeLabel.length > 0),
  5030. hasMultipleActive = ($activeLabel.length > 1),
  5031. isFirstLabel = (labelIndex === 0),
  5032. isLastLabel = (labelIndex + 1 == labelCount),
  5033. isSearch = module.is.searchSelection(),
  5034. isFocusedOnSearch = module.is.focusedOnSearch(),
  5035. isFocused = module.is.focused(),
  5036. caretAtStart = (isFocusedOnSearch && module.get.caretPosition() === 0),
  5037. $nextLabel
  5038. ;
  5039. if(isSearch && !hasActiveLabel && !isFocusedOnSearch) {
  5040. return;
  5041. }
  5042. if(pressedKey == keys.leftArrow) {
  5043. // activate previous label
  5044. if((isFocused || caretAtStart) && !hasActiveLabel) {
  5045. module.verbose('Selecting previous label');
  5046. $label.last().addClass(className.active);
  5047. }
  5048. else if(hasActiveLabel) {
  5049. if(!event.shiftKey) {
  5050. module.verbose('Selecting previous label');
  5051. $label.removeClass(className.active);
  5052. }
  5053. else {
  5054. module.verbose('Adding previous label to selection');
  5055. }
  5056. if(isFirstLabel && !hasMultipleActive) {
  5057. $activeLabel.addClass(className.active);
  5058. }
  5059. else {
  5060. $activeLabel.prev(selector.siblingLabel)
  5061. .addClass(className.active)
  5062. .end()
  5063. ;
  5064. }
  5065. event.preventDefault();
  5066. }
  5067. }
  5068. else if(pressedKey == keys.rightArrow) {
  5069. // activate first label
  5070. if(isFocused && !hasActiveLabel) {
  5071. $label.first().addClass(className.active);
  5072. }
  5073. // activate next label
  5074. if(hasActiveLabel) {
  5075. if(!event.shiftKey) {
  5076. module.verbose('Selecting next label');
  5077. $label.removeClass(className.active);
  5078. }
  5079. else {
  5080. module.verbose('Adding next label to selection');
  5081. }
  5082. if(isLastLabel) {
  5083. if(isSearch) {
  5084. if(!isFocusedOnSearch) {
  5085. module.focusSearch();
  5086. }
  5087. else {
  5088. $label.removeClass(className.active);
  5089. }
  5090. }
  5091. else if(hasMultipleActive) {
  5092. $activeLabel.next(selector.siblingLabel).addClass(className.active);
  5093. }
  5094. else {
  5095. $activeLabel.addClass(className.active);
  5096. }
  5097. }
  5098. else {
  5099. $activeLabel.next(selector.siblingLabel).addClass(className.active);
  5100. }
  5101. event.preventDefault();
  5102. }
  5103. }
  5104. else if(pressedKey == keys.deleteKey || pressedKey == keys.backspace) {
  5105. if(hasActiveLabel) {
  5106. module.verbose('Removing active labels');
  5107. if(isLastLabel) {
  5108. if(isSearch && !isFocusedOnSearch) {
  5109. module.focusSearch();
  5110. }
  5111. }
  5112. $activeLabel.last().next(selector.siblingLabel).addClass(className.active);
  5113. module.remove.activeLabels($activeLabel);
  5114. event.preventDefault();
  5115. }
  5116. else if(caretAtStart && !hasActiveLabel && pressedKey == keys.backspace) {
  5117. module.verbose('Removing last label on input backspace');
  5118. $activeLabel = $label.last().addClass(className.active);
  5119. module.remove.activeLabels($activeLabel);
  5120. }
  5121. }
  5122. else {
  5123. $activeLabel.removeClass(className.active);
  5124. }
  5125. }
  5126. }
  5127. },
  5128. keydown: function(event) {
  5129. var
  5130. pressedKey = event.which,
  5131. isShortcutKey = module.is.inObject(pressedKey, keys)
  5132. ;
  5133. if(isShortcutKey) {
  5134. var
  5135. $currentlySelected = $item.not(selector.unselectable).filter('.' + className.selected).eq(0),
  5136. $activeItem = $menu.children('.' + className.active).eq(0),
  5137. $selectedItem = ($currentlySelected.length > 0)
  5138. ? $currentlySelected
  5139. : $activeItem,
  5140. $visibleItems = ($selectedItem.length > 0)
  5141. ? $selectedItem.siblings(':not(.' + className.filtered +')').addBack()
  5142. : $menu.children(':not(.' + className.filtered +')'),
  5143. $subMenu = $selectedItem.children(selector.menu),
  5144. $parentMenu = $selectedItem.closest(selector.menu),
  5145. inVisibleMenu = ($parentMenu.hasClass(className.visible) || $parentMenu.hasClass(className.animating) || $parentMenu.parent(selector.menu).length > 0),
  5146. hasSubMenu = ($subMenu.length> 0),
  5147. hasSelectedItem = ($selectedItem.length > 0),
  5148. selectedIsSelectable = ($selectedItem.not(selector.unselectable).length > 0),
  5149. delimiterPressed = (pressedKey == keys.delimiter && settings.allowAdditions && module.is.multiple()),
  5150. isAdditionWithoutMenu = (settings.allowAdditions && settings.hideAdditions && (pressedKey == keys.enter || delimiterPressed) && selectedIsSelectable),
  5151. $nextItem,
  5152. isSubMenuItem,
  5153. newIndex
  5154. ;
  5155. // allow selection with menu closed
  5156. if(isAdditionWithoutMenu) {
  5157. module.verbose('Selecting item from keyboard shortcut', $selectedItem);
  5158. module.event.item.click.call($selectedItem, event);
  5159. if(module.is.searchSelection()) {
  5160. module.remove.searchTerm();
  5161. }
  5162. }
  5163. // visible menu keyboard shortcuts
  5164. if( module.is.visible() ) {
  5165. // enter (select or open sub-menu)
  5166. if(pressedKey == keys.enter || delimiterPressed) {
  5167. if(pressedKey == keys.enter && hasSelectedItem && hasSubMenu && !settings.allowCategorySelection) {
  5168. module.verbose('Pressed enter on unselectable category, opening sub menu');
  5169. pressedKey = keys.rightArrow;
  5170. }
  5171. else if(selectedIsSelectable) {
  5172. module.verbose('Selecting item from keyboard shortcut', $selectedItem);
  5173. module.event.item.click.call($selectedItem, event);
  5174. if(module.is.searchSelection()) {
  5175. module.remove.searchTerm();
  5176. }
  5177. }
  5178. event.preventDefault();
  5179. }
  5180. // sub-menu actions
  5181. if(hasSelectedItem) {
  5182. if(pressedKey == keys.leftArrow) {
  5183. isSubMenuItem = ($parentMenu[0] !== $menu[0]);
  5184. if(isSubMenuItem) {
  5185. module.verbose('Left key pressed, closing sub-menu');
  5186. module.animate.hide(false, $parentMenu);
  5187. $selectedItem
  5188. .removeClass(className.selected)
  5189. ;
  5190. $parentMenu
  5191. .closest(selector.item)
  5192. .addClass(className.selected)
  5193. ;
  5194. event.preventDefault();
  5195. }
  5196. }
  5197. // right arrow (show sub-menu)
  5198. if(pressedKey == keys.rightArrow) {
  5199. if(hasSubMenu) {
  5200. module.verbose('Right key pressed, opening sub-menu');
  5201. module.animate.show(false, $subMenu);
  5202. $selectedItem
  5203. .removeClass(className.selected)
  5204. ;
  5205. $subMenu
  5206. .find(selector.item).eq(0)
  5207. .addClass(className.selected)
  5208. ;
  5209. event.preventDefault();
  5210. }
  5211. }
  5212. }
  5213. // up arrow (traverse menu up)
  5214. if(pressedKey == keys.upArrow) {
  5215. $nextItem = (hasSelectedItem && inVisibleMenu)
  5216. ? $selectedItem.prevAll(selector.item + ':not(' + selector.unselectable + ')').eq(0)
  5217. : $item.eq(0)
  5218. ;
  5219. if($visibleItems.index( $nextItem ) < 0) {
  5220. module.verbose('Up key pressed but reached top of current menu');
  5221. event.preventDefault();
  5222. return;
  5223. }
  5224. else {
  5225. module.verbose('Up key pressed, changing active item');
  5226. $selectedItem
  5227. .removeClass(className.selected)
  5228. ;
  5229. $nextItem
  5230. .addClass(className.selected)
  5231. ;
  5232. module.set.scrollPosition($nextItem);
  5233. if(settings.selectOnKeydown && module.is.single()) {
  5234. module.set.selectedItem($nextItem);
  5235. }
  5236. }
  5237. event.preventDefault();
  5238. }
  5239. // down arrow (traverse menu down)
  5240. if(pressedKey == keys.downArrow) {
  5241. $nextItem = (hasSelectedItem && inVisibleMenu)
  5242. ? $nextItem = $selectedItem.nextAll(selector.item + ':not(' + selector.unselectable + ')').eq(0)
  5243. : $item.eq(0)
  5244. ;
  5245. if($nextItem.length === 0) {
  5246. module.verbose('Down key pressed but reached bottom of current menu');
  5247. event.preventDefault();
  5248. return;
  5249. }
  5250. else {
  5251. module.verbose('Down key pressed, changing active item');
  5252. $item
  5253. .removeClass(className.selected)
  5254. ;
  5255. $nextItem
  5256. .addClass(className.selected)
  5257. ;
  5258. module.set.scrollPosition($nextItem);
  5259. if(settings.selectOnKeydown && module.is.single()) {
  5260. module.set.selectedItem($nextItem);
  5261. }
  5262. }
  5263. event.preventDefault();
  5264. }
  5265. // page down (show next page)
  5266. if(pressedKey == keys.pageUp) {
  5267. module.scrollPage('up');
  5268. event.preventDefault();
  5269. }
  5270. if(pressedKey == keys.pageDown) {
  5271. module.scrollPage('down');
  5272. event.preventDefault();
  5273. }
  5274. // escape (close menu)
  5275. if(pressedKey == keys.escape) {
  5276. module.verbose('Escape key pressed, closing dropdown');
  5277. module.hide();
  5278. }
  5279. }
  5280. else {
  5281. // delimiter key
  5282. if(delimiterPressed) {
  5283. event.preventDefault();
  5284. }
  5285. // down arrow (open menu)
  5286. if(pressedKey == keys.downArrow && !module.is.visible()) {
  5287. module.verbose('Down key pressed, showing dropdown');
  5288. module.select.firstUnfiltered();
  5289. module.show();
  5290. event.preventDefault();
  5291. }
  5292. }
  5293. }
  5294. else {
  5295. if( !module.has.search() ) {
  5296. module.set.selectedLetter( String.fromCharCode(pressedKey) );
  5297. }
  5298. }
  5299. }
  5300. },
  5301. trigger: {
  5302. change: function() {
  5303. var
  5304. events = document.createEvent('HTMLEvents'),
  5305. inputElement = $input[0]
  5306. ;
  5307. if(inputElement) {
  5308. module.verbose('Triggering native change event');
  5309. events.initEvent('change', true, false);
  5310. inputElement.dispatchEvent(events);
  5311. }
  5312. }
  5313. },
  5314. determine: {
  5315. selectAction: function(text, value) {
  5316. module.verbose('Determining action', settings.action);
  5317. if( $.isFunction( module.action[settings.action] ) ) {
  5318. module.verbose('Triggering preset action', settings.action, text, value);
  5319. module.action[ settings.action ].call(element, text, value, this);
  5320. }
  5321. else if( $.isFunction(settings.action) ) {
  5322. module.verbose('Triggering user action', settings.action, text, value);
  5323. settings.action.call(element, text, value, this);
  5324. }
  5325. else {
  5326. module.error(error.action, settings.action);
  5327. }
  5328. },
  5329. eventInModule: function(event, callback) {
  5330. var
  5331. $target = $(event.target),
  5332. inDocument = ($target.closest(document.documentElement).length > 0),
  5333. inModule = ($target.closest($module).length > 0)
  5334. ;
  5335. callback = $.isFunction(callback)
  5336. ? callback
  5337. : function(){}
  5338. ;
  5339. if(inDocument && !inModule) {
  5340. module.verbose('Triggering event', callback);
  5341. callback();
  5342. return true;
  5343. }
  5344. else {
  5345. module.verbose('Event occurred in dropdown, canceling callback');
  5346. return false;
  5347. }
  5348. },
  5349. eventOnElement: function(event, callback) {
  5350. var
  5351. $target = $(event.target),
  5352. $label = $target.closest(selector.siblingLabel),
  5353. inVisibleDOM = document.body.contains(event.target),
  5354. notOnLabel = ($module.find($label).length === 0),
  5355. notInMenu = ($target.closest($menu).length === 0)
  5356. ;
  5357. callback = $.isFunction(callback)
  5358. ? callback
  5359. : function(){}
  5360. ;
  5361. if(inVisibleDOM && notOnLabel && notInMenu) {
  5362. module.verbose('Triggering event', callback);
  5363. callback();
  5364. return true;
  5365. }
  5366. else {
  5367. module.verbose('Event occurred in dropdown menu, canceling callback');
  5368. return false;
  5369. }
  5370. }
  5371. },
  5372. action: {
  5373. nothing: function() {},
  5374. activate: function(text, value, element) {
  5375. value = (value !== undefined)
  5376. ? value
  5377. : text
  5378. ;
  5379. if( module.can.activate( $(element) ) ) {
  5380. module.set.selected(value, $(element));
  5381. if(module.is.multiple() && !module.is.allFiltered()) {
  5382. return;
  5383. }
  5384. else {
  5385. module.hideAndClear();
  5386. }
  5387. }
  5388. },
  5389. select: function(text, value, element) {
  5390. value = (value !== undefined)
  5391. ? value
  5392. : text
  5393. ;
  5394. if( module.can.activate( $(element) ) ) {
  5395. module.set.value(value, $(element));
  5396. if(module.is.multiple() && !module.is.allFiltered()) {
  5397. return;
  5398. }
  5399. else {
  5400. module.hideAndClear();
  5401. }
  5402. }
  5403. },
  5404. combo: function(text, value, element) {
  5405. value = (value !== undefined)
  5406. ? value
  5407. : text
  5408. ;
  5409. module.set.selected(value, $(element));
  5410. module.hideAndClear();
  5411. },
  5412. hide: function(text, value, element) {
  5413. module.set.value(value, text);
  5414. module.hideAndClear();
  5415. }
  5416. },
  5417. get: {
  5418. id: function() {
  5419. return id;
  5420. },
  5421. defaultText: function() {
  5422. return $module.data(metadata.defaultText);
  5423. },
  5424. defaultValue: function() {
  5425. return $module.data(metadata.defaultValue);
  5426. },
  5427. placeholderText: function() {
  5428. return $module.data(metadata.placeholderText) || '';
  5429. },
  5430. text: function() {
  5431. return $text.text();
  5432. },
  5433. query: function() {
  5434. return $.trim($search.val());
  5435. },
  5436. searchWidth: function(value) {
  5437. value = (value !== undefined)
  5438. ? value
  5439. : $search.val()
  5440. ;
  5441. $sizer.text(value);
  5442. // prevent rounding issues
  5443. return Math.ceil( $sizer.width() + 1);
  5444. },
  5445. selectionCount: function() {
  5446. var
  5447. values = module.get.values(),
  5448. count
  5449. ;
  5450. count = ( module.is.multiple() )
  5451. ? $.isArray(values)
  5452. ? values.length
  5453. : 0
  5454. : (module.get.value() !== '')
  5455. ? 1
  5456. : 0
  5457. ;
  5458. return count;
  5459. },
  5460. transition: function($subMenu) {
  5461. return (settings.transition == 'auto')
  5462. ? module.is.upward($subMenu)
  5463. ? 'slide up'
  5464. : 'slide down'
  5465. : settings.transition
  5466. ;
  5467. },
  5468. userValues: function() {
  5469. var
  5470. values = module.get.values()
  5471. ;
  5472. if(!values) {
  5473. return false;
  5474. }
  5475. values = $.isArray(values)
  5476. ? values
  5477. : [values]
  5478. ;
  5479. return $.grep(values, function(value) {
  5480. return (module.get.item(value) === false);
  5481. });
  5482. },
  5483. uniqueArray: function(array) {
  5484. return $.grep(array, function (value, index) {
  5485. return $.inArray(value, array) === index;
  5486. });
  5487. },
  5488. caretPosition: function() {
  5489. var
  5490. input = $search.get(0),
  5491. range,
  5492. rangeLength
  5493. ;
  5494. if('selectionStart' in input) {
  5495. return input.selectionStart;
  5496. }
  5497. else if (document.selection) {
  5498. input.focus();
  5499. range = document.selection.createRange();
  5500. rangeLength = range.text.length;
  5501. range.moveStart('character', -input.value.length);
  5502. return range.text.length - rangeLength;
  5503. }
  5504. },
  5505. value: function() {
  5506. var
  5507. value = ($input.length > 0)
  5508. ? $input.val()
  5509. : $module.data(metadata.value),
  5510. isEmptyMultiselect = ($.isArray(value) && value.length === 1 && value[0] === '')
  5511. ;
  5512. // prevents placeholder element from being selected when multiple
  5513. return (value === undefined || isEmptyMultiselect)
  5514. ? ''
  5515. : value
  5516. ;
  5517. },
  5518. values: function() {
  5519. var
  5520. value = module.get.value()
  5521. ;
  5522. if(value === '') {
  5523. return '';
  5524. }
  5525. return ( !module.has.selectInput() && module.is.multiple() )
  5526. ? (typeof value == 'string') // delimited string
  5527. ? value.split(settings.delimiter)
  5528. : ''
  5529. : value
  5530. ;
  5531. },
  5532. remoteValues: function() {
  5533. var
  5534. values = module.get.values(),
  5535. remoteValues = false
  5536. ;
  5537. if(values) {
  5538. if(typeof values == 'string') {
  5539. values = [values];
  5540. }
  5541. $.each(values, function(index, value) {
  5542. var
  5543. name = module.read.remoteData(value)
  5544. ;
  5545. module.verbose('Restoring value from session data', name, value);
  5546. if(name) {
  5547. if(!remoteValues) {
  5548. remoteValues = {};
  5549. }
  5550. remoteValues[value] = name;
  5551. }
  5552. });
  5553. }
  5554. return remoteValues;
  5555. },
  5556. choiceText: function($choice, preserveHTML) {
  5557. preserveHTML = (preserveHTML !== undefined)
  5558. ? preserveHTML
  5559. : settings.preserveHTML
  5560. ;
  5561. if($choice) {
  5562. if($choice.find(selector.menu).length > 0) {
  5563. module.verbose('Retrieving text of element with sub-menu');
  5564. $choice = $choice.clone();
  5565. $choice.find(selector.menu).remove();
  5566. $choice.find(selector.menuIcon).remove();
  5567. }
  5568. return ($choice.data(metadata.text) !== undefined)
  5569. ? $choice.data(metadata.text)
  5570. : (preserveHTML)
  5571. ? $.trim($choice.html())
  5572. : $.trim($choice.text())
  5573. ;
  5574. }
  5575. },
  5576. choiceValue: function($choice, choiceText) {
  5577. choiceText = choiceText || module.get.choiceText($choice);
  5578. if(!$choice) {
  5579. return false;
  5580. }
  5581. return ($choice.data(metadata.value) !== undefined)
  5582. ? String( $choice.data(metadata.value) )
  5583. : (typeof choiceText === 'string')
  5584. ? $.trim(choiceText.toLowerCase())
  5585. : String(choiceText)
  5586. ;
  5587. },
  5588. inputEvent: function() {
  5589. var
  5590. input = $search[0]
  5591. ;
  5592. if(input) {
  5593. return (input.oninput !== undefined)
  5594. ? 'input'
  5595. : (input.onpropertychange !== undefined)
  5596. ? 'propertychange'
  5597. : 'keyup'
  5598. ;
  5599. }
  5600. return false;
  5601. },
  5602. selectValues: function() {
  5603. var
  5604. select = {}
  5605. ;
  5606. select.values = [];
  5607. $module
  5608. .find('option')
  5609. .each(function() {
  5610. var
  5611. $option = $(this),
  5612. name = $option.html(),
  5613. disabled = $option.attr('disabled'),
  5614. value = ( $option.attr('value') !== undefined )
  5615. ? $option.attr('value')
  5616. : name
  5617. ;
  5618. if(settings.placeholder === 'auto' && value === '') {
  5619. select.placeholder = name;
  5620. }
  5621. else {
  5622. select.values.push({
  5623. name : name,
  5624. value : value,
  5625. disabled : disabled
  5626. });
  5627. }
  5628. })
  5629. ;
  5630. if(settings.placeholder && settings.placeholder !== 'auto') {
  5631. module.debug('Setting placeholder value to', settings.placeholder);
  5632. select.placeholder = settings.placeholder;
  5633. }
  5634. if(settings.sortSelect) {
  5635. select.values.sort(function(a, b) {
  5636. return (a.name > b.name)
  5637. ? 1
  5638. : -1
  5639. ;
  5640. });
  5641. module.debug('Retrieved and sorted values from select', select);
  5642. }
  5643. else {
  5644. module.debug('Retrieved values from select', select);
  5645. }
  5646. return select;
  5647. },
  5648. activeItem: function() {
  5649. return $item.filter('.' + className.active);
  5650. },
  5651. selectedItem: function() {
  5652. var
  5653. $selectedItem = $item.not(selector.unselectable).filter('.' + className.selected)
  5654. ;
  5655. return ($selectedItem.length > 0)
  5656. ? $selectedItem
  5657. : $item.eq(0)
  5658. ;
  5659. },
  5660. itemWithAdditions: function(value) {
  5661. var
  5662. $items = module.get.item(value),
  5663. $userItems = module.create.userChoice(value),
  5664. hasUserItems = ($userItems && $userItems.length > 0)
  5665. ;
  5666. if(hasUserItems) {
  5667. $items = ($items.length > 0)
  5668. ? $items.add($userItems)
  5669. : $userItems
  5670. ;
  5671. }
  5672. return $items;
  5673. },
  5674. item: function(value, strict) {
  5675. var
  5676. $selectedItem = false,
  5677. shouldSearch,
  5678. isMultiple
  5679. ;
  5680. value = (value !== undefined)
  5681. ? value
  5682. : ( module.get.values() !== undefined)
  5683. ? module.get.values()
  5684. : module.get.text()
  5685. ;
  5686. shouldSearch = (isMultiple)
  5687. ? (value.length > 0)
  5688. : (value !== undefined && value !== null)
  5689. ;
  5690. isMultiple = (module.is.multiple() && $.isArray(value));
  5691. strict = (value === '' || value === 0)
  5692. ? true
  5693. : strict || false
  5694. ;
  5695. if(shouldSearch) {
  5696. $item
  5697. .each(function() {
  5698. var
  5699. $choice = $(this),
  5700. optionText = module.get.choiceText($choice),
  5701. optionValue = module.get.choiceValue($choice, optionText)
  5702. ;
  5703. // safe early exit
  5704. if(optionValue === null || optionValue === undefined) {
  5705. return;
  5706. }
  5707. if(isMultiple) {
  5708. if($.inArray( String(optionValue), value) !== -1 || $.inArray(optionText, value) !== -1) {
  5709. $selectedItem = ($selectedItem)
  5710. ? $selectedItem.add($choice)
  5711. : $choice
  5712. ;
  5713. }
  5714. }
  5715. else if(strict) {
  5716. module.verbose('Ambiguous dropdown value using strict type check', $choice, value);
  5717. if( optionValue === value || optionText === value) {
  5718. $selectedItem = $choice;
  5719. return true;
  5720. }
  5721. }
  5722. else {
  5723. if( String(optionValue) == String(value) || optionText == value) {
  5724. module.verbose('Found select item by value', optionValue, value);
  5725. $selectedItem = $choice;
  5726. return true;
  5727. }
  5728. }
  5729. })
  5730. ;
  5731. }
  5732. return $selectedItem;
  5733. }
  5734. },
  5735. check: {
  5736. maxSelections: function(selectionCount) {
  5737. if(settings.maxSelections) {
  5738. selectionCount = (selectionCount !== undefined)
  5739. ? selectionCount
  5740. : module.get.selectionCount()
  5741. ;
  5742. if(selectionCount >= settings.maxSelections) {
  5743. module.debug('Maximum selection count reached');
  5744. if(settings.useLabels) {
  5745. $item.addClass(className.filtered);
  5746. module.add.message(message.maxSelections);
  5747. }
  5748. return true;
  5749. }
  5750. else {
  5751. module.verbose('No longer at maximum selection count');
  5752. module.remove.message();
  5753. module.remove.filteredItem();
  5754. if(module.is.searchSelection()) {
  5755. module.filterItems();
  5756. }
  5757. return false;
  5758. }
  5759. }
  5760. return true;
  5761. }
  5762. },
  5763. restore: {
  5764. defaults: function() {
  5765. module.clear();
  5766. module.restore.defaultText();
  5767. module.restore.defaultValue();
  5768. },
  5769. defaultText: function() {
  5770. var
  5771. defaultText = module.get.defaultText(),
  5772. placeholderText = module.get.placeholderText
  5773. ;
  5774. if(defaultText === placeholderText) {
  5775. module.debug('Restoring default placeholder text', defaultText);
  5776. module.set.placeholderText(defaultText);
  5777. }
  5778. else {
  5779. module.debug('Restoring default text', defaultText);
  5780. module.set.text(defaultText);
  5781. }
  5782. },
  5783. placeholderText: function() {
  5784. module.set.placeholderText();
  5785. },
  5786. defaultValue: function() {
  5787. var
  5788. defaultValue = module.get.defaultValue()
  5789. ;
  5790. if(defaultValue !== undefined) {
  5791. module.debug('Restoring default value', defaultValue);
  5792. if(defaultValue !== '') {
  5793. module.set.value(defaultValue);
  5794. module.set.selected();
  5795. }
  5796. else {
  5797. module.remove.activeItem();
  5798. module.remove.selectedItem();
  5799. }
  5800. }
  5801. },
  5802. labels: function() {
  5803. if(settings.allowAdditions) {
  5804. if(!settings.useLabels) {
  5805. module.error(error.labels);
  5806. settings.useLabels = true;
  5807. }
  5808. module.debug('Restoring selected values');
  5809. module.create.userLabels();
  5810. }
  5811. module.check.maxSelections();
  5812. },
  5813. selected: function() {
  5814. module.restore.values();
  5815. if(module.is.multiple()) {
  5816. module.debug('Restoring previously selected values and labels');
  5817. module.restore.labels();
  5818. }
  5819. else {
  5820. module.debug('Restoring previously selected values');
  5821. }
  5822. },
  5823. values: function() {
  5824. // prevents callbacks from occurring on initial load
  5825. module.set.initialLoad();
  5826. if(settings.apiSettings && settings.saveRemoteData && module.get.remoteValues()) {
  5827. module.restore.remoteValues();
  5828. }
  5829. else {
  5830. module.set.selected();
  5831. }
  5832. module.remove.initialLoad();
  5833. },
  5834. remoteValues: function() {
  5835. var
  5836. values = module.get.remoteValues()
  5837. ;
  5838. module.debug('Recreating selected from session data', values);
  5839. if(values) {
  5840. if( module.is.single() ) {
  5841. $.each(values, function(value, name) {
  5842. module.set.text(name);
  5843. });
  5844. }
  5845. else {
  5846. $.each(values, function(value, name) {
  5847. module.add.label(value, name);
  5848. });
  5849. }
  5850. }
  5851. }
  5852. },
  5853. read: {
  5854. remoteData: function(value) {
  5855. var
  5856. name
  5857. ;
  5858. if(window.Storage === undefined) {
  5859. module.error(error.noStorage);
  5860. return;
  5861. }
  5862. name = sessionStorage.getItem(value);
  5863. return (name !== undefined)
  5864. ? name
  5865. : false
  5866. ;
  5867. }
  5868. },
  5869. save: {
  5870. defaults: function() {
  5871. module.save.defaultText();
  5872. module.save.placeholderText();
  5873. module.save.defaultValue();
  5874. },
  5875. defaultValue: function() {
  5876. var
  5877. value = module.get.value()
  5878. ;
  5879. module.verbose('Saving default value as', value);
  5880. $module.data(metadata.defaultValue, value);
  5881. },
  5882. defaultText: function() {
  5883. var
  5884. text = module.get.text()
  5885. ;
  5886. module.verbose('Saving default text as', text);
  5887. $module.data(metadata.defaultText, text);
  5888. },
  5889. placeholderText: function() {
  5890. var
  5891. text
  5892. ;
  5893. if(settings.placeholder !== false && $text.hasClass(className.placeholder)) {
  5894. text = module.get.text();
  5895. module.verbose('Saving placeholder text as', text);
  5896. $module.data(metadata.placeholderText, text);
  5897. }
  5898. },
  5899. remoteData: function(name, value) {
  5900. if(window.Storage === undefined) {
  5901. module.error(error.noStorage);
  5902. return;
  5903. }
  5904. module.verbose('Saving remote data to session storage', value, name);
  5905. sessionStorage.setItem(value, name);
  5906. }
  5907. },
  5908. clear: function() {
  5909. if(module.is.multiple() && settings.useLabels) {
  5910. module.remove.labels();
  5911. }
  5912. else {
  5913. module.remove.activeItem();
  5914. module.remove.selectedItem();
  5915. }
  5916. module.set.placeholderText();
  5917. module.clearValue();
  5918. },
  5919. clearValue: function() {
  5920. module.set.value('');
  5921. },
  5922. scrollPage: function(direction, $selectedItem) {
  5923. var
  5924. $currentItem = $selectedItem || module.get.selectedItem(),
  5925. $menu = $currentItem.closest(selector.menu),
  5926. menuHeight = $menu.outerHeight(),
  5927. currentScroll = $menu.scrollTop(),
  5928. itemHeight = $item.eq(0).outerHeight(),
  5929. itemsPerPage = Math.floor(menuHeight / itemHeight),
  5930. maxScroll = $menu.prop('scrollHeight'),
  5931. newScroll = (direction == 'up')
  5932. ? currentScroll - (itemHeight * itemsPerPage)
  5933. : currentScroll + (itemHeight * itemsPerPage),
  5934. $selectableItem = $item.not(selector.unselectable),
  5935. isWithinRange,
  5936. $nextSelectedItem,
  5937. elementIndex
  5938. ;
  5939. elementIndex = (direction == 'up')
  5940. ? $selectableItem.index($currentItem) - itemsPerPage
  5941. : $selectableItem.index($currentItem) + itemsPerPage
  5942. ;
  5943. isWithinRange = (direction == 'up')
  5944. ? (elementIndex >= 0)
  5945. : (elementIndex < $selectableItem.length)
  5946. ;
  5947. $nextSelectedItem = (isWithinRange)
  5948. ? $selectableItem.eq(elementIndex)
  5949. : (direction == 'up')
  5950. ? $selectableItem.first()
  5951. : $selectableItem.last()
  5952. ;
  5953. if($nextSelectedItem.length > 0) {
  5954. module.debug('Scrolling page', direction, $nextSelectedItem);
  5955. $currentItem
  5956. .removeClass(className.selected)
  5957. ;
  5958. $nextSelectedItem
  5959. .addClass(className.selected)
  5960. ;
  5961. if(settings.selectOnKeydown && module.is.single()) {
  5962. module.set.selectedItem($nextSelectedItem);
  5963. }
  5964. $menu
  5965. .scrollTop(newScroll)
  5966. ;
  5967. }
  5968. },
  5969. set: {
  5970. filtered: function() {
  5971. var
  5972. isMultiple = module.is.multiple(),
  5973. isSearch = module.is.searchSelection(),
  5974. isSearchMultiple = (isMultiple && isSearch),
  5975. searchValue = (isSearch)
  5976. ? module.get.query()
  5977. : '',
  5978. hasSearchValue = (typeof searchValue === 'string' && searchValue.length > 0),
  5979. searchWidth = module.get.searchWidth(),
  5980. valueIsSet = searchValue !== ''
  5981. ;
  5982. if(isMultiple && hasSearchValue) {
  5983. module.verbose('Adjusting input width', searchWidth, settings.glyphWidth);
  5984. $search.css('width', searchWidth);
  5985. }
  5986. if(hasSearchValue || (isSearchMultiple && valueIsSet)) {
  5987. module.verbose('Hiding placeholder text');
  5988. $text.addClass(className.filtered);
  5989. }
  5990. else if(!isMultiple || (isSearchMultiple && !valueIsSet)) {
  5991. module.verbose('Showing placeholder text');
  5992. $text.removeClass(className.filtered);
  5993. }
  5994. },
  5995. empty: function() {
  5996. $module.addClass(className.empty);
  5997. },
  5998. loading: function() {
  5999. $module.addClass(className.loading);
  6000. },
  6001. placeholderText: function(text) {
  6002. text = text || module.get.placeholderText();
  6003. module.debug('Setting placeholder text', text);
  6004. module.set.text(text);
  6005. $text.addClass(className.placeholder);
  6006. },
  6007. tabbable: function() {
  6008. if( module.has.search() ) {
  6009. module.debug('Added tabindex to searchable dropdown');
  6010. $search
  6011. .val('')
  6012. .attr('tabindex', 0)
  6013. ;
  6014. $menu
  6015. .attr('tabindex', -1)
  6016. ;
  6017. }
  6018. else {
  6019. module.debug('Added tabindex to dropdown');
  6020. if( $module.attr('tabindex') === undefined) {
  6021. $module
  6022. .attr('tabindex', 0)
  6023. ;
  6024. $menu
  6025. .attr('tabindex', -1)
  6026. ;
  6027. }
  6028. }
  6029. },
  6030. initialLoad: function() {
  6031. module.verbose('Setting initial load');
  6032. initialLoad = true;
  6033. },
  6034. activeItem: function($item) {
  6035. if( settings.allowAdditions && $item.filter(selector.addition).length > 0 ) {
  6036. $item.addClass(className.filtered);
  6037. }
  6038. else {
  6039. $item.addClass(className.active);
  6040. }
  6041. },
  6042. partialSearch: function(text) {
  6043. var
  6044. length = module.get.query().length
  6045. ;
  6046. $search.val( text.substr(0 , length));
  6047. },
  6048. scrollPosition: function($item, forceScroll) {
  6049. var
  6050. edgeTolerance = 5,
  6051. $menu,
  6052. hasActive,
  6053. offset,
  6054. itemHeight,
  6055. itemOffset,
  6056. menuOffset,
  6057. menuScroll,
  6058. menuHeight,
  6059. abovePage,
  6060. belowPage
  6061. ;
  6062. $item = $item || module.get.selectedItem();
  6063. $menu = $item.closest(selector.menu);
  6064. hasActive = ($item && $item.length > 0);
  6065. forceScroll = (forceScroll !== undefined)
  6066. ? forceScroll
  6067. : false
  6068. ;
  6069. if($item && $menu.length > 0 && hasActive) {
  6070. itemOffset = $item.position().top;
  6071. $menu.addClass(className.loading);
  6072. menuScroll = $menu.scrollTop();
  6073. menuOffset = $menu.offset().top;
  6074. itemOffset = $item.offset().top;
  6075. offset = menuScroll - menuOffset + itemOffset;
  6076. if(!forceScroll) {
  6077. menuHeight = $menu.height();
  6078. belowPage = menuScroll + menuHeight < (offset + edgeTolerance);
  6079. abovePage = ((offset - edgeTolerance) < menuScroll);
  6080. }
  6081. module.debug('Scrolling to active item', offset);
  6082. if(forceScroll || abovePage || belowPage) {
  6083. $menu.scrollTop(offset);
  6084. }
  6085. $menu.removeClass(className.loading);
  6086. }
  6087. },
  6088. text: function(text) {
  6089. if(settings.action !== 'select') {
  6090. if(settings.action == 'combo') {
  6091. module.debug('Changing combo button text', text, $combo);
  6092. if(settings.preserveHTML) {
  6093. $combo.html(text);
  6094. }
  6095. else {
  6096. $combo.text(text);
  6097. }
  6098. }
  6099. else {
  6100. if(text !== module.get.placeholderText()) {
  6101. $text.removeClass(className.placeholder);
  6102. }
  6103. module.debug('Changing text', text, $text);
  6104. $text
  6105. .removeClass(className.filtered)
  6106. ;
  6107. if(settings.preserveHTML) {
  6108. $text.html(text);
  6109. }
  6110. else {
  6111. $text.text(text);
  6112. }
  6113. }
  6114. }
  6115. },
  6116. selectedItem: function($item) {
  6117. var
  6118. value = module.get.choiceValue($item),
  6119. text = module.get.choiceText($item, false)
  6120. ;
  6121. module.debug('Setting user selection to item', $item);
  6122. module.remove.activeItem();
  6123. module.set.partialSearch(text);
  6124. module.set.activeItem($item);
  6125. module.set.selected(value, $item);
  6126. module.set.text(text);
  6127. },
  6128. selectedLetter: function(letter) {
  6129. var
  6130. $selectedItem = $item.filter('.' + className.selected),
  6131. alreadySelectedLetter = $selectedItem.length > 0 && module.has.firstLetter($selectedItem, letter),
  6132. $nextValue = false,
  6133. $nextItem
  6134. ;
  6135. // check next of same letter
  6136. if(alreadySelectedLetter) {
  6137. $nextItem = $selectedItem.nextAll($item).eq(0);
  6138. if( module.has.firstLetter($nextItem, letter) ) {
  6139. $nextValue = $nextItem;
  6140. }
  6141. }
  6142. // check all values
  6143. if(!$nextValue) {
  6144. $item
  6145. .each(function(){
  6146. if(module.has.firstLetter($(this), letter)) {
  6147. $nextValue = $(this);
  6148. return false;
  6149. }
  6150. })
  6151. ;
  6152. }
  6153. // set next value
  6154. if($nextValue) {
  6155. module.verbose('Scrolling to next value with letter', letter);
  6156. module.set.scrollPosition($nextValue);
  6157. $selectedItem.removeClass(className.selected);
  6158. $nextValue.addClass(className.selected);
  6159. if(settings.selectOnKeydown && module.is.single()) {
  6160. module.set.selectedItem($nextValue);
  6161. }
  6162. }
  6163. },
  6164. direction: function($menu) {
  6165. if(settings.direction == 'auto') {
  6166. if(module.is.onScreen($menu)) {
  6167. module.remove.upward($menu);
  6168. }
  6169. else {
  6170. module.set.upward($menu);
  6171. }
  6172. }
  6173. else if(settings.direction == 'upward') {
  6174. module.set.upward($menu);
  6175. }
  6176. },
  6177. upward: function($menu) {
  6178. var $element = $menu || $module;
  6179. $element.addClass(className.upward);
  6180. },
  6181. value: function(value, text, $selected) {
  6182. var
  6183. escapedValue = module.escape.value(value),
  6184. hasInput = ($input.length > 0),
  6185. isAddition = !module.has.value(value),
  6186. currentValue = module.get.values(),
  6187. stringValue = (value !== undefined)
  6188. ? String(value)
  6189. : value,
  6190. newValue
  6191. ;
  6192. if(hasInput) {
  6193. if(!settings.allowReselection && stringValue == currentValue) {
  6194. module.verbose('Skipping value update already same value', value, currentValue);
  6195. if(!module.is.initialLoad()) {
  6196. return;
  6197. }
  6198. }
  6199. if( module.is.single() && module.has.selectInput() && module.can.extendSelect() ) {
  6200. module.debug('Adding user option', value);
  6201. module.add.optionValue(value);
  6202. }
  6203. module.debug('Updating input value', escapedValue, currentValue);
  6204. internalChange = true;
  6205. $input
  6206. .val(escapedValue)
  6207. ;
  6208. if(settings.fireOnInit === false && module.is.initialLoad()) {
  6209. module.debug('Input native change event ignored on initial load');
  6210. }
  6211. else {
  6212. module.trigger.change();
  6213. }
  6214. internalChange = false;
  6215. }
  6216. else {
  6217. module.verbose('Storing value in metadata', escapedValue, $input);
  6218. if(escapedValue !== currentValue) {
  6219. $module.data(metadata.value, stringValue);
  6220. }
  6221. }
  6222. if(settings.fireOnInit === false && module.is.initialLoad()) {
  6223. module.verbose('No callback on initial load', settings.onChange);
  6224. }
  6225. else {
  6226. settings.onChange.call(element, value, text, $selected);
  6227. }
  6228. },
  6229. active: function() {
  6230. $module
  6231. .addClass(className.active)
  6232. ;
  6233. },
  6234. multiple: function() {
  6235. $module.addClass(className.multiple);
  6236. },
  6237. visible: function() {
  6238. $module.addClass(className.visible);
  6239. },
  6240. exactly: function(value, $selectedItem) {
  6241. module.debug('Setting selected to exact values');
  6242. module.clear();
  6243. module.set.selected(value, $selectedItem);
  6244. },
  6245. selected: function(value, $selectedItem) {
  6246. var
  6247. isMultiple = module.is.multiple(),
  6248. $userSelectedItem
  6249. ;
  6250. $selectedItem = (settings.allowAdditions)
  6251. ? $selectedItem || module.get.itemWithAdditions(value)
  6252. : $selectedItem || module.get.item(value)
  6253. ;
  6254. if(!$selectedItem) {
  6255. return;
  6256. }
  6257. module.debug('Setting selected menu item to', $selectedItem);
  6258. if(module.is.multiple()) {
  6259. module.remove.searchWidth();
  6260. }
  6261. if(module.is.single()) {
  6262. module.remove.activeItem();
  6263. module.remove.selectedItem();
  6264. }
  6265. else if(settings.useLabels) {
  6266. module.remove.selectedItem();
  6267. }
  6268. // select each item
  6269. $selectedItem
  6270. .each(function() {
  6271. var
  6272. $selected = $(this),
  6273. selectedText = module.get.choiceText($selected),
  6274. selectedValue = module.get.choiceValue($selected, selectedText),
  6275. isFiltered = $selected.hasClass(className.filtered),
  6276. isActive = $selected.hasClass(className.active),
  6277. isUserValue = $selected.hasClass(className.addition),
  6278. shouldAnimate = (isMultiple && $selectedItem.length == 1)
  6279. ;
  6280. if(isMultiple) {
  6281. if(!isActive || isUserValue) {
  6282. if(settings.apiSettings && settings.saveRemoteData) {
  6283. module.save.remoteData(selectedText, selectedValue);
  6284. }
  6285. if(settings.useLabels) {
  6286. module.add.value(selectedValue, selectedText, $selected);
  6287. module.add.label(selectedValue, selectedText, shouldAnimate);
  6288. module.set.activeItem($selected);
  6289. module.filterActive();
  6290. module.select.nextAvailable($selectedItem);
  6291. }
  6292. else {
  6293. module.add.value(selectedValue, selectedText, $selected);
  6294. module.set.text(module.add.variables(message.count));
  6295. module.set.activeItem($selected);
  6296. }
  6297. }
  6298. else if(!isFiltered) {
  6299. module.debug('Selected active value, removing label');
  6300. module.remove.selected(selectedValue);
  6301. }
  6302. }
  6303. else {
  6304. if(settings.apiSettings && settings.saveRemoteData) {
  6305. module.save.remoteData(selectedText, selectedValue);
  6306. }
  6307. module.set.text(selectedText);
  6308. module.set.value(selectedValue, selectedText, $selected);
  6309. $selected
  6310. .addClass(className.active)
  6311. .addClass(className.selected)
  6312. ;
  6313. }
  6314. })
  6315. ;
  6316. }
  6317. },
  6318. add: {
  6319. label: function(value, text, shouldAnimate) {
  6320. var
  6321. $next = module.is.searchSelection()
  6322. ? $search
  6323. : $text,
  6324. escapedValue = module.escape.value(value),
  6325. $label
  6326. ;
  6327. $label = $('<a />')
  6328. .addClass(className.label)
  6329. .attr('data-value', escapedValue)
  6330. .html(templates.label(escapedValue, text))
  6331. ;
  6332. $label = settings.onLabelCreate.call($label, escapedValue, text);
  6333. if(module.has.label(value)) {
  6334. module.debug('Label already exists, skipping', escapedValue);
  6335. return;
  6336. }
  6337. if(settings.label.variation) {
  6338. $label.addClass(settings.label.variation);
  6339. }
  6340. if(shouldAnimate === true) {
  6341. module.debug('Animating in label', $label);
  6342. $label
  6343. .addClass(className.hidden)
  6344. .insertBefore($next)
  6345. .transition(settings.label.transition, settings.label.duration)
  6346. ;
  6347. }
  6348. else {
  6349. module.debug('Adding selection label', $label);
  6350. $label
  6351. .insertBefore($next)
  6352. ;
  6353. }
  6354. },
  6355. message: function(message) {
  6356. var
  6357. $message = $menu.children(selector.message),
  6358. html = settings.templates.message(module.add.variables(message))
  6359. ;
  6360. if($message.length > 0) {
  6361. $message
  6362. .html(html)
  6363. ;
  6364. }
  6365. else {
  6366. $message = $('<div/>')
  6367. .html(html)
  6368. .addClass(className.message)
  6369. .appendTo($menu)
  6370. ;
  6371. }
  6372. },
  6373. optionValue: function(value) {
  6374. var
  6375. escapedValue = module.escape.value(value),
  6376. $option = $input.find('option[value="' + escapedValue + '"]'),
  6377. hasOption = ($option.length > 0)
  6378. ;
  6379. if(hasOption) {
  6380. return;
  6381. }
  6382. // temporarily disconnect observer
  6383. module.disconnect.selectObserver();
  6384. if( module.is.single() ) {
  6385. module.verbose('Removing previous user addition');
  6386. $input.find('option.' + className.addition).remove();
  6387. }
  6388. $('<option/>')
  6389. .prop('value', escapedValue)
  6390. .addClass(className.addition)
  6391. .html(value)
  6392. .appendTo($input)
  6393. ;
  6394. module.verbose('Adding user addition as an <option>', value);
  6395. module.observe.select();
  6396. },
  6397. userSuggestion: function(value) {
  6398. var
  6399. $addition = $menu.children(selector.addition),
  6400. $existingItem = module.get.item(value),
  6401. alreadyHasValue = $existingItem && $existingItem.not(selector.addition).length,
  6402. hasUserSuggestion = $addition.length > 0,
  6403. html
  6404. ;
  6405. if(settings.useLabels && module.has.maxSelections()) {
  6406. return;
  6407. }
  6408. if(value === '' || alreadyHasValue) {
  6409. $addition.remove();
  6410. return;
  6411. }
  6412. if(hasUserSuggestion) {
  6413. $addition
  6414. .data(metadata.value, value)
  6415. .data(metadata.text, value)
  6416. .attr('data-' + metadata.value, value)
  6417. .attr('data-' + metadata.text, value)
  6418. .removeClass(className.filtered)
  6419. ;
  6420. if(!settings.hideAdditions) {
  6421. html = settings.templates.addition( module.add.variables(message.addResult, value) );
  6422. $addition
  6423. .html(html)
  6424. ;
  6425. }
  6426. module.verbose('Replacing user suggestion with new value', $addition);
  6427. }
  6428. else {
  6429. $addition = module.create.userChoice(value);
  6430. $addition
  6431. .prependTo($menu)
  6432. ;
  6433. module.verbose('Adding item choice to menu corresponding with user choice addition', $addition);
  6434. }
  6435. if(!settings.hideAdditions || module.is.allFiltered()) {
  6436. $addition
  6437. .addClass(className.selected)
  6438. .siblings()
  6439. .removeClass(className.selected)
  6440. ;
  6441. }
  6442. module.refreshItems();
  6443. },
  6444. variables: function(message, term) {
  6445. var
  6446. hasCount = (message.search('{count}') !== -1),
  6447. hasMaxCount = (message.search('{maxCount}') !== -1),
  6448. hasTerm = (message.search('{term}') !== -1),
  6449. values,
  6450. count,
  6451. query
  6452. ;
  6453. module.verbose('Adding templated variables to message', message);
  6454. if(hasCount) {
  6455. count = module.get.selectionCount();
  6456. message = message.replace('{count}', count);
  6457. }
  6458. if(hasMaxCount) {
  6459. count = module.get.selectionCount();
  6460. message = message.replace('{maxCount}', settings.maxSelections);
  6461. }
  6462. if(hasTerm) {
  6463. query = term || module.get.query();
  6464. message = message.replace('{term}', query);
  6465. }
  6466. return message;
  6467. },
  6468. value: function(addedValue, addedText, $selectedItem) {
  6469. var
  6470. currentValue = module.get.values(),
  6471. newValue
  6472. ;
  6473. if(addedValue === '') {
  6474. module.debug('Cannot select blank values from multiselect');
  6475. return;
  6476. }
  6477. // extend current array
  6478. if($.isArray(currentValue)) {
  6479. newValue = currentValue.concat([addedValue]);
  6480. newValue = module.get.uniqueArray(newValue);
  6481. }
  6482. else {
  6483. newValue = [addedValue];
  6484. }
  6485. // add values
  6486. if( module.has.selectInput() ) {
  6487. if(module.can.extendSelect()) {
  6488. module.debug('Adding value to select', addedValue, newValue, $input);
  6489. module.add.optionValue(addedValue);
  6490. }
  6491. }
  6492. else {
  6493. newValue = newValue.join(settings.delimiter);
  6494. module.debug('Setting hidden input to delimited value', newValue, $input);
  6495. }
  6496. if(settings.fireOnInit === false && module.is.initialLoad()) {
  6497. module.verbose('Skipping onadd callback on initial load', settings.onAdd);
  6498. }
  6499. else {
  6500. settings.onAdd.call(element, addedValue, addedText, $selectedItem);
  6501. }
  6502. module.set.value(newValue, addedValue, addedText, $selectedItem);
  6503. module.check.maxSelections();
  6504. }
  6505. },
  6506. remove: {
  6507. active: function() {
  6508. $module.removeClass(className.active);
  6509. },
  6510. activeLabel: function() {
  6511. $module.find(selector.label).removeClass(className.active);
  6512. },
  6513. empty: function() {
  6514. $module.removeClass(className.empty);
  6515. },
  6516. loading: function() {
  6517. $module.removeClass(className.loading);
  6518. },
  6519. initialLoad: function() {
  6520. initialLoad = false;
  6521. },
  6522. upward: function($menu) {
  6523. var $element = $menu || $module;
  6524. $element.removeClass(className.upward);
  6525. },
  6526. visible: function() {
  6527. $module.removeClass(className.visible);
  6528. },
  6529. activeItem: function() {
  6530. $item.removeClass(className.active);
  6531. },
  6532. filteredItem: function() {
  6533. if(settings.useLabels && module.has.maxSelections() ) {
  6534. return;
  6535. }
  6536. if(settings.useLabels && module.is.multiple()) {
  6537. $item.not('.' + className.active).removeClass(className.filtered);
  6538. }
  6539. else {
  6540. $item.removeClass(className.filtered);
  6541. }
  6542. module.remove.empty();
  6543. },
  6544. optionValue: function(value) {
  6545. var
  6546. escapedValue = module.escape.value(value),
  6547. $option = $input.find('option[value="' + escapedValue + '"]'),
  6548. hasOption = ($option.length > 0)
  6549. ;
  6550. if(!hasOption || !$option.hasClass(className.addition)) {
  6551. return;
  6552. }
  6553. // temporarily disconnect observer
  6554. if(selectObserver) {
  6555. selectObserver.disconnect();
  6556. module.verbose('Temporarily disconnecting mutation observer');
  6557. }
  6558. $option.remove();
  6559. module.verbose('Removing user addition as an <option>', escapedValue);
  6560. if(selectObserver) {
  6561. selectObserver.observe($input[0], {
  6562. childList : true,
  6563. subtree : true
  6564. });
  6565. }
  6566. },
  6567. message: function() {
  6568. $menu.children(selector.message).remove();
  6569. },
  6570. searchWidth: function() {
  6571. $search.css('width', '');
  6572. },
  6573. searchTerm: function() {
  6574. module.verbose('Cleared search term');
  6575. $search.val('');
  6576. module.set.filtered();
  6577. },
  6578. userAddition: function() {
  6579. $item.filter(selector.addition).remove();
  6580. },
  6581. selected: function(value, $selectedItem) {
  6582. $selectedItem = (settings.allowAdditions)
  6583. ? $selectedItem || module.get.itemWithAdditions(value)
  6584. : $selectedItem || module.get.item(value)
  6585. ;
  6586. if(!$selectedItem) {
  6587. return false;
  6588. }
  6589. $selectedItem
  6590. .each(function() {
  6591. var
  6592. $selected = $(this),
  6593. selectedText = module.get.choiceText($selected),
  6594. selectedValue = module.get.choiceValue($selected, selectedText)
  6595. ;
  6596. if(module.is.multiple()) {
  6597. if(settings.useLabels) {
  6598. module.remove.value(selectedValue, selectedText, $selected);
  6599. module.remove.label(selectedValue);
  6600. }
  6601. else {
  6602. module.remove.value(selectedValue, selectedText, $selected);
  6603. if(module.get.selectionCount() === 0) {
  6604. module.set.placeholderText();
  6605. }
  6606. else {
  6607. module.set.text(module.add.variables(message.count));
  6608. }
  6609. }
  6610. }
  6611. else {
  6612. module.remove.value(selectedValue, selectedText, $selected);
  6613. }
  6614. $selected
  6615. .removeClass(className.filtered)
  6616. .removeClass(className.active)
  6617. ;
  6618. if(settings.useLabels) {
  6619. $selected.removeClass(className.selected);
  6620. }
  6621. })
  6622. ;
  6623. },
  6624. selectedItem: function() {
  6625. $item.removeClass(className.selected);
  6626. },
  6627. value: function(removedValue, removedText, $removedItem) {
  6628. var
  6629. values = module.get.values(),
  6630. newValue
  6631. ;
  6632. if( module.has.selectInput() ) {
  6633. module.verbose('Input is <select> removing selected option', removedValue);
  6634. newValue = module.remove.arrayValue(removedValue, values);
  6635. module.remove.optionValue(removedValue);
  6636. }
  6637. else {
  6638. module.verbose('Removing from delimited values', removedValue);
  6639. newValue = module.remove.arrayValue(removedValue, values);
  6640. newValue = newValue.join(settings.delimiter);
  6641. }
  6642. if(settings.fireOnInit === false && module.is.initialLoad()) {
  6643. module.verbose('No callback on initial load', settings.onRemove);
  6644. }
  6645. else {
  6646. settings.onRemove.call(element, removedValue, removedText, $removedItem);
  6647. }
  6648. module.set.value(newValue, removedText, $removedItem);
  6649. module.check.maxSelections();
  6650. },
  6651. arrayValue: function(removedValue, values) {
  6652. if( !$.isArray(values) ) {
  6653. values = [values];
  6654. }
  6655. values = $.grep(values, function(value){
  6656. return (removedValue != value);
  6657. });
  6658. module.verbose('Removed value from delimited string', removedValue, values);
  6659. return values;
  6660. },
  6661. label: function(value, shouldAnimate) {
  6662. var
  6663. $labels = $module.find(selector.label),
  6664. $removedLabel = $labels.filter('[data-value="' + value +'"]')
  6665. ;
  6666. module.verbose('Removing label', $removedLabel);
  6667. $removedLabel.remove();
  6668. },
  6669. activeLabels: function($activeLabels) {
  6670. $activeLabels = $activeLabels || $module.find(selector.label).filter('.' + className.active);
  6671. module.verbose('Removing active label selections', $activeLabels);
  6672. module.remove.labels($activeLabels);
  6673. },
  6674. labels: function($labels) {
  6675. $labels = $labels || $module.find(selector.label);
  6676. module.verbose('Removing labels', $labels);
  6677. $labels
  6678. .each(function(){
  6679. var
  6680. $label = $(this),
  6681. value = $label.data(metadata.value),
  6682. stringValue = (value !== undefined)
  6683. ? String(value)
  6684. : value,
  6685. isUserValue = module.is.userValue(stringValue)
  6686. ;
  6687. if(settings.onLabelRemove.call($label, value) === false) {
  6688. module.debug('Label remove callback cancelled removal');
  6689. return;
  6690. }
  6691. module.remove.message();
  6692. if(isUserValue) {
  6693. module.remove.value(stringValue);
  6694. module.remove.label(stringValue);
  6695. }
  6696. else {
  6697. // selected will also remove label
  6698. module.remove.selected(stringValue);
  6699. }
  6700. })
  6701. ;
  6702. },
  6703. tabbable: function() {
  6704. if( module.has.search() ) {
  6705. module.debug('Searchable dropdown initialized');
  6706. $search
  6707. .removeAttr('tabindex')
  6708. ;
  6709. $menu
  6710. .removeAttr('tabindex')
  6711. ;
  6712. }
  6713. else {
  6714. module.debug('Simple selection dropdown initialized');
  6715. $module
  6716. .removeAttr('tabindex')
  6717. ;
  6718. $menu
  6719. .removeAttr('tabindex')
  6720. ;
  6721. }
  6722. }
  6723. },
  6724. has: {
  6725. menuSearch: function() {
  6726. return (module.has.search() && $search.closest($menu).length > 0);
  6727. },
  6728. search: function() {
  6729. return ($search.length > 0);
  6730. },
  6731. sizer: function() {
  6732. return ($sizer.length > 0);
  6733. },
  6734. selectInput: function() {
  6735. return ( $input.is('select') );
  6736. },
  6737. minCharacters: function(searchTerm) {
  6738. if(settings.minCharacters) {
  6739. searchTerm = (searchTerm !== undefined)
  6740. ? String(searchTerm)
  6741. : String(module.get.query())
  6742. ;
  6743. return (searchTerm.length >= settings.minCharacters);
  6744. }
  6745. return true;
  6746. },
  6747. firstLetter: function($item, letter) {
  6748. var
  6749. text,
  6750. firstLetter
  6751. ;
  6752. if(!$item || $item.length === 0 || typeof letter !== 'string') {
  6753. return false;
  6754. }
  6755. text = module.get.choiceText($item, false);
  6756. letter = letter.toLowerCase();
  6757. firstLetter = String(text).charAt(0).toLowerCase();
  6758. return (letter == firstLetter);
  6759. },
  6760. input: function() {
  6761. return ($input.length > 0);
  6762. },
  6763. items: function() {
  6764. return ($item.length > 0);
  6765. },
  6766. menu: function() {
  6767. return ($menu.length > 0);
  6768. },
  6769. message: function() {
  6770. return ($menu.children(selector.message).length !== 0);
  6771. },
  6772. label: function(value) {
  6773. var
  6774. escapedValue = module.escape.value(value),
  6775. $labels = $module.find(selector.label)
  6776. ;
  6777. return ($labels.filter('[data-value="' + escapedValue +'"]').length > 0);
  6778. },
  6779. maxSelections: function() {
  6780. return (settings.maxSelections && module.get.selectionCount() >= settings.maxSelections);
  6781. },
  6782. allResultsFiltered: function() {
  6783. var
  6784. $normalResults = $item.not(selector.addition)
  6785. ;
  6786. return ($normalResults.filter(selector.unselectable).length === $normalResults.length);
  6787. },
  6788. userSuggestion: function() {
  6789. return ($menu.children(selector.addition).length > 0);
  6790. },
  6791. query: function() {
  6792. return (module.get.query() !== '');
  6793. },
  6794. value: function(value) {
  6795. var
  6796. values = module.get.values(),
  6797. hasValue = $.isArray(values)
  6798. ? values && ($.inArray(value, values) !== -1)
  6799. : (values == value)
  6800. ;
  6801. return (hasValue)
  6802. ? true
  6803. : false
  6804. ;
  6805. }
  6806. },
  6807. is: {
  6808. active: function() {
  6809. return $module.hasClass(className.active);
  6810. },
  6811. bubbledLabelClick: function(event) {
  6812. return $(event.target).is('select, input') && $module.closest('label').length > 0;
  6813. },
  6814. bubbledIconClick: function(event) {
  6815. return $(event.target).closest($icon).length > 0;
  6816. },
  6817. alreadySetup: function() {
  6818. return ($module.is('select') && $module.parent(selector.dropdown).length > 0 && $module.prev().length === 0);
  6819. },
  6820. animating: function($subMenu) {
  6821. return ($subMenu)
  6822. ? $subMenu.transition && $subMenu.transition('is animating')
  6823. : $menu.transition && $menu.transition('is animating')
  6824. ;
  6825. },
  6826. disabled: function() {
  6827. return $module.hasClass(className.disabled);
  6828. },
  6829. focused: function() {
  6830. return (document.activeElement === $module[0]);
  6831. },
  6832. focusedOnSearch: function() {
  6833. return (document.activeElement === $search[0]);
  6834. },
  6835. allFiltered: function() {
  6836. return( (module.is.multiple() || module.has.search()) && !(settings.hideAdditions == false && module.has.userSuggestion()) && !module.has.message() && module.has.allResultsFiltered() );
  6837. },
  6838. hidden: function($subMenu) {
  6839. return !module.is.visible($subMenu);
  6840. },
  6841. initialLoad: function() {
  6842. return initialLoad;
  6843. },
  6844. onScreen: function($subMenu) {
  6845. var
  6846. $currentMenu = $subMenu || $menu,
  6847. canOpenDownward = true,
  6848. onScreen = {},
  6849. calculations
  6850. ;
  6851. $currentMenu.addClass(className.loading);
  6852. calculations = {
  6853. context: {
  6854. scrollTop : $context.scrollTop(),
  6855. height : $context.outerHeight()
  6856. },
  6857. menu : {
  6858. offset: $currentMenu.offset(),
  6859. height: $currentMenu.outerHeight()
  6860. }
  6861. };
  6862. onScreen = {
  6863. above : (calculations.context.scrollTop) <= calculations.menu.offset.top - calculations.menu.height,
  6864. below : (calculations.context.scrollTop + calculations.context.height) >= calculations.menu.offset.top + calculations.menu.height
  6865. };
  6866. if(onScreen.below) {
  6867. module.verbose('Dropdown can fit in context downward', onScreen);
  6868. canOpenDownward = true;
  6869. }
  6870. else if(!onScreen.below && !onScreen.above) {
  6871. module.verbose('Dropdown cannot fit in either direction, favoring downward', onScreen);
  6872. canOpenDownward = true;
  6873. }
  6874. else {
  6875. module.verbose('Dropdown cannot fit below, opening upward', onScreen);
  6876. canOpenDownward = false;
  6877. }
  6878. $currentMenu.removeClass(className.loading);
  6879. return canOpenDownward;
  6880. },
  6881. inObject: function(needle, object) {
  6882. var
  6883. found = false
  6884. ;
  6885. $.each(object, function(index, property) {
  6886. if(property == needle) {
  6887. found = true;
  6888. return true;
  6889. }
  6890. });
  6891. return found;
  6892. },
  6893. multiple: function() {
  6894. return $module.hasClass(className.multiple);
  6895. },
  6896. single: function() {
  6897. return !module.is.multiple();
  6898. },
  6899. selectMutation: function(mutations) {
  6900. var
  6901. selectChanged = false
  6902. ;
  6903. $.each(mutations, function(index, mutation) {
  6904. if(mutation.target && $(mutation.target).is('select')) {
  6905. selectChanged = true;
  6906. return true;
  6907. }
  6908. });
  6909. return selectChanged;
  6910. },
  6911. search: function() {
  6912. return $module.hasClass(className.search);
  6913. },
  6914. searchSelection: function() {
  6915. return ( module.has.search() && $search.parent(selector.dropdown).length === 1 );
  6916. },
  6917. selection: function() {
  6918. return $module.hasClass(className.selection);
  6919. },
  6920. userValue: function(value) {
  6921. return ($.inArray(value, module.get.userValues()) !== -1);
  6922. },
  6923. upward: function($menu) {
  6924. var $element = $menu || $module;
  6925. return $element.hasClass(className.upward);
  6926. },
  6927. visible: function($subMenu) {
  6928. return ($subMenu)
  6929. ? $subMenu.hasClass(className.visible)
  6930. : $menu.hasClass(className.visible)
  6931. ;
  6932. }
  6933. },
  6934. can: {
  6935. activate: function($item) {
  6936. if(settings.useLabels) {
  6937. return true;
  6938. }
  6939. if(!module.has.maxSelections()) {
  6940. return true;
  6941. }
  6942. if(module.has.maxSelections() && $item.hasClass(className.active)) {
  6943. return true;
  6944. }
  6945. return false;
  6946. },
  6947. click: function() {
  6948. return (hasTouch || settings.on == 'click');
  6949. },
  6950. extendSelect: function() {
  6951. return settings.allowAdditions || settings.apiSettings;
  6952. },
  6953. show: function() {
  6954. return !module.is.disabled() && (module.has.items() || module.has.message());
  6955. },
  6956. useAPI: function() {
  6957. return $.fn.api !== undefined;
  6958. }
  6959. },
  6960. animate: {
  6961. show: function(callback, $subMenu) {
  6962. var
  6963. $currentMenu = $subMenu || $menu,
  6964. start = ($subMenu)
  6965. ? function() {}
  6966. : function() {
  6967. module.hideSubMenus();
  6968. module.hideOthers();
  6969. module.set.active();
  6970. },
  6971. transition
  6972. ;
  6973. callback = $.isFunction(callback)
  6974. ? callback
  6975. : function(){}
  6976. ;
  6977. module.verbose('Doing menu show animation', $currentMenu);
  6978. module.set.direction($subMenu);
  6979. transition = module.get.transition($subMenu);
  6980. if( module.is.selection() ) {
  6981. module.set.scrollPosition(module.get.selectedItem(), true);
  6982. }
  6983. if( module.is.hidden($currentMenu) || module.is.animating($currentMenu) ) {
  6984. if(transition == 'none') {
  6985. start();
  6986. $currentMenu.transition('show');
  6987. callback.call(element);
  6988. }
  6989. else if($.fn.transition !== undefined && $module.transition('is supported')) {
  6990. $currentMenu
  6991. .transition({
  6992. animation : transition + ' in',
  6993. debug : settings.debug,
  6994. verbose : settings.verbose,
  6995. duration : settings.duration,
  6996. queue : true,
  6997. onStart : start,
  6998. onComplete : function() {
  6999. callback.call(element);
  7000. }
  7001. })
  7002. ;
  7003. }
  7004. else {
  7005. module.error(error.noTransition, transition);
  7006. }
  7007. }
  7008. },
  7009. hide: function(callback, $subMenu) {
  7010. var
  7011. $currentMenu = $subMenu || $menu,
  7012. duration = ($subMenu)
  7013. ? (settings.duration * 0.9)
  7014. : settings.duration,
  7015. start = ($subMenu)
  7016. ? function() {}
  7017. : function() {
  7018. if( module.can.click() ) {
  7019. module.unbind.intent();
  7020. }
  7021. module.remove.active();
  7022. },
  7023. transition = module.get.transition($subMenu)
  7024. ;
  7025. callback = $.isFunction(callback)
  7026. ? callback
  7027. : function(){}
  7028. ;
  7029. if( module.is.visible($currentMenu) || module.is.animating($currentMenu) ) {
  7030. module.verbose('Doing menu hide animation', $currentMenu);
  7031. if(transition == 'none') {
  7032. start();
  7033. $currentMenu.transition('hide');
  7034. callback.call(element);
  7035. }
  7036. else if($.fn.transition !== undefined && $module.transition('is supported')) {
  7037. $currentMenu
  7038. .transition({
  7039. animation : transition + ' out',
  7040. duration : settings.duration,
  7041. debug : settings.debug,
  7042. verbose : settings.verbose,
  7043. queue : true,
  7044. onStart : start,
  7045. onComplete : function() {
  7046. if(settings.direction == 'auto') {
  7047. module.remove.upward($subMenu);
  7048. }
  7049. callback.call(element);
  7050. }
  7051. })
  7052. ;
  7053. }
  7054. else {
  7055. module.error(error.transition);
  7056. }
  7057. }
  7058. }
  7059. },
  7060. hideAndClear: function() {
  7061. module.remove.searchTerm();
  7062. if( module.has.maxSelections() ) {
  7063. return;
  7064. }
  7065. if(module.has.search()) {
  7066. module.hide(function() {
  7067. module.remove.filteredItem();
  7068. });
  7069. }
  7070. else {
  7071. module.hide();
  7072. }
  7073. },
  7074. delay: {
  7075. show: function() {
  7076. module.verbose('Delaying show event to ensure user intent');
  7077. clearTimeout(module.timer);
  7078. module.timer = setTimeout(module.show, settings.delay.show);
  7079. },
  7080. hide: function() {
  7081. module.verbose('Delaying hide event to ensure user intent');
  7082. clearTimeout(module.timer);
  7083. module.timer = setTimeout(module.hide, settings.delay.hide);
  7084. }
  7085. },
  7086. escape: {
  7087. value: function(value) {
  7088. var
  7089. multipleValues = $.isArray(value),
  7090. stringValue = (typeof value === 'string'),
  7091. isUnparsable = (!stringValue && !multipleValues),
  7092. hasQuotes = (stringValue && value.search(regExp.quote) !== -1),
  7093. values = []
  7094. ;
  7095. if(!module.has.selectInput() || isUnparsable || !hasQuotes) {
  7096. return value;
  7097. }
  7098. module.debug('Encoding quote values for use in select', value);
  7099. if(multipleValues) {
  7100. $.each(value, function(index, value){
  7101. values.push(value.replace(regExp.quote, '&quot;'));
  7102. });
  7103. return values;
  7104. }
  7105. return value.replace(regExp.quote, '&quot;');
  7106. },
  7107. regExp: function(text) {
  7108. text = String(text);
  7109. return text.replace(regExp.escape, '\\$&');
  7110. }
  7111. },
  7112. setting: function(name, value) {
  7113. module.debug('Changing setting', name, value);
  7114. if( $.isPlainObject(name) ) {
  7115. $.extend(true, settings, name);
  7116. }
  7117. else if(value !== undefined) {
  7118. if($.isPlainObject(settings[name])) {
  7119. $.extend(true, settings[name], value);
  7120. }
  7121. else {
  7122. settings[name] = value;
  7123. }
  7124. }
  7125. else {
  7126. return settings[name];
  7127. }
  7128. },
  7129. internal: function(name, value) {
  7130. if( $.isPlainObject(name) ) {
  7131. $.extend(true, module, name);
  7132. }
  7133. else if(value !== undefined) {
  7134. module[name] = value;
  7135. }
  7136. else {
  7137. return module[name];
  7138. }
  7139. },
  7140. debug: function() {
  7141. if(!settings.silent && settings.debug) {
  7142. if(settings.performance) {
  7143. module.performance.log(arguments);
  7144. }
  7145. else {
  7146. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  7147. module.debug.apply(console, arguments);
  7148. }
  7149. }
  7150. },
  7151. verbose: function() {
  7152. if(!settings.silent && settings.verbose && settings.debug) {
  7153. if(settings.performance) {
  7154. module.performance.log(arguments);
  7155. }
  7156. else {
  7157. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  7158. module.verbose.apply(console, arguments);
  7159. }
  7160. }
  7161. },
  7162. error: function() {
  7163. if(!settings.silent) {
  7164. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  7165. module.error.apply(console, arguments);
  7166. }
  7167. },
  7168. performance: {
  7169. log: function(message) {
  7170. var
  7171. currentTime,
  7172. executionTime,
  7173. previousTime
  7174. ;
  7175. if(settings.performance) {
  7176. currentTime = new Date().getTime();
  7177. previousTime = time || currentTime;
  7178. executionTime = currentTime - previousTime;
  7179. time = currentTime;
  7180. performance.push({
  7181. 'Name' : message[0],
  7182. 'Arguments' : [].slice.call(message, 1) || '',
  7183. 'Element' : element,
  7184. 'Execution Time' : executionTime
  7185. });
  7186. }
  7187. clearTimeout(module.performance.timer);
  7188. module.performance.timer = setTimeout(module.performance.display, 500);
  7189. },
  7190. display: function() {
  7191. var
  7192. title = settings.name + ':',
  7193. totalTime = 0
  7194. ;
  7195. time = false;
  7196. clearTimeout(module.performance.timer);
  7197. $.each(performance, function(index, data) {
  7198. totalTime += data['Execution Time'];
  7199. });
  7200. title += ' ' + totalTime + 'ms';
  7201. if(moduleSelector) {
  7202. title += ' \'' + moduleSelector + '\'';
  7203. }
  7204. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  7205. console.groupCollapsed(title);
  7206. if(console.table) {
  7207. console.table(performance);
  7208. }
  7209. else {
  7210. $.each(performance, function(index, data) {
  7211. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  7212. });
  7213. }
  7214. console.groupEnd();
  7215. }
  7216. performance = [];
  7217. }
  7218. },
  7219. invoke: function(query, passedArguments, context) {
  7220. var
  7221. object = instance,
  7222. maxDepth,
  7223. found,
  7224. response
  7225. ;
  7226. passedArguments = passedArguments || queryArguments;
  7227. context = element || context;
  7228. if(typeof query == 'string' && object !== undefined) {
  7229. query = query.split(/[\. ]/);
  7230. maxDepth = query.length - 1;
  7231. $.each(query, function(depth, value) {
  7232. var camelCaseValue = (depth != maxDepth)
  7233. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  7234. : query
  7235. ;
  7236. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  7237. object = object[camelCaseValue];
  7238. }
  7239. else if( object[camelCaseValue] !== undefined ) {
  7240. found = object[camelCaseValue];
  7241. return false;
  7242. }
  7243. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  7244. object = object[value];
  7245. }
  7246. else if( object[value] !== undefined ) {
  7247. found = object[value];
  7248. return false;
  7249. }
  7250. else {
  7251. module.error(error.method, query);
  7252. return false;
  7253. }
  7254. });
  7255. }
  7256. if ( $.isFunction( found ) ) {
  7257. response = found.apply(context, passedArguments);
  7258. }
  7259. else if(found !== undefined) {
  7260. response = found;
  7261. }
  7262. if($.isArray(returnedValue)) {
  7263. returnedValue.push(response);
  7264. }
  7265. else if(returnedValue !== undefined) {
  7266. returnedValue = [returnedValue, response];
  7267. }
  7268. else if(response !== undefined) {
  7269. returnedValue = response;
  7270. }
  7271. return found;
  7272. }
  7273. };
  7274. if(methodInvoked) {
  7275. if(instance === undefined) {
  7276. module.initialize();
  7277. }
  7278. module.invoke(query);
  7279. }
  7280. else {
  7281. if(instance !== undefined) {
  7282. instance.invoke('destroy');
  7283. }
  7284. module.initialize();
  7285. }
  7286. })
  7287. ;
  7288. return (returnedValue !== undefined)
  7289. ? returnedValue
  7290. : $allModules
  7291. ;
  7292. };
  7293. $.fn.dropdown.settings = {
  7294. silent : false,
  7295. debug : false,
  7296. verbose : false,
  7297. performance : true,
  7298. on : 'click', // what event should show menu action on item selection
  7299. action : 'activate', // action on item selection (nothing, activate, select, combo, hide, function(){})
  7300. apiSettings : false,
  7301. selectOnKeydown : true, // Whether selection should occur automatically when keyboard shortcuts used
  7302. minCharacters : 0, // Minimum characters required to trigger API call
  7303. saveRemoteData : true, // Whether remote name/value pairs should be stored in sessionStorage to allow remote data to be restored on page refresh
  7304. throttle : 200, // How long to wait after last user input to search remotely
  7305. context : window, // Context to use when determining if on screen
  7306. direction : 'auto', // Whether dropdown should always open in one direction
  7307. keepOnScreen : true, // Whether dropdown should check whether it is on screen before showing
  7308. match : 'both', // what to match against with search selection (both, text, or label)
  7309. fullTextSearch : false, // search anywhere in value (set to 'exact' to require exact matches)
  7310. placeholder : 'auto', // whether to convert blank <select> values to placeholder text
  7311. preserveHTML : true, // preserve html when selecting value
  7312. sortSelect : false, // sort selection on init
  7313. forceSelection : true, // force a choice on blur with search selection
  7314. allowAdditions : false, // whether multiple select should allow user added values
  7315. hideAdditions : true, // whether or not to hide special message prompting a user they can enter a value
  7316. maxSelections : false, // When set to a number limits the number of selections to this count
  7317. useLabels : true, // whether multiple select should filter currently active selections from choices
  7318. delimiter : ',', // when multiselect uses normal <input> the values will be delimited with this character
  7319. showOnFocus : true, // show menu on focus
  7320. allowReselection : false, // whether current value should trigger callbacks when reselected
  7321. allowTab : true, // add tabindex to element
  7322. allowCategorySelection : false, // allow elements with sub-menus to be selected
  7323. fireOnInit : false, // Whether callbacks should fire when initializing dropdown values
  7324. transition : 'auto', // auto transition will slide down or up based on direction
  7325. duration : 200, // duration of transition
  7326. glyphWidth : 1.037, // widest glyph width in em (W is 1.037 em) used to calculate multiselect input width
  7327. // label settings on multi-select
  7328. label: {
  7329. transition : 'scale',
  7330. duration : 200,
  7331. variation : false
  7332. },
  7333. // delay before event
  7334. delay : {
  7335. hide : 300,
  7336. show : 200,
  7337. search : 20,
  7338. touch : 50
  7339. },
  7340. /* Callbacks */
  7341. onChange : function(value, text, $selected){},
  7342. onAdd : function(value, text, $selected){},
  7343. onRemove : function(value, text, $selected){},
  7344. onLabelSelect : function($selectedLabels){},
  7345. onLabelCreate : function(value, text) { return $(this); },
  7346. onLabelRemove : function(value) { return true; },
  7347. onNoResults : function(searchTerm) { return true; },
  7348. onShow : function(){},
  7349. onHide : function(){},
  7350. /* Component */
  7351. name : 'Dropdown',
  7352. namespace : 'dropdown',
  7353. message: {
  7354. addResult : 'Add <b>{term}</b>',
  7355. count : '{count} selected',
  7356. maxSelections : 'Max {maxCount} selections',
  7357. noResults : 'No results found.',
  7358. serverError : 'There was an error contacting the server'
  7359. },
  7360. error : {
  7361. action : 'You called a dropdown action that was not defined',
  7362. alreadySetup : 'Once a select has been initialized behaviors must be called on the created ui dropdown',
  7363. labels : 'Allowing user additions currently requires the use of labels.',
  7364. missingMultiple : '<select> requires multiple property to be set to correctly preserve multiple values',
  7365. method : 'The method you called is not defined.',
  7366. noAPI : 'The API module is required to load resources remotely',
  7367. noStorage : 'Saving remote data requires session storage',
  7368. noTransition : 'This module requires ui transitions <https://github.com/Semantic-Org/UI-Transition>'
  7369. },
  7370. regExp : {
  7371. escape : /[-[\]{}()*+?.,\\^$|#\s]/g,
  7372. quote : /"/g
  7373. },
  7374. metadata : {
  7375. defaultText : 'defaultText',
  7376. defaultValue : 'defaultValue',
  7377. placeholderText : 'placeholder',
  7378. text : 'text',
  7379. value : 'value'
  7380. },
  7381. // property names for remote query
  7382. fields: {
  7383. remoteValues : 'results', // grouping for api results
  7384. values : 'values', // grouping for all dropdown values
  7385. disabled : 'disabled', // whether value should be disabled
  7386. name : 'name', // displayed dropdown text
  7387. value : 'value', // actual dropdown value
  7388. text : 'text' // displayed text when selected
  7389. },
  7390. keys : {
  7391. backspace : 8,
  7392. delimiter : 188, // comma
  7393. deleteKey : 46,
  7394. enter : 13,
  7395. escape : 27,
  7396. pageUp : 33,
  7397. pageDown : 34,
  7398. leftArrow : 37,
  7399. upArrow : 38,
  7400. rightArrow : 39,
  7401. downArrow : 40
  7402. },
  7403. selector : {
  7404. addition : '.addition',
  7405. dropdown : '.ui.dropdown',
  7406. hidden : '.hidden',
  7407. icon : '> .dropdown.icon',
  7408. input : '> input[type="hidden"], > select',
  7409. item : '.item',
  7410. label : '> .label',
  7411. remove : '> .label > .delete.icon',
  7412. siblingLabel : '.label',
  7413. menu : '.menu',
  7414. message : '.message',
  7415. menuIcon : '.dropdown.icon',
  7416. search : 'input.search, .menu > .search > input, .menu input.search',
  7417. sizer : '> input.sizer',
  7418. text : '> .text:not(.icon)',
  7419. unselectable : '.disabled, .filtered'
  7420. },
  7421. className : {
  7422. active : 'active',
  7423. addition : 'addition',
  7424. animating : 'animating',
  7425. disabled : 'disabled',
  7426. empty : 'empty',
  7427. dropdown : 'ui dropdown',
  7428. filtered : 'filtered',
  7429. hidden : 'hidden transition',
  7430. item : 'item',
  7431. label : 'ui label',
  7432. loading : 'loading',
  7433. menu : 'menu',
  7434. message : 'message',
  7435. multiple : 'multiple',
  7436. placeholder : 'default',
  7437. sizer : 'sizer',
  7438. search : 'search',
  7439. selected : 'selected',
  7440. selection : 'selection',
  7441. upward : 'upward',
  7442. visible : 'visible'
  7443. }
  7444. };
  7445. /* Templates */
  7446. $.fn.dropdown.settings.templates = {
  7447. // generates dropdown from select values
  7448. dropdown: function(select) {
  7449. var
  7450. placeholder = select.placeholder || false,
  7451. values = select.values || {},
  7452. html = ''
  7453. ;
  7454. html += '<i class="dropdown icon"></i>';
  7455. if(select.placeholder) {
  7456. html += '<div class="default text">' + placeholder + '</div>';
  7457. }
  7458. else {
  7459. html += '<div class="text"></div>';
  7460. }
  7461. html += '<div class="menu">';
  7462. $.each(select.values, function(index, option) {
  7463. html += (option.disabled)
  7464. ? '<div class="disabled item" data-value="' + option.value + '">' + option.name + '</div>'
  7465. : '<div class="item" data-value="' + option.value + '">' + option.name + '</div>'
  7466. ;
  7467. });
  7468. html += '</div>';
  7469. return html;
  7470. },
  7471. // generates just menu from select
  7472. menu: function(response, fields) {
  7473. var
  7474. values = response[fields.values] || {},
  7475. html = ''
  7476. ;
  7477. $.each(values, function(index, option) {
  7478. var
  7479. maybeText = (option[fields.text])
  7480. ? 'data-text="' + option[fields.text] + '"'
  7481. : '',
  7482. maybeDisabled = (option[fields.disabled])
  7483. ? 'disabled '
  7484. : ''
  7485. ;
  7486. html += '<div class="'+ maybeDisabled +'item" data-value="' + option[fields.value] + '"' + maybeText + '>'
  7487. html += option[fields.name];
  7488. html += '</div>';
  7489. });
  7490. return html;
  7491. },
  7492. // generates label for multiselect
  7493. label: function(value, text) {
  7494. return text + '<i class="delete icon"></i>';
  7495. },
  7496. // generates messages like "No results"
  7497. message: function(message) {
  7498. return message;
  7499. },
  7500. // generates user addition to selection menu
  7501. addition: function(choice) {
  7502. return choice;
  7503. }
  7504. };
  7505. })( jQuery, window, document );
  7506. /*!
  7507. * # Semantic UI 2.2.6 - Embed
  7508. * http://github.com/semantic-org/semantic-ui/
  7509. *
  7510. *
  7511. * Released under the MIT license
  7512. * http://opensource.org/licenses/MIT
  7513. *
  7514. */
  7515. ;(function ($, window, document, undefined) {
  7516. "use strict";
  7517. window = (typeof window != 'undefined' && window.Math == Math)
  7518. ? window
  7519. : (typeof self != 'undefined' && self.Math == Math)
  7520. ? self
  7521. : Function('return this')()
  7522. ;
  7523. $.fn.embed = function(parameters) {
  7524. var
  7525. $allModules = $(this),
  7526. moduleSelector = $allModules.selector || '',
  7527. time = new Date().getTime(),
  7528. performance = [],
  7529. query = arguments[0],
  7530. methodInvoked = (typeof query == 'string'),
  7531. queryArguments = [].slice.call(arguments, 1),
  7532. returnedValue
  7533. ;
  7534. $allModules
  7535. .each(function() {
  7536. var
  7537. settings = ( $.isPlainObject(parameters) )
  7538. ? $.extend(true, {}, $.fn.embed.settings, parameters)
  7539. : $.extend({}, $.fn.embed.settings),
  7540. selector = settings.selector,
  7541. className = settings.className,
  7542. sources = settings.sources,
  7543. error = settings.error,
  7544. metadata = settings.metadata,
  7545. namespace = settings.namespace,
  7546. templates = settings.templates,
  7547. eventNamespace = '.' + namespace,
  7548. moduleNamespace = 'module-' + namespace,
  7549. $window = $(window),
  7550. $module = $(this),
  7551. $placeholder = $module.find(selector.placeholder),
  7552. $icon = $module.find(selector.icon),
  7553. $embed = $module.find(selector.embed),
  7554. element = this,
  7555. instance = $module.data(moduleNamespace),
  7556. module
  7557. ;
  7558. module = {
  7559. initialize: function() {
  7560. module.debug('Initializing embed');
  7561. module.determine.autoplay();
  7562. module.create();
  7563. module.bind.events();
  7564. module.instantiate();
  7565. },
  7566. instantiate: function() {
  7567. module.verbose('Storing instance of module', module);
  7568. instance = module;
  7569. $module
  7570. .data(moduleNamespace, module)
  7571. ;
  7572. },
  7573. destroy: function() {
  7574. module.verbose('Destroying previous instance of embed');
  7575. module.reset();
  7576. $module
  7577. .removeData(moduleNamespace)
  7578. .off(eventNamespace)
  7579. ;
  7580. },
  7581. refresh: function() {
  7582. module.verbose('Refreshing selector cache');
  7583. $placeholder = $module.find(selector.placeholder);
  7584. $icon = $module.find(selector.icon);
  7585. $embed = $module.find(selector.embed);
  7586. },
  7587. bind: {
  7588. events: function() {
  7589. if( module.has.placeholder() ) {
  7590. module.debug('Adding placeholder events');
  7591. $module
  7592. .on('click' + eventNamespace, selector.placeholder, module.createAndShow)
  7593. .on('click' + eventNamespace, selector.icon, module.createAndShow)
  7594. ;
  7595. }
  7596. }
  7597. },
  7598. create: function() {
  7599. var
  7600. placeholder = module.get.placeholder()
  7601. ;
  7602. if(placeholder) {
  7603. module.createPlaceholder();
  7604. }
  7605. else {
  7606. module.createAndShow();
  7607. }
  7608. },
  7609. createPlaceholder: function(placeholder) {
  7610. var
  7611. icon = module.get.icon(),
  7612. url = module.get.url(),
  7613. embed = module.generate.embed(url)
  7614. ;
  7615. placeholder = placeholder || module.get.placeholder();
  7616. $module.html( templates.placeholder(placeholder, icon) );
  7617. module.debug('Creating placeholder for embed', placeholder, icon);
  7618. },
  7619. createEmbed: function(url) {
  7620. module.refresh();
  7621. url = url || module.get.url();
  7622. $embed = $('<div/>')
  7623. .addClass(className.embed)
  7624. .html( module.generate.embed(url) )
  7625. .appendTo($module)
  7626. ;
  7627. settings.onCreate.call(element, url);
  7628. module.debug('Creating embed object', $embed);
  7629. },
  7630. changeEmbed: function(url) {
  7631. $embed
  7632. .html( module.generate.embed(url) )
  7633. ;
  7634. },
  7635. createAndShow: function() {
  7636. module.createEmbed();
  7637. module.show();
  7638. },
  7639. // sets new embed
  7640. change: function(source, id, url) {
  7641. module.debug('Changing video to ', source, id, url);
  7642. $module
  7643. .data(metadata.source, source)
  7644. .data(metadata.id, id)
  7645. ;
  7646. if(url) {
  7647. $module.data(metadata.url, url);
  7648. }
  7649. else {
  7650. $module.removeData(metadata.url);
  7651. }
  7652. if(module.has.embed()) {
  7653. module.changeEmbed();
  7654. }
  7655. else {
  7656. module.create();
  7657. }
  7658. },
  7659. // clears embed
  7660. reset: function() {
  7661. module.debug('Clearing embed and showing placeholder');
  7662. module.remove.active();
  7663. module.remove.embed();
  7664. module.showPlaceholder();
  7665. settings.onReset.call(element);
  7666. },
  7667. // shows current embed
  7668. show: function() {
  7669. module.debug('Showing embed');
  7670. module.set.active();
  7671. settings.onDisplay.call(element);
  7672. },
  7673. hide: function() {
  7674. module.debug('Hiding embed');
  7675. module.showPlaceholder();
  7676. },
  7677. showPlaceholder: function() {
  7678. module.debug('Showing placeholder image');
  7679. module.remove.active();
  7680. settings.onPlaceholderDisplay.call(element);
  7681. },
  7682. get: {
  7683. id: function() {
  7684. return settings.id || $module.data(metadata.id);
  7685. },
  7686. placeholder: function() {
  7687. return settings.placeholder || $module.data(metadata.placeholder);
  7688. },
  7689. icon: function() {
  7690. return (settings.icon)
  7691. ? settings.icon
  7692. : ($module.data(metadata.icon) !== undefined)
  7693. ? $module.data(metadata.icon)
  7694. : module.determine.icon()
  7695. ;
  7696. },
  7697. source: function(url) {
  7698. return (settings.source)
  7699. ? settings.source
  7700. : ($module.data(metadata.source) !== undefined)
  7701. ? $module.data(metadata.source)
  7702. : module.determine.source()
  7703. ;
  7704. },
  7705. type: function() {
  7706. var source = module.get.source();
  7707. return (sources[source] !== undefined)
  7708. ? sources[source].type
  7709. : false
  7710. ;
  7711. },
  7712. url: function() {
  7713. return (settings.url)
  7714. ? settings.url
  7715. : ($module.data(metadata.url) !== undefined)
  7716. ? $module.data(metadata.url)
  7717. : module.determine.url()
  7718. ;
  7719. }
  7720. },
  7721. determine: {
  7722. autoplay: function() {
  7723. if(module.should.autoplay()) {
  7724. settings.autoplay = true;
  7725. }
  7726. },
  7727. source: function(url) {
  7728. var
  7729. matchedSource = false
  7730. ;
  7731. url = url || module.get.url();
  7732. if(url) {
  7733. $.each(sources, function(name, source) {
  7734. if(url.search(source.domain) !== -1) {
  7735. matchedSource = name;
  7736. return false;
  7737. }
  7738. });
  7739. }
  7740. return matchedSource;
  7741. },
  7742. icon: function() {
  7743. var
  7744. source = module.get.source()
  7745. ;
  7746. return (sources[source] !== undefined)
  7747. ? sources[source].icon
  7748. : false
  7749. ;
  7750. },
  7751. url: function() {
  7752. var
  7753. id = settings.id || $module.data(metadata.id),
  7754. source = settings.source || $module.data(metadata.source),
  7755. url
  7756. ;
  7757. url = (sources[source] !== undefined)
  7758. ? sources[source].url.replace('{id}', id)
  7759. : false
  7760. ;
  7761. if(url) {
  7762. $module.data(metadata.url, url);
  7763. }
  7764. return url;
  7765. }
  7766. },
  7767. set: {
  7768. active: function() {
  7769. $module.addClass(className.active);
  7770. }
  7771. },
  7772. remove: {
  7773. active: function() {
  7774. $module.removeClass(className.active);
  7775. },
  7776. embed: function() {
  7777. $embed.empty();
  7778. }
  7779. },
  7780. encode: {
  7781. parameters: function(parameters) {
  7782. var
  7783. urlString = [],
  7784. index
  7785. ;
  7786. for (index in parameters) {
  7787. urlString.push( encodeURIComponent(index) + '=' + encodeURIComponent( parameters[index] ) );
  7788. }
  7789. return urlString.join('&amp;');
  7790. }
  7791. },
  7792. generate: {
  7793. embed: function(url) {
  7794. module.debug('Generating embed html');
  7795. var
  7796. source = module.get.source(),
  7797. html,
  7798. parameters
  7799. ;
  7800. url = module.get.url(url);
  7801. if(url) {
  7802. parameters = module.generate.parameters(source);
  7803. html = templates.iframe(url, parameters);
  7804. }
  7805. else {
  7806. module.error(error.noURL, $module);
  7807. }
  7808. return html;
  7809. },
  7810. parameters: function(source, extraParameters) {
  7811. var
  7812. parameters = (sources[source] && sources[source].parameters !== undefined)
  7813. ? sources[source].parameters(settings)
  7814. : {}
  7815. ;
  7816. extraParameters = extraParameters || settings.parameters;
  7817. if(extraParameters) {
  7818. parameters = $.extend({}, parameters, extraParameters);
  7819. }
  7820. parameters = settings.onEmbed(parameters);
  7821. return module.encode.parameters(parameters);
  7822. }
  7823. },
  7824. has: {
  7825. embed: function() {
  7826. return ($embed.length > 0);
  7827. },
  7828. placeholder: function() {
  7829. return settings.placeholder || $module.data(metadata.placeholder);
  7830. }
  7831. },
  7832. should: {
  7833. autoplay: function() {
  7834. return (settings.autoplay === 'auto')
  7835. ? (settings.placeholder || $module.data(metadata.placeholder) !== undefined)
  7836. : settings.autoplay
  7837. ;
  7838. }
  7839. },
  7840. is: {
  7841. video: function() {
  7842. return module.get.type() == 'video';
  7843. }
  7844. },
  7845. setting: function(name, value) {
  7846. module.debug('Changing setting', name, value);
  7847. if( $.isPlainObject(name) ) {
  7848. $.extend(true, settings, name);
  7849. }
  7850. else if(value !== undefined) {
  7851. if($.isPlainObject(settings[name])) {
  7852. $.extend(true, settings[name], value);
  7853. }
  7854. else {
  7855. settings[name] = value;
  7856. }
  7857. }
  7858. else {
  7859. return settings[name];
  7860. }
  7861. },
  7862. internal: function(name, value) {
  7863. if( $.isPlainObject(name) ) {
  7864. $.extend(true, module, name);
  7865. }
  7866. else if(value !== undefined) {
  7867. module[name] = value;
  7868. }
  7869. else {
  7870. return module[name];
  7871. }
  7872. },
  7873. debug: function() {
  7874. if(!settings.silent && settings.debug) {
  7875. if(settings.performance) {
  7876. module.performance.log(arguments);
  7877. }
  7878. else {
  7879. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  7880. module.debug.apply(console, arguments);
  7881. }
  7882. }
  7883. },
  7884. verbose: function() {
  7885. if(!settings.silent && settings.verbose && settings.debug) {
  7886. if(settings.performance) {
  7887. module.performance.log(arguments);
  7888. }
  7889. else {
  7890. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  7891. module.verbose.apply(console, arguments);
  7892. }
  7893. }
  7894. },
  7895. error: function() {
  7896. if(!settings.silent) {
  7897. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  7898. module.error.apply(console, arguments);
  7899. }
  7900. },
  7901. performance: {
  7902. log: function(message) {
  7903. var
  7904. currentTime,
  7905. executionTime,
  7906. previousTime
  7907. ;
  7908. if(settings.performance) {
  7909. currentTime = new Date().getTime();
  7910. previousTime = time || currentTime;
  7911. executionTime = currentTime - previousTime;
  7912. time = currentTime;
  7913. performance.push({
  7914. 'Name' : message[0],
  7915. 'Arguments' : [].slice.call(message, 1) || '',
  7916. 'Element' : element,
  7917. 'Execution Time' : executionTime
  7918. });
  7919. }
  7920. clearTimeout(module.performance.timer);
  7921. module.performance.timer = setTimeout(module.performance.display, 500);
  7922. },
  7923. display: function() {
  7924. var
  7925. title = settings.name + ':',
  7926. totalTime = 0
  7927. ;
  7928. time = false;
  7929. clearTimeout(module.performance.timer);
  7930. $.each(performance, function(index, data) {
  7931. totalTime += data['Execution Time'];
  7932. });
  7933. title += ' ' + totalTime + 'ms';
  7934. if(moduleSelector) {
  7935. title += ' \'' + moduleSelector + '\'';
  7936. }
  7937. if($allModules.length > 1) {
  7938. title += ' ' + '(' + $allModules.length + ')';
  7939. }
  7940. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  7941. console.groupCollapsed(title);
  7942. if(console.table) {
  7943. console.table(performance);
  7944. }
  7945. else {
  7946. $.each(performance, function(index, data) {
  7947. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  7948. });
  7949. }
  7950. console.groupEnd();
  7951. }
  7952. performance = [];
  7953. }
  7954. },
  7955. invoke: function(query, passedArguments, context) {
  7956. var
  7957. object = instance,
  7958. maxDepth,
  7959. found,
  7960. response
  7961. ;
  7962. passedArguments = passedArguments || queryArguments;
  7963. context = element || context;
  7964. if(typeof query == 'string' && object !== undefined) {
  7965. query = query.split(/[\. ]/);
  7966. maxDepth = query.length - 1;
  7967. $.each(query, function(depth, value) {
  7968. var camelCaseValue = (depth != maxDepth)
  7969. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  7970. : query
  7971. ;
  7972. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  7973. object = object[camelCaseValue];
  7974. }
  7975. else if( object[camelCaseValue] !== undefined ) {
  7976. found = object[camelCaseValue];
  7977. return false;
  7978. }
  7979. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  7980. object = object[value];
  7981. }
  7982. else if( object[value] !== undefined ) {
  7983. found = object[value];
  7984. return false;
  7985. }
  7986. else {
  7987. module.error(error.method, query);
  7988. return false;
  7989. }
  7990. });
  7991. }
  7992. if ( $.isFunction( found ) ) {
  7993. response = found.apply(context, passedArguments);
  7994. }
  7995. else if(found !== undefined) {
  7996. response = found;
  7997. }
  7998. if($.isArray(returnedValue)) {
  7999. returnedValue.push(response);
  8000. }
  8001. else if(returnedValue !== undefined) {
  8002. returnedValue = [returnedValue, response];
  8003. }
  8004. else if(response !== undefined) {
  8005. returnedValue = response;
  8006. }
  8007. return found;
  8008. }
  8009. };
  8010. if(methodInvoked) {
  8011. if(instance === undefined) {
  8012. module.initialize();
  8013. }
  8014. module.invoke(query);
  8015. }
  8016. else {
  8017. if(instance !== undefined) {
  8018. instance.invoke('destroy');
  8019. }
  8020. module.initialize();
  8021. }
  8022. })
  8023. ;
  8024. return (returnedValue !== undefined)
  8025. ? returnedValue
  8026. : this
  8027. ;
  8028. };
  8029. $.fn.embed.settings = {
  8030. name : 'Embed',
  8031. namespace : 'embed',
  8032. silent : false,
  8033. debug : false,
  8034. verbose : false,
  8035. performance : true,
  8036. icon : false,
  8037. source : false,
  8038. url : false,
  8039. id : false,
  8040. // standard video settings
  8041. autoplay : 'auto',
  8042. color : '#444444',
  8043. hd : true,
  8044. brandedUI : false,
  8045. // additional parameters to include with the embed
  8046. parameters: false,
  8047. onDisplay : function() {},
  8048. onPlaceholderDisplay : function() {},
  8049. onReset : function() {},
  8050. onCreate : function(url) {},
  8051. onEmbed : function(parameters) {
  8052. return parameters;
  8053. },
  8054. metadata : {
  8055. id : 'id',
  8056. icon : 'icon',
  8057. placeholder : 'placeholder',
  8058. source : 'source',
  8059. url : 'url'
  8060. },
  8061. error : {
  8062. noURL : 'No URL specified',
  8063. method : 'The method you called is not defined'
  8064. },
  8065. className : {
  8066. active : 'active',
  8067. embed : 'embed'
  8068. },
  8069. selector : {
  8070. embed : '.embed',
  8071. placeholder : '.placeholder',
  8072. icon : '.icon'
  8073. },
  8074. sources: {
  8075. youtube: {
  8076. name : 'youtube',
  8077. type : 'video',
  8078. icon : 'video play',
  8079. domain : 'youtube.com',
  8080. url : '//www.youtube.com/embed/{id}',
  8081. parameters: function(settings) {
  8082. return {
  8083. autohide : !settings.brandedUI,
  8084. autoplay : settings.autoplay,
  8085. color : settings.color || undefined,
  8086. hq : settings.hd,
  8087. jsapi : settings.api,
  8088. modestbranding : !settings.brandedUI
  8089. };
  8090. }
  8091. },
  8092. vimeo: {
  8093. name : 'vimeo',
  8094. type : 'video',
  8095. icon : 'video play',
  8096. domain : 'vimeo.com',
  8097. url : '//player.vimeo.com/video/{id}',
  8098. parameters: function(settings) {
  8099. return {
  8100. api : settings.api,
  8101. autoplay : settings.autoplay,
  8102. byline : settings.brandedUI,
  8103. color : settings.color || undefined,
  8104. portrait : settings.brandedUI,
  8105. title : settings.brandedUI
  8106. };
  8107. }
  8108. }
  8109. },
  8110. templates: {
  8111. iframe : function(url, parameters) {
  8112. var src = url;
  8113. if (parameters) {
  8114. src += '?' + parameters;
  8115. }
  8116. return ''
  8117. + '<iframe src="' + src + '"'
  8118. + ' width="100%" height="100%"'
  8119. + ' frameborder="0" scrolling="no" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>'
  8120. ;
  8121. },
  8122. placeholder : function(image, icon) {
  8123. var
  8124. html = ''
  8125. ;
  8126. if(icon) {
  8127. html += '<i class="' + icon + ' icon"></i>';
  8128. }
  8129. if(image) {
  8130. html += '<img class="placeholder" src="' + image + '">';
  8131. }
  8132. return html;
  8133. }
  8134. },
  8135. // NOT YET IMPLEMENTED
  8136. api : false,
  8137. onPause : function() {},
  8138. onPlay : function() {},
  8139. onStop : function() {}
  8140. };
  8141. })( jQuery, window, document );
  8142. /*!
  8143. * # Semantic UI 2.2.6 - Modal
  8144. * http://github.com/semantic-org/semantic-ui/
  8145. *
  8146. *
  8147. * Released under the MIT license
  8148. * http://opensource.org/licenses/MIT
  8149. *
  8150. */
  8151. ;(function ($, window, document, undefined) {
  8152. "use strict";
  8153. window = (typeof window != 'undefined' && window.Math == Math)
  8154. ? window
  8155. : (typeof self != 'undefined' && self.Math == Math)
  8156. ? self
  8157. : Function('return this')()
  8158. ;
  8159. $.fn.modal = function(parameters) {
  8160. var
  8161. $allModules = $(this),
  8162. $window = $(window),
  8163. $document = $(document),
  8164. $body = $('body'),
  8165. moduleSelector = $allModules.selector || '',
  8166. time = new Date().getTime(),
  8167. performance = [],
  8168. query = arguments[0],
  8169. methodInvoked = (typeof query == 'string'),
  8170. queryArguments = [].slice.call(arguments, 1),
  8171. requestAnimationFrame = window.requestAnimationFrame
  8172. || window.mozRequestAnimationFrame
  8173. || window.webkitRequestAnimationFrame
  8174. || window.msRequestAnimationFrame
  8175. || function(callback) { setTimeout(callback, 0); },
  8176. returnedValue
  8177. ;
  8178. $allModules
  8179. .each(function() {
  8180. var
  8181. settings = ( $.isPlainObject(parameters) )
  8182. ? $.extend(true, {}, $.fn.modal.settings, parameters)
  8183. : $.extend({}, $.fn.modal.settings),
  8184. selector = settings.selector,
  8185. className = settings.className,
  8186. namespace = settings.namespace,
  8187. error = settings.error,
  8188. eventNamespace = '.' + namespace,
  8189. moduleNamespace = 'module-' + namespace,
  8190. $module = $(this),
  8191. $context = $(settings.context),
  8192. $close = $module.find(selector.close),
  8193. $allModals,
  8194. $otherModals,
  8195. $focusedElement,
  8196. $dimmable,
  8197. $dimmer,
  8198. element = this,
  8199. instance = $module.data(moduleNamespace),
  8200. elementEventNamespace,
  8201. id,
  8202. observer,
  8203. module
  8204. ;
  8205. module = {
  8206. initialize: function() {
  8207. module.verbose('Initializing dimmer', $context);
  8208. module.create.id();
  8209. module.create.dimmer();
  8210. module.refreshModals();
  8211. module.bind.events();
  8212. if(settings.observeChanges) {
  8213. module.observeChanges();
  8214. }
  8215. module.instantiate();
  8216. },
  8217. instantiate: function() {
  8218. module.verbose('Storing instance of modal');
  8219. instance = module;
  8220. $module
  8221. .data(moduleNamespace, instance)
  8222. ;
  8223. },
  8224. create: {
  8225. dimmer: function() {
  8226. var
  8227. defaultSettings = {
  8228. debug : settings.debug,
  8229. dimmerName : 'modals',
  8230. duration : {
  8231. show : settings.duration,
  8232. hide : settings.duration
  8233. }
  8234. },
  8235. dimmerSettings = $.extend(true, defaultSettings, settings.dimmerSettings)
  8236. ;
  8237. if(settings.inverted) {
  8238. dimmerSettings.variation = (dimmerSettings.variation !== undefined)
  8239. ? dimmerSettings.variation + ' inverted'
  8240. : 'inverted'
  8241. ;
  8242. }
  8243. if($.fn.dimmer === undefined) {
  8244. module.error(error.dimmer);
  8245. return;
  8246. }
  8247. module.debug('Creating dimmer with settings', dimmerSettings);
  8248. $dimmable = $context.dimmer(dimmerSettings);
  8249. if(settings.detachable) {
  8250. module.verbose('Modal is detachable, moving content into dimmer');
  8251. $dimmable.dimmer('add content', $module);
  8252. }
  8253. else {
  8254. module.set.undetached();
  8255. }
  8256. if(settings.blurring) {
  8257. $dimmable.addClass(className.blurring);
  8258. }
  8259. $dimmer = $dimmable.dimmer('get dimmer');
  8260. },
  8261. id: function() {
  8262. id = (Math.random().toString(16) + '000000000').substr(2,8);
  8263. elementEventNamespace = '.' + id;
  8264. module.verbose('Creating unique id for element', id);
  8265. }
  8266. },
  8267. destroy: function() {
  8268. module.verbose('Destroying previous modal');
  8269. $module
  8270. .removeData(moduleNamespace)
  8271. .off(eventNamespace)
  8272. ;
  8273. $window.off(elementEventNamespace);
  8274. $dimmer.off(elementEventNamespace);
  8275. $close.off(eventNamespace);
  8276. $context.dimmer('destroy');
  8277. },
  8278. observeChanges: function() {
  8279. if('MutationObserver' in window) {
  8280. observer = new MutationObserver(function(mutations) {
  8281. module.debug('DOM tree modified, refreshing');
  8282. module.refresh();
  8283. });
  8284. observer.observe(element, {
  8285. childList : true,
  8286. subtree : true
  8287. });
  8288. module.debug('Setting up mutation observer', observer);
  8289. }
  8290. },
  8291. refresh: function() {
  8292. module.remove.scrolling();
  8293. module.cacheSizes();
  8294. module.set.screenHeight();
  8295. module.set.type();
  8296. module.set.position();
  8297. },
  8298. refreshModals: function() {
  8299. $otherModals = $module.siblings(selector.modal);
  8300. $allModals = $otherModals.add($module);
  8301. },
  8302. attachEvents: function(selector, event) {
  8303. var
  8304. $toggle = $(selector)
  8305. ;
  8306. event = $.isFunction(module[event])
  8307. ? module[event]
  8308. : module.toggle
  8309. ;
  8310. if($toggle.length > 0) {
  8311. module.debug('Attaching modal events to element', selector, event);
  8312. $toggle
  8313. .off(eventNamespace)
  8314. .on('click' + eventNamespace, event)
  8315. ;
  8316. }
  8317. else {
  8318. module.error(error.notFound, selector);
  8319. }
  8320. },
  8321. bind: {
  8322. events: function() {
  8323. module.verbose('Attaching events');
  8324. $module
  8325. .on('click' + eventNamespace, selector.close, module.event.close)
  8326. .on('click' + eventNamespace, selector.approve, module.event.approve)
  8327. .on('click' + eventNamespace, selector.deny, module.event.deny)
  8328. ;
  8329. $window
  8330. .on('resize' + elementEventNamespace, module.event.resize)
  8331. ;
  8332. }
  8333. },
  8334. get: {
  8335. id: function() {
  8336. return (Math.random().toString(16) + '000000000').substr(2,8);
  8337. }
  8338. },
  8339. event: {
  8340. approve: function() {
  8341. if(settings.onApprove.call(element, $(this)) === false) {
  8342. module.verbose('Approve callback returned false cancelling hide');
  8343. return;
  8344. }
  8345. module.hide();
  8346. },
  8347. deny: function() {
  8348. if(settings.onDeny.call(element, $(this)) === false) {
  8349. module.verbose('Deny callback returned false cancelling hide');
  8350. return;
  8351. }
  8352. module.hide();
  8353. },
  8354. close: function() {
  8355. module.hide();
  8356. },
  8357. click: function(event) {
  8358. var
  8359. $target = $(event.target),
  8360. isInModal = ($target.closest(selector.modal).length > 0),
  8361. isInDOM = $.contains(document.documentElement, event.target)
  8362. ;
  8363. if(!isInModal && isInDOM) {
  8364. module.debug('Dimmer clicked, hiding all modals');
  8365. if( module.is.active() ) {
  8366. module.remove.clickaway();
  8367. if(settings.allowMultiple) {
  8368. module.hide();
  8369. }
  8370. else {
  8371. module.hideAll();
  8372. }
  8373. }
  8374. }
  8375. },
  8376. debounce: function(method, delay) {
  8377. clearTimeout(module.timer);
  8378. module.timer = setTimeout(method, delay);
  8379. },
  8380. keyboard: function(event) {
  8381. var
  8382. keyCode = event.which,
  8383. escapeKey = 27
  8384. ;
  8385. if(keyCode == escapeKey) {
  8386. if(settings.closable) {
  8387. module.debug('Escape key pressed hiding modal');
  8388. module.hide();
  8389. }
  8390. else {
  8391. module.debug('Escape key pressed, but closable is set to false');
  8392. }
  8393. event.preventDefault();
  8394. }
  8395. },
  8396. resize: function() {
  8397. if( $dimmable.dimmer('is active') ) {
  8398. requestAnimationFrame(module.refresh);
  8399. }
  8400. }
  8401. },
  8402. toggle: function() {
  8403. if( module.is.active() || module.is.animating() ) {
  8404. module.hide();
  8405. }
  8406. else {
  8407. module.show();
  8408. }
  8409. },
  8410. show: function(callback) {
  8411. callback = $.isFunction(callback)
  8412. ? callback
  8413. : function(){}
  8414. ;
  8415. module.refreshModals();
  8416. module.showModal(callback);
  8417. },
  8418. hide: function(callback) {
  8419. callback = $.isFunction(callback)
  8420. ? callback
  8421. : function(){}
  8422. ;
  8423. module.refreshModals();
  8424. module.hideModal(callback);
  8425. },
  8426. showModal: function(callback) {
  8427. callback = $.isFunction(callback)
  8428. ? callback
  8429. : function(){}
  8430. ;
  8431. if( module.is.animating() || !module.is.active() ) {
  8432. module.showDimmer();
  8433. module.cacheSizes();
  8434. module.set.position();
  8435. module.set.screenHeight();
  8436. module.set.type();
  8437. module.set.clickaway();
  8438. if( !settings.allowMultiple && module.others.active() ) {
  8439. module.hideOthers(module.showModal);
  8440. }
  8441. else {
  8442. settings.onShow.call(element);
  8443. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  8444. module.debug('Showing modal with css animations');
  8445. $module
  8446. .transition({
  8447. debug : settings.debug,
  8448. animation : settings.transition + ' in',
  8449. queue : settings.queue,
  8450. duration : settings.duration,
  8451. useFailSafe : true,
  8452. onComplete : function() {
  8453. settings.onVisible.apply(element);
  8454. if(settings.keyboardShortcuts) {
  8455. module.add.keyboardShortcuts();
  8456. }
  8457. module.save.focus();
  8458. module.set.active();
  8459. if(settings.autofocus) {
  8460. module.set.autofocus();
  8461. }
  8462. callback();
  8463. }
  8464. })
  8465. ;
  8466. }
  8467. else {
  8468. module.error(error.noTransition);
  8469. }
  8470. }
  8471. }
  8472. else {
  8473. module.debug('Modal is already visible');
  8474. }
  8475. },
  8476. hideModal: function(callback, keepDimmed) {
  8477. callback = $.isFunction(callback)
  8478. ? callback
  8479. : function(){}
  8480. ;
  8481. module.debug('Hiding modal');
  8482. if(settings.onHide.call(element, $(this)) === false) {
  8483. module.verbose('Hide callback returned false cancelling hide');
  8484. return;
  8485. }
  8486. if( module.is.animating() || module.is.active() ) {
  8487. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  8488. module.remove.active();
  8489. $module
  8490. .transition({
  8491. debug : settings.debug,
  8492. animation : settings.transition + ' out',
  8493. queue : settings.queue,
  8494. duration : settings.duration,
  8495. useFailSafe : true,
  8496. onStart : function() {
  8497. if(!module.others.active() && !keepDimmed) {
  8498. module.hideDimmer();
  8499. }
  8500. if(settings.keyboardShortcuts) {
  8501. module.remove.keyboardShortcuts();
  8502. }
  8503. },
  8504. onComplete : function() {
  8505. settings.onHidden.call(element);
  8506. module.restore.focus();
  8507. callback();
  8508. }
  8509. })
  8510. ;
  8511. }
  8512. else {
  8513. module.error(error.noTransition);
  8514. }
  8515. }
  8516. },
  8517. showDimmer: function() {
  8518. if($dimmable.dimmer('is animating') || !$dimmable.dimmer('is active') ) {
  8519. module.debug('Showing dimmer');
  8520. $dimmable.dimmer('show');
  8521. }
  8522. else {
  8523. module.debug('Dimmer already visible');
  8524. }
  8525. },
  8526. hideDimmer: function() {
  8527. if( $dimmable.dimmer('is animating') || ($dimmable.dimmer('is active')) ) {
  8528. $dimmable.dimmer('hide', function() {
  8529. module.remove.clickaway();
  8530. module.remove.screenHeight();
  8531. });
  8532. }
  8533. else {
  8534. module.debug('Dimmer is not visible cannot hide');
  8535. return;
  8536. }
  8537. },
  8538. hideAll: function(callback) {
  8539. var
  8540. $visibleModals = $allModals.filter('.' + className.active + ', .' + className.animating)
  8541. ;
  8542. callback = $.isFunction(callback)
  8543. ? callback
  8544. : function(){}
  8545. ;
  8546. if( $visibleModals.length > 0 ) {
  8547. module.debug('Hiding all visible modals');
  8548. module.hideDimmer();
  8549. $visibleModals
  8550. .modal('hide modal', callback)
  8551. ;
  8552. }
  8553. },
  8554. hideOthers: function(callback) {
  8555. var
  8556. $visibleModals = $otherModals.filter('.' + className.active + ', .' + className.animating)
  8557. ;
  8558. callback = $.isFunction(callback)
  8559. ? callback
  8560. : function(){}
  8561. ;
  8562. if( $visibleModals.length > 0 ) {
  8563. module.debug('Hiding other modals', $otherModals);
  8564. $visibleModals
  8565. .modal('hide modal', callback, true)
  8566. ;
  8567. }
  8568. },
  8569. others: {
  8570. active: function() {
  8571. return ($otherModals.filter('.' + className.active).length > 0);
  8572. },
  8573. animating: function() {
  8574. return ($otherModals.filter('.' + className.animating).length > 0);
  8575. }
  8576. },
  8577. add: {
  8578. keyboardShortcuts: function() {
  8579. module.verbose('Adding keyboard shortcuts');
  8580. $document
  8581. .on('keyup' + eventNamespace, module.event.keyboard)
  8582. ;
  8583. }
  8584. },
  8585. save: {
  8586. focus: function() {
  8587. $focusedElement = $(document.activeElement).blur();
  8588. }
  8589. },
  8590. restore: {
  8591. focus: function() {
  8592. if($focusedElement && $focusedElement.length > 0) {
  8593. $focusedElement.focus();
  8594. }
  8595. }
  8596. },
  8597. remove: {
  8598. active: function() {
  8599. $module.removeClass(className.active);
  8600. },
  8601. clickaway: function() {
  8602. if(settings.closable) {
  8603. $dimmer
  8604. .off('click' + elementEventNamespace)
  8605. ;
  8606. }
  8607. },
  8608. bodyStyle: function() {
  8609. if($body.attr('style') === '') {
  8610. module.verbose('Removing style attribute');
  8611. $body.removeAttr('style');
  8612. }
  8613. },
  8614. screenHeight: function() {
  8615. module.debug('Removing page height');
  8616. $body
  8617. .css('height', '')
  8618. ;
  8619. },
  8620. keyboardShortcuts: function() {
  8621. module.verbose('Removing keyboard shortcuts');
  8622. $document
  8623. .off('keyup' + eventNamespace)
  8624. ;
  8625. },
  8626. scrolling: function() {
  8627. $dimmable.removeClass(className.scrolling);
  8628. $module.removeClass(className.scrolling);
  8629. }
  8630. },
  8631. cacheSizes: function() {
  8632. var
  8633. modalHeight = $module.outerHeight()
  8634. ;
  8635. if(module.cache === undefined || modalHeight !== 0) {
  8636. module.cache = {
  8637. pageHeight : $(document).outerHeight(),
  8638. height : modalHeight + settings.offset,
  8639. contextHeight : (settings.context == 'body')
  8640. ? $(window).height()
  8641. : $dimmable.height()
  8642. };
  8643. }
  8644. module.debug('Caching modal and container sizes', module.cache);
  8645. },
  8646. can: {
  8647. fit: function() {
  8648. return ( ( module.cache.height + (settings.padding * 2) ) < module.cache.contextHeight);
  8649. }
  8650. },
  8651. is: {
  8652. active: function() {
  8653. return $module.hasClass(className.active);
  8654. },
  8655. animating: function() {
  8656. return $module.transition('is supported')
  8657. ? $module.transition('is animating')
  8658. : $module.is(':visible')
  8659. ;
  8660. },
  8661. scrolling: function() {
  8662. return $dimmable.hasClass(className.scrolling);
  8663. },
  8664. modernBrowser: function() {
  8665. // appName for IE11 reports 'Netscape' can no longer use
  8666. return !(window.ActiveXObject || "ActiveXObject" in window);
  8667. }
  8668. },
  8669. set: {
  8670. autofocus: function() {
  8671. var
  8672. $inputs = $module.find('[tabindex], :input').filter(':visible'),
  8673. $autofocus = $inputs.filter('[autofocus]'),
  8674. $input = ($autofocus.length > 0)
  8675. ? $autofocus.first()
  8676. : $inputs.first()
  8677. ;
  8678. if($input.length > 0) {
  8679. $input.focus();
  8680. }
  8681. },
  8682. clickaway: function() {
  8683. if(settings.closable) {
  8684. $dimmer
  8685. .on('click' + elementEventNamespace, module.event.click)
  8686. ;
  8687. }
  8688. },
  8689. screenHeight: function() {
  8690. if( module.can.fit() ) {
  8691. $body.css('height', '');
  8692. }
  8693. else {
  8694. module.debug('Modal is taller than page content, resizing page height');
  8695. $body
  8696. .css('height', module.cache.height + (settings.padding * 2) )
  8697. ;
  8698. }
  8699. },
  8700. active: function() {
  8701. $module.addClass(className.active);
  8702. },
  8703. scrolling: function() {
  8704. $dimmable.addClass(className.scrolling);
  8705. $module.addClass(className.scrolling);
  8706. },
  8707. type: function() {
  8708. if(module.can.fit()) {
  8709. module.verbose('Modal fits on screen');
  8710. if(!module.others.active() && !module.others.animating()) {
  8711. module.remove.scrolling();
  8712. }
  8713. }
  8714. else {
  8715. module.verbose('Modal cannot fit on screen setting to scrolling');
  8716. module.set.scrolling();
  8717. }
  8718. },
  8719. position: function() {
  8720. module.verbose('Centering modal on page', module.cache);
  8721. if(module.can.fit()) {
  8722. $module
  8723. .css({
  8724. top: '',
  8725. marginTop: -(module.cache.height / 2)
  8726. })
  8727. ;
  8728. }
  8729. else {
  8730. $module
  8731. .css({
  8732. marginTop : '',
  8733. top : $document.scrollTop()
  8734. })
  8735. ;
  8736. }
  8737. },
  8738. undetached: function() {
  8739. $dimmable.addClass(className.undetached);
  8740. }
  8741. },
  8742. setting: function(name, value) {
  8743. module.debug('Changing setting', name, value);
  8744. if( $.isPlainObject(name) ) {
  8745. $.extend(true, settings, name);
  8746. }
  8747. else if(value !== undefined) {
  8748. if($.isPlainObject(settings[name])) {
  8749. $.extend(true, settings[name], value);
  8750. }
  8751. else {
  8752. settings[name] = value;
  8753. }
  8754. }
  8755. else {
  8756. return settings[name];
  8757. }
  8758. },
  8759. internal: function(name, value) {
  8760. if( $.isPlainObject(name) ) {
  8761. $.extend(true, module, name);
  8762. }
  8763. else if(value !== undefined) {
  8764. module[name] = value;
  8765. }
  8766. else {
  8767. return module[name];
  8768. }
  8769. },
  8770. debug: function() {
  8771. if(!settings.silent && settings.debug) {
  8772. if(settings.performance) {
  8773. module.performance.log(arguments);
  8774. }
  8775. else {
  8776. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  8777. module.debug.apply(console, arguments);
  8778. }
  8779. }
  8780. },
  8781. verbose: function() {
  8782. if(!settings.silent && settings.verbose && settings.debug) {
  8783. if(settings.performance) {
  8784. module.performance.log(arguments);
  8785. }
  8786. else {
  8787. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  8788. module.verbose.apply(console, arguments);
  8789. }
  8790. }
  8791. },
  8792. error: function() {
  8793. if(!settings.silent) {
  8794. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  8795. module.error.apply(console, arguments);
  8796. }
  8797. },
  8798. performance: {
  8799. log: function(message) {
  8800. var
  8801. currentTime,
  8802. executionTime,
  8803. previousTime
  8804. ;
  8805. if(settings.performance) {
  8806. currentTime = new Date().getTime();
  8807. previousTime = time || currentTime;
  8808. executionTime = currentTime - previousTime;
  8809. time = currentTime;
  8810. performance.push({
  8811. 'Name' : message[0],
  8812. 'Arguments' : [].slice.call(message, 1) || '',
  8813. 'Element' : element,
  8814. 'Execution Time' : executionTime
  8815. });
  8816. }
  8817. clearTimeout(module.performance.timer);
  8818. module.performance.timer = setTimeout(module.performance.display, 500);
  8819. },
  8820. display: function() {
  8821. var
  8822. title = settings.name + ':',
  8823. totalTime = 0
  8824. ;
  8825. time = false;
  8826. clearTimeout(module.performance.timer);
  8827. $.each(performance, function(index, data) {
  8828. totalTime += data['Execution Time'];
  8829. });
  8830. title += ' ' + totalTime + 'ms';
  8831. if(moduleSelector) {
  8832. title += ' \'' + moduleSelector + '\'';
  8833. }
  8834. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  8835. console.groupCollapsed(title);
  8836. if(console.table) {
  8837. console.table(performance);
  8838. }
  8839. else {
  8840. $.each(performance, function(index, data) {
  8841. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  8842. });
  8843. }
  8844. console.groupEnd();
  8845. }
  8846. performance = [];
  8847. }
  8848. },
  8849. invoke: function(query, passedArguments, context) {
  8850. var
  8851. object = instance,
  8852. maxDepth,
  8853. found,
  8854. response
  8855. ;
  8856. passedArguments = passedArguments || queryArguments;
  8857. context = element || context;
  8858. if(typeof query == 'string' && object !== undefined) {
  8859. query = query.split(/[\. ]/);
  8860. maxDepth = query.length - 1;
  8861. $.each(query, function(depth, value) {
  8862. var camelCaseValue = (depth != maxDepth)
  8863. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  8864. : query
  8865. ;
  8866. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  8867. object = object[camelCaseValue];
  8868. }
  8869. else if( object[camelCaseValue] !== undefined ) {
  8870. found = object[camelCaseValue];
  8871. return false;
  8872. }
  8873. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  8874. object = object[value];
  8875. }
  8876. else if( object[value] !== undefined ) {
  8877. found = object[value];
  8878. return false;
  8879. }
  8880. else {
  8881. return false;
  8882. }
  8883. });
  8884. }
  8885. if ( $.isFunction( found ) ) {
  8886. response = found.apply(context, passedArguments);
  8887. }
  8888. else if(found !== undefined) {
  8889. response = found;
  8890. }
  8891. if($.isArray(returnedValue)) {
  8892. returnedValue.push(response);
  8893. }
  8894. else if(returnedValue !== undefined) {
  8895. returnedValue = [returnedValue, response];
  8896. }
  8897. else if(response !== undefined) {
  8898. returnedValue = response;
  8899. }
  8900. return found;
  8901. }
  8902. };
  8903. if(methodInvoked) {
  8904. if(instance === undefined) {
  8905. module.initialize();
  8906. }
  8907. module.invoke(query);
  8908. }
  8909. else {
  8910. if(instance !== undefined) {
  8911. instance.invoke('destroy');
  8912. }
  8913. module.initialize();
  8914. }
  8915. })
  8916. ;
  8917. return (returnedValue !== undefined)
  8918. ? returnedValue
  8919. : this
  8920. ;
  8921. };
  8922. $.fn.modal.settings = {
  8923. name : 'Modal',
  8924. namespace : 'modal',
  8925. silent : false,
  8926. debug : false,
  8927. verbose : false,
  8928. performance : true,
  8929. observeChanges : false,
  8930. allowMultiple : false,
  8931. detachable : true,
  8932. closable : true,
  8933. autofocus : true,
  8934. inverted : false,
  8935. blurring : false,
  8936. dimmerSettings : {
  8937. closable : false,
  8938. useCSS : true
  8939. },
  8940. // whether to use keyboard shortcuts
  8941. keyboardShortcuts: true,
  8942. context : 'body',
  8943. queue : false,
  8944. duration : 500,
  8945. offset : 0,
  8946. transition : 'scale',
  8947. // padding with edge of page
  8948. padding : 50,
  8949. // called before show animation
  8950. onShow : function(){},
  8951. // called after show animation
  8952. onVisible : function(){},
  8953. // called before hide animation
  8954. onHide : function(){ return true; },
  8955. // called after hide animation
  8956. onHidden : function(){},
  8957. // called after approve selector match
  8958. onApprove : function(){ return true; },
  8959. // called after deny selector match
  8960. onDeny : function(){ return true; },
  8961. selector : {
  8962. close : '> .close',
  8963. approve : '.actions .positive, .actions .approve, .actions .ok',
  8964. deny : '.actions .negative, .actions .deny, .actions .cancel',
  8965. modal : '.ui.modal'
  8966. },
  8967. error : {
  8968. dimmer : 'UI Dimmer, a required component is not included in this page',
  8969. method : 'The method you called is not defined.',
  8970. notFound : 'The element you specified could not be found'
  8971. },
  8972. className : {
  8973. active : 'active',
  8974. animating : 'animating',
  8975. blurring : 'blurring',
  8976. scrolling : 'scrolling',
  8977. undetached : 'undetached'
  8978. }
  8979. };
  8980. })( jQuery, window, document );
  8981. /*!
  8982. * # Semantic UI 2.2.6 - Nag
  8983. * http://github.com/semantic-org/semantic-ui/
  8984. *
  8985. *
  8986. * Released under the MIT license
  8987. * http://opensource.org/licenses/MIT
  8988. *
  8989. */
  8990. ;(function ($, window, document, undefined) {
  8991. "use strict";
  8992. window = (typeof window != 'undefined' && window.Math == Math)
  8993. ? window
  8994. : (typeof self != 'undefined' && self.Math == Math)
  8995. ? self
  8996. : Function('return this')()
  8997. ;
  8998. $.fn.nag = function(parameters) {
  8999. var
  9000. $allModules = $(this),
  9001. moduleSelector = $allModules.selector || '',
  9002. time = new Date().getTime(),
  9003. performance = [],
  9004. query = arguments[0],
  9005. methodInvoked = (typeof query == 'string'),
  9006. queryArguments = [].slice.call(arguments, 1),
  9007. returnedValue
  9008. ;
  9009. $allModules
  9010. .each(function() {
  9011. var
  9012. settings = ( $.isPlainObject(parameters) )
  9013. ? $.extend(true, {}, $.fn.nag.settings, parameters)
  9014. : $.extend({}, $.fn.nag.settings),
  9015. className = settings.className,
  9016. selector = settings.selector,
  9017. error = settings.error,
  9018. namespace = settings.namespace,
  9019. eventNamespace = '.' + namespace,
  9020. moduleNamespace = namespace + '-module',
  9021. $module = $(this),
  9022. $close = $module.find(selector.close),
  9023. $context = (settings.context)
  9024. ? $(settings.context)
  9025. : $('body'),
  9026. element = this,
  9027. instance = $module.data(moduleNamespace),
  9028. moduleOffset,
  9029. moduleHeight,
  9030. contextWidth,
  9031. contextHeight,
  9032. contextOffset,
  9033. yOffset,
  9034. yPosition,
  9035. timer,
  9036. module,
  9037. requestAnimationFrame = window.requestAnimationFrame
  9038. || window.mozRequestAnimationFrame
  9039. || window.webkitRequestAnimationFrame
  9040. || window.msRequestAnimationFrame
  9041. || function(callback) { setTimeout(callback, 0); }
  9042. ;
  9043. module = {
  9044. initialize: function() {
  9045. module.verbose('Initializing element');
  9046. $module
  9047. .on('click' + eventNamespace, selector.close, module.dismiss)
  9048. .data(moduleNamespace, module)
  9049. ;
  9050. if(settings.detachable && $module.parent()[0] !== $context[0]) {
  9051. $module
  9052. .detach()
  9053. .prependTo($context)
  9054. ;
  9055. }
  9056. if(settings.displayTime > 0) {
  9057. setTimeout(module.hide, settings.displayTime);
  9058. }
  9059. module.show();
  9060. },
  9061. destroy: function() {
  9062. module.verbose('Destroying instance');
  9063. $module
  9064. .removeData(moduleNamespace)
  9065. .off(eventNamespace)
  9066. ;
  9067. },
  9068. show: function() {
  9069. if( module.should.show() && !$module.is(':visible') ) {
  9070. module.debug('Showing nag', settings.animation.show);
  9071. if(settings.animation.show == 'fade') {
  9072. $module
  9073. .fadeIn(settings.duration, settings.easing)
  9074. ;
  9075. }
  9076. else {
  9077. $module
  9078. .slideDown(settings.duration, settings.easing)
  9079. ;
  9080. }
  9081. }
  9082. },
  9083. hide: function() {
  9084. module.debug('Showing nag', settings.animation.hide);
  9085. if(settings.animation.show == 'fade') {
  9086. $module
  9087. .fadeIn(settings.duration, settings.easing)
  9088. ;
  9089. }
  9090. else {
  9091. $module
  9092. .slideUp(settings.duration, settings.easing)
  9093. ;
  9094. }
  9095. },
  9096. onHide: function() {
  9097. module.debug('Removing nag', settings.animation.hide);
  9098. $module.remove();
  9099. if (settings.onHide) {
  9100. settings.onHide();
  9101. }
  9102. },
  9103. dismiss: function(event) {
  9104. if(settings.storageMethod) {
  9105. module.storage.set(settings.key, settings.value);
  9106. }
  9107. module.hide();
  9108. event.stopImmediatePropagation();
  9109. event.preventDefault();
  9110. },
  9111. should: {
  9112. show: function() {
  9113. if(settings.persist) {
  9114. module.debug('Persistent nag is set, can show nag');
  9115. return true;
  9116. }
  9117. if( module.storage.get(settings.key) != settings.value.toString() ) {
  9118. module.debug('Stored value is not set, can show nag', module.storage.get(settings.key));
  9119. return true;
  9120. }
  9121. module.debug('Stored value is set, cannot show nag', module.storage.get(settings.key));
  9122. return false;
  9123. }
  9124. },
  9125. get: {
  9126. storageOptions: function() {
  9127. var
  9128. options = {}
  9129. ;
  9130. if(settings.expires) {
  9131. options.expires = settings.expires;
  9132. }
  9133. if(settings.domain) {
  9134. options.domain = settings.domain;
  9135. }
  9136. if(settings.path) {
  9137. options.path = settings.path;
  9138. }
  9139. return options;
  9140. }
  9141. },
  9142. clear: function() {
  9143. module.storage.remove(settings.key);
  9144. },
  9145. storage: {
  9146. set: function(key, value) {
  9147. var
  9148. options = module.get.storageOptions()
  9149. ;
  9150. if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
  9151. window.localStorage.setItem(key, value);
  9152. module.debug('Value stored using local storage', key, value);
  9153. }
  9154. else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) {
  9155. window.sessionStorage.setItem(key, value);
  9156. module.debug('Value stored using session storage', key, value);
  9157. }
  9158. else if($.cookie !== undefined) {
  9159. $.cookie(key, value, options);
  9160. module.debug('Value stored using cookie', key, value, options);
  9161. }
  9162. else {
  9163. module.error(error.noCookieStorage);
  9164. return;
  9165. }
  9166. },
  9167. get: function(key, value) {
  9168. var
  9169. storedValue
  9170. ;
  9171. if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
  9172. storedValue = window.localStorage.getItem(key);
  9173. }
  9174. else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) {
  9175. storedValue = window.sessionStorage.getItem(key);
  9176. }
  9177. // get by cookie
  9178. else if($.cookie !== undefined) {
  9179. storedValue = $.cookie(key);
  9180. }
  9181. else {
  9182. module.error(error.noCookieStorage);
  9183. }
  9184. if(storedValue == 'undefined' || storedValue == 'null' || storedValue === undefined || storedValue === null) {
  9185. storedValue = undefined;
  9186. }
  9187. return storedValue;
  9188. },
  9189. remove: function(key) {
  9190. var
  9191. options = module.get.storageOptions()
  9192. ;
  9193. if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
  9194. window.localStorage.removeItem(key);
  9195. }
  9196. else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) {
  9197. window.sessionStorage.removeItem(key);
  9198. }
  9199. // store by cookie
  9200. else if($.cookie !== undefined) {
  9201. $.removeCookie(key, options);
  9202. }
  9203. else {
  9204. module.error(error.noStorage);
  9205. }
  9206. }
  9207. },
  9208. setting: function(name, value) {
  9209. module.debug('Changing setting', name, value);
  9210. if( $.isPlainObject(name) ) {
  9211. $.extend(true, settings, name);
  9212. }
  9213. else if(value !== undefined) {
  9214. if($.isPlainObject(settings[name])) {
  9215. $.extend(true, settings[name], value);
  9216. }
  9217. else {
  9218. settings[name] = value;
  9219. }
  9220. }
  9221. else {
  9222. return settings[name];
  9223. }
  9224. },
  9225. internal: function(name, value) {
  9226. if( $.isPlainObject(name) ) {
  9227. $.extend(true, module, name);
  9228. }
  9229. else if(value !== undefined) {
  9230. module[name] = value;
  9231. }
  9232. else {
  9233. return module[name];
  9234. }
  9235. },
  9236. debug: function() {
  9237. if(!settings.silent && settings.debug) {
  9238. if(settings.performance) {
  9239. module.performance.log(arguments);
  9240. }
  9241. else {
  9242. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  9243. module.debug.apply(console, arguments);
  9244. }
  9245. }
  9246. },
  9247. verbose: function() {
  9248. if(!settings.silent && settings.verbose && settings.debug) {
  9249. if(settings.performance) {
  9250. module.performance.log(arguments);
  9251. }
  9252. else {
  9253. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  9254. module.verbose.apply(console, arguments);
  9255. }
  9256. }
  9257. },
  9258. error: function() {
  9259. if(!settings.silent) {
  9260. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  9261. module.error.apply(console, arguments);
  9262. }
  9263. },
  9264. performance: {
  9265. log: function(message) {
  9266. var
  9267. currentTime,
  9268. executionTime,
  9269. previousTime
  9270. ;
  9271. if(settings.performance) {
  9272. currentTime = new Date().getTime();
  9273. previousTime = time || currentTime;
  9274. executionTime = currentTime - previousTime;
  9275. time = currentTime;
  9276. performance.push({
  9277. 'Name' : message[0],
  9278. 'Arguments' : [].slice.call(message, 1) || '',
  9279. 'Element' : element,
  9280. 'Execution Time' : executionTime
  9281. });
  9282. }
  9283. clearTimeout(module.performance.timer);
  9284. module.performance.timer = setTimeout(module.performance.display, 500);
  9285. },
  9286. display: function() {
  9287. var
  9288. title = settings.name + ':',
  9289. totalTime = 0
  9290. ;
  9291. time = false;
  9292. clearTimeout(module.performance.timer);
  9293. $.each(performance, function(index, data) {
  9294. totalTime += data['Execution Time'];
  9295. });
  9296. title += ' ' + totalTime + 'ms';
  9297. if(moduleSelector) {
  9298. title += ' \'' + moduleSelector + '\'';
  9299. }
  9300. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  9301. console.groupCollapsed(title);
  9302. if(console.table) {
  9303. console.table(performance);
  9304. }
  9305. else {
  9306. $.each(performance, function(index, data) {
  9307. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  9308. });
  9309. }
  9310. console.groupEnd();
  9311. }
  9312. performance = [];
  9313. }
  9314. },
  9315. invoke: function(query, passedArguments, context) {
  9316. var
  9317. object = instance,
  9318. maxDepth,
  9319. found,
  9320. response
  9321. ;
  9322. passedArguments = passedArguments || queryArguments;
  9323. context = element || context;
  9324. if(typeof query == 'string' && object !== undefined) {
  9325. query = query.split(/[\. ]/);
  9326. maxDepth = query.length - 1;
  9327. $.each(query, function(depth, value) {
  9328. var camelCaseValue = (depth != maxDepth)
  9329. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  9330. : query
  9331. ;
  9332. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  9333. object = object[camelCaseValue];
  9334. }
  9335. else if( object[camelCaseValue] !== undefined ) {
  9336. found = object[camelCaseValue];
  9337. return false;
  9338. }
  9339. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  9340. object = object[value];
  9341. }
  9342. else if( object[value] !== undefined ) {
  9343. found = object[value];
  9344. return false;
  9345. }
  9346. else {
  9347. module.error(error.method, query);
  9348. return false;
  9349. }
  9350. });
  9351. }
  9352. if ( $.isFunction( found ) ) {
  9353. response = found.apply(context, passedArguments);
  9354. }
  9355. else if(found !== undefined) {
  9356. response = found;
  9357. }
  9358. if($.isArray(returnedValue)) {
  9359. returnedValue.push(response);
  9360. }
  9361. else if(returnedValue !== undefined) {
  9362. returnedValue = [returnedValue, response];
  9363. }
  9364. else if(response !== undefined) {
  9365. returnedValue = response;
  9366. }
  9367. return found;
  9368. }
  9369. };
  9370. if(methodInvoked) {
  9371. if(instance === undefined) {
  9372. module.initialize();
  9373. }
  9374. module.invoke(query);
  9375. }
  9376. else {
  9377. if(instance !== undefined) {
  9378. instance.invoke('destroy');
  9379. }
  9380. module.initialize();
  9381. }
  9382. })
  9383. ;
  9384. return (returnedValue !== undefined)
  9385. ? returnedValue
  9386. : this
  9387. ;
  9388. };
  9389. $.fn.nag.settings = {
  9390. name : 'Nag',
  9391. silent : false,
  9392. debug : false,
  9393. verbose : false,
  9394. performance : true,
  9395. namespace : 'Nag',
  9396. // allows cookie to be overridden
  9397. persist : false,
  9398. // set to zero to require manually dismissal, otherwise hides on its own
  9399. displayTime : 0,
  9400. animation : {
  9401. show : 'slide',
  9402. hide : 'slide'
  9403. },
  9404. context : false,
  9405. detachable : false,
  9406. expires : 30,
  9407. domain : false,
  9408. path : '/',
  9409. // type of storage to use
  9410. storageMethod : 'cookie',
  9411. // value to store in dismissed localstorage/cookie
  9412. key : 'nag',
  9413. value : 'dismiss',
  9414. error: {
  9415. noCookieStorage : '$.cookie is not included. A storage solution is required.',
  9416. noStorage : 'Neither $.cookie or store is defined. A storage solution is required for storing state',
  9417. method : 'The method you called is not defined.'
  9418. },
  9419. className : {
  9420. bottom : 'bottom',
  9421. fixed : 'fixed'
  9422. },
  9423. selector : {
  9424. close : '.close.icon'
  9425. },
  9426. speed : 500,
  9427. easing : 'easeOutQuad',
  9428. onHide: function() {}
  9429. };
  9430. // Adds easing
  9431. $.extend( $.easing, {
  9432. easeOutQuad: function (x, t, b, c, d) {
  9433. return -c *(t/=d)*(t-2) + b;
  9434. }
  9435. });
  9436. })( jQuery, window, document );
  9437. /*!
  9438. * # Semantic UI 2.2.6 - Popup
  9439. * http://github.com/semantic-org/semantic-ui/
  9440. *
  9441. *
  9442. * Released under the MIT license
  9443. * http://opensource.org/licenses/MIT
  9444. *
  9445. */
  9446. ;(function ($, window, document, undefined) {
  9447. "use strict";
  9448. window = (typeof window != 'undefined' && window.Math == Math)
  9449. ? window
  9450. : (typeof self != 'undefined' && self.Math == Math)
  9451. ? self
  9452. : Function('return this')()
  9453. ;
  9454. $.fn.popup = function(parameters) {
  9455. var
  9456. $allModules = $(this),
  9457. $document = $(document),
  9458. $window = $(window),
  9459. $body = $('body'),
  9460. moduleSelector = $allModules.selector || '',
  9461. hasTouch = (true),
  9462. time = new Date().getTime(),
  9463. performance = [],
  9464. query = arguments[0],
  9465. methodInvoked = (typeof query == 'string'),
  9466. queryArguments = [].slice.call(arguments, 1),
  9467. returnedValue
  9468. ;
  9469. $allModules
  9470. .each(function() {
  9471. var
  9472. settings = ( $.isPlainObject(parameters) )
  9473. ? $.extend(true, {}, $.fn.popup.settings, parameters)
  9474. : $.extend({}, $.fn.popup.settings),
  9475. selector = settings.selector,
  9476. className = settings.className,
  9477. error = settings.error,
  9478. metadata = settings.metadata,
  9479. namespace = settings.namespace,
  9480. eventNamespace = '.' + settings.namespace,
  9481. moduleNamespace = 'module-' + namespace,
  9482. $module = $(this),
  9483. $context = $(settings.context),
  9484. $scrollContext = $(settings.scrollContext),
  9485. $boundary = $(settings.boundary),
  9486. $target = (settings.target)
  9487. ? $(settings.target)
  9488. : $module,
  9489. $popup,
  9490. $offsetParent,
  9491. searchDepth = 0,
  9492. triedPositions = false,
  9493. openedWithTouch = false,
  9494. element = this,
  9495. instance = $module.data(moduleNamespace),
  9496. documentObserver,
  9497. elementNamespace,
  9498. id,
  9499. module
  9500. ;
  9501. module = {
  9502. // binds events
  9503. initialize: function() {
  9504. module.debug('Initializing', $module);
  9505. module.createID();
  9506. module.bind.events();
  9507. if(!module.exists() && settings.preserve) {
  9508. module.create();
  9509. }
  9510. if(settings.observeChanges) {
  9511. module.observeChanges();
  9512. }
  9513. module.instantiate();
  9514. },
  9515. instantiate: function() {
  9516. module.verbose('Storing instance', module);
  9517. instance = module;
  9518. $module
  9519. .data(moduleNamespace, instance)
  9520. ;
  9521. },
  9522. observeChanges: function() {
  9523. if('MutationObserver' in window) {
  9524. documentObserver = new MutationObserver(module.event.documentChanged);
  9525. documentObserver.observe(document, {
  9526. childList : true,
  9527. subtree : true
  9528. });
  9529. module.debug('Setting up mutation observer', documentObserver);
  9530. }
  9531. },
  9532. refresh: function() {
  9533. if(settings.popup) {
  9534. $popup = $(settings.popup).eq(0);
  9535. }
  9536. else {
  9537. if(settings.inline) {
  9538. $popup = $target.nextAll(selector.popup).eq(0);
  9539. settings.popup = $popup;
  9540. }
  9541. }
  9542. if(settings.popup) {
  9543. $popup.addClass(className.loading);
  9544. $offsetParent = module.get.offsetParent();
  9545. $popup.removeClass(className.loading);
  9546. if(settings.movePopup && module.has.popup() && module.get.offsetParent($popup)[0] !== $offsetParent[0]) {
  9547. module.debug('Moving popup to the same offset parent as activating element');
  9548. $popup
  9549. .detach()
  9550. .appendTo($offsetParent)
  9551. ;
  9552. }
  9553. }
  9554. else {
  9555. $offsetParent = (settings.inline)
  9556. ? module.get.offsetParent($target)
  9557. : module.has.popup()
  9558. ? module.get.offsetParent($popup)
  9559. : $body
  9560. ;
  9561. }
  9562. if( $offsetParent.is('html') && $offsetParent[0] !== $body[0] ) {
  9563. module.debug('Setting page as offset parent');
  9564. $offsetParent = $body;
  9565. }
  9566. if( module.get.variation() ) {
  9567. module.set.variation();
  9568. }
  9569. },
  9570. reposition: function() {
  9571. module.refresh();
  9572. module.set.position();
  9573. },
  9574. destroy: function() {
  9575. module.debug('Destroying previous module');
  9576. if(documentObserver) {
  9577. documentObserver.disconnect();
  9578. }
  9579. // remove element only if was created dynamically
  9580. if($popup && !settings.preserve) {
  9581. module.removePopup();
  9582. }
  9583. // clear all timeouts
  9584. clearTimeout(module.hideTimer);
  9585. clearTimeout(module.showTimer);
  9586. // remove events
  9587. module.unbind.close();
  9588. module.unbind.events();
  9589. $module
  9590. .removeData(moduleNamespace)
  9591. ;
  9592. },
  9593. event: {
  9594. start: function(event) {
  9595. var
  9596. delay = ($.isPlainObject(settings.delay))
  9597. ? settings.delay.show
  9598. : settings.delay
  9599. ;
  9600. clearTimeout(module.hideTimer);
  9601. if(!openedWithTouch) {
  9602. module.showTimer = setTimeout(module.show, delay);
  9603. }
  9604. },
  9605. end: function() {
  9606. var
  9607. delay = ($.isPlainObject(settings.delay))
  9608. ? settings.delay.hide
  9609. : settings.delay
  9610. ;
  9611. clearTimeout(module.showTimer);
  9612. module.hideTimer = setTimeout(module.hide, delay);
  9613. },
  9614. touchstart: function(event) {
  9615. openedWithTouch = true;
  9616. module.show();
  9617. },
  9618. resize: function() {
  9619. if( module.is.visible() ) {
  9620. module.set.position();
  9621. }
  9622. },
  9623. documentChanged: function(mutations) {
  9624. [].forEach.call(mutations, function(mutation) {
  9625. if(mutation.removedNodes) {
  9626. [].forEach.call(mutation.removedNodes, function(node) {
  9627. if(node == element || $(node).find(element).length > 0) {
  9628. module.debug('Element removed from DOM, tearing down events');
  9629. module.destroy();
  9630. }
  9631. });
  9632. }
  9633. });
  9634. },
  9635. hideGracefully: function(event) {
  9636. var
  9637. $target = $(event.target),
  9638. isInDOM = $.contains(document.documentElement, event.target),
  9639. inPopup = ($target.closest(selector.popup).length > 0)
  9640. ;
  9641. // don't close on clicks inside popup
  9642. if(event && !inPopup && isInDOM) {
  9643. module.debug('Click occurred outside popup hiding popup');
  9644. module.hide();
  9645. }
  9646. else {
  9647. module.debug('Click was inside popup, keeping popup open');
  9648. }
  9649. }
  9650. },
  9651. // generates popup html from metadata
  9652. create: function() {
  9653. var
  9654. html = module.get.html(),
  9655. title = module.get.title(),
  9656. content = module.get.content()
  9657. ;
  9658. if(html || content || title) {
  9659. module.debug('Creating pop-up html');
  9660. if(!html) {
  9661. html = settings.templates.popup({
  9662. title : title,
  9663. content : content
  9664. });
  9665. }
  9666. $popup = $('<div/>')
  9667. .addClass(className.popup)
  9668. .data(metadata.activator, $module)
  9669. .html(html)
  9670. ;
  9671. if(settings.inline) {
  9672. module.verbose('Inserting popup element inline', $popup);
  9673. $popup
  9674. .insertAfter($module)
  9675. ;
  9676. }
  9677. else {
  9678. module.verbose('Appending popup element to body', $popup);
  9679. $popup
  9680. .appendTo( $context )
  9681. ;
  9682. }
  9683. module.refresh();
  9684. module.set.variation();
  9685. if(settings.hoverable) {
  9686. module.bind.popup();
  9687. }
  9688. settings.onCreate.call($popup, element);
  9689. }
  9690. else if($target.next(selector.popup).length !== 0) {
  9691. module.verbose('Pre-existing popup found');
  9692. settings.inline = true;
  9693. settings.popup = $target.next(selector.popup).data(metadata.activator, $module);
  9694. module.refresh();
  9695. if(settings.hoverable) {
  9696. module.bind.popup();
  9697. }
  9698. }
  9699. else if(settings.popup) {
  9700. $(settings.popup).data(metadata.activator, $module);
  9701. module.verbose('Used popup specified in settings');
  9702. module.refresh();
  9703. if(settings.hoverable) {
  9704. module.bind.popup();
  9705. }
  9706. }
  9707. else {
  9708. module.debug('No content specified skipping display', element);
  9709. }
  9710. },
  9711. createID: function() {
  9712. id = (Math.random().toString(16) + '000000000').substr(2, 8);
  9713. elementNamespace = '.' + id;
  9714. module.verbose('Creating unique id for element', id);
  9715. },
  9716. // determines popup state
  9717. toggle: function() {
  9718. module.debug('Toggling pop-up');
  9719. if( module.is.hidden() ) {
  9720. module.debug('Popup is hidden, showing pop-up');
  9721. module.unbind.close();
  9722. module.show();
  9723. }
  9724. else {
  9725. module.debug('Popup is visible, hiding pop-up');
  9726. module.hide();
  9727. }
  9728. },
  9729. show: function(callback) {
  9730. callback = callback || function(){};
  9731. module.debug('Showing pop-up', settings.transition);
  9732. if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) {
  9733. if( !module.exists() ) {
  9734. module.create();
  9735. }
  9736. if(settings.onShow.call($popup, element) === false) {
  9737. module.debug('onShow callback returned false, cancelling popup animation');
  9738. return;
  9739. }
  9740. else if(!settings.preserve && !settings.popup) {
  9741. module.refresh();
  9742. }
  9743. if( $popup && module.set.position() ) {
  9744. module.save.conditions();
  9745. if(settings.exclusive) {
  9746. module.hideAll();
  9747. }
  9748. module.animate.show(callback);
  9749. }
  9750. }
  9751. },
  9752. hide: function(callback) {
  9753. callback = callback || function(){};
  9754. if( module.is.visible() || module.is.animating() ) {
  9755. if(settings.onHide.call($popup, element) === false) {
  9756. module.debug('onHide callback returned false, cancelling popup animation');
  9757. return;
  9758. }
  9759. module.remove.visible();
  9760. module.unbind.close();
  9761. module.restore.conditions();
  9762. module.animate.hide(callback);
  9763. }
  9764. },
  9765. hideAll: function() {
  9766. $(selector.popup)
  9767. .filter('.' + className.visible)
  9768. .each(function() {
  9769. $(this)
  9770. .data(metadata.activator)
  9771. .popup('hide')
  9772. ;
  9773. })
  9774. ;
  9775. },
  9776. exists: function() {
  9777. if(!$popup) {
  9778. return false;
  9779. }
  9780. if(settings.inline || settings.popup) {
  9781. return ( module.has.popup() );
  9782. }
  9783. else {
  9784. return ( $popup.closest($context).length >= 1 )
  9785. ? true
  9786. : false
  9787. ;
  9788. }
  9789. },
  9790. removePopup: function() {
  9791. if( module.has.popup() && !settings.popup) {
  9792. module.debug('Removing popup', $popup);
  9793. $popup.remove();
  9794. $popup = undefined;
  9795. settings.onRemove.call($popup, element);
  9796. }
  9797. },
  9798. save: {
  9799. conditions: function() {
  9800. module.cache = {
  9801. title: $module.attr('title')
  9802. };
  9803. if (module.cache.title) {
  9804. $module.removeAttr('title');
  9805. }
  9806. module.verbose('Saving original attributes', module.cache.title);
  9807. }
  9808. },
  9809. restore: {
  9810. conditions: function() {
  9811. if(module.cache && module.cache.title) {
  9812. $module.attr('title', module.cache.title);
  9813. module.verbose('Restoring original attributes', module.cache.title);
  9814. }
  9815. return true;
  9816. }
  9817. },
  9818. supports: {
  9819. svg: function() {
  9820. return (typeof SVGGraphicsElement === undefined);
  9821. }
  9822. },
  9823. animate: {
  9824. show: function(callback) {
  9825. callback = $.isFunction(callback) ? callback : function(){};
  9826. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  9827. module.set.visible();
  9828. $popup
  9829. .transition({
  9830. animation : settings.transition + ' in',
  9831. queue : false,
  9832. debug : settings.debug,
  9833. verbose : settings.verbose,
  9834. duration : settings.duration,
  9835. onComplete : function() {
  9836. module.bind.close();
  9837. callback.call($popup, element);
  9838. settings.onVisible.call($popup, element);
  9839. }
  9840. })
  9841. ;
  9842. }
  9843. else {
  9844. module.error(error.noTransition);
  9845. }
  9846. },
  9847. hide: function(callback) {
  9848. callback = $.isFunction(callback) ? callback : function(){};
  9849. module.debug('Hiding pop-up');
  9850. if(settings.onHide.call($popup, element) === false) {
  9851. module.debug('onHide callback returned false, cancelling popup animation');
  9852. return;
  9853. }
  9854. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
  9855. $popup
  9856. .transition({
  9857. animation : settings.transition + ' out',
  9858. queue : false,
  9859. duration : settings.duration,
  9860. debug : settings.debug,
  9861. verbose : settings.verbose,
  9862. onComplete : function() {
  9863. module.reset();
  9864. callback.call($popup, element);
  9865. settings.onHidden.call($popup, element);
  9866. }
  9867. })
  9868. ;
  9869. }
  9870. else {
  9871. module.error(error.noTransition);
  9872. }
  9873. }
  9874. },
  9875. change: {
  9876. content: function(html) {
  9877. $popup.html(html);
  9878. }
  9879. },
  9880. get: {
  9881. html: function() {
  9882. $module.removeData(metadata.html);
  9883. return $module.data(metadata.html) || settings.html;
  9884. },
  9885. title: function() {
  9886. $module.removeData(metadata.title);
  9887. return $module.data(metadata.title) || settings.title;
  9888. },
  9889. content: function() {
  9890. $module.removeData(metadata.content);
  9891. return $module.data(metadata.content) || $module.attr('title') || settings.content;
  9892. },
  9893. variation: function() {
  9894. $module.removeData(metadata.variation);
  9895. return $module.data(metadata.variation) || settings.variation;
  9896. },
  9897. popup: function() {
  9898. return $popup;
  9899. },
  9900. popupOffset: function() {
  9901. return $popup.offset();
  9902. },
  9903. calculations: function() {
  9904. var
  9905. targetElement = $target[0],
  9906. isWindow = ($boundary[0] == window),
  9907. targetPosition = (settings.inline || (settings.popup && settings.movePopup))
  9908. ? $target.position()
  9909. : $target.offset(),
  9910. screenPosition = (isWindow)
  9911. ? { top: 0, left: 0 }
  9912. : $boundary.offset(),
  9913. calculations = {},
  9914. scroll = (isWindow)
  9915. ? { top: $window.scrollTop(), left: $window.scrollLeft() }
  9916. : { top: 0, left: 0},
  9917. screen
  9918. ;
  9919. calculations = {
  9920. // element which is launching popup
  9921. target : {
  9922. element : $target[0],
  9923. width : $target.outerWidth(),
  9924. height : $target.outerHeight(),
  9925. top : targetPosition.top,
  9926. left : targetPosition.left,
  9927. margin : {}
  9928. },
  9929. // popup itself
  9930. popup : {
  9931. width : $popup.outerWidth(),
  9932. height : $popup.outerHeight()
  9933. },
  9934. // offset container (or 3d context)
  9935. parent : {
  9936. width : $offsetParent.outerWidth(),
  9937. height : $offsetParent.outerHeight()
  9938. },
  9939. // screen boundaries
  9940. screen : {
  9941. top : screenPosition.top,
  9942. left : screenPosition.left,
  9943. scroll: {
  9944. top : scroll.top,
  9945. left : scroll.left
  9946. },
  9947. width : $boundary.width(),
  9948. height : $boundary.height()
  9949. }
  9950. };
  9951. // add in container calcs if fluid
  9952. if( settings.setFluidWidth && module.is.fluid() ) {
  9953. calculations.container = {
  9954. width: $popup.parent().outerWidth()
  9955. };
  9956. calculations.popup.width = calculations.container.width;
  9957. }
  9958. // add in margins if inline
  9959. calculations.target.margin.top = (settings.inline)
  9960. ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10)
  9961. : 0
  9962. ;
  9963. calculations.target.margin.left = (settings.inline)
  9964. ? module.is.rtl()
  9965. ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-right'), 10)
  9966. : parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left'), 10)
  9967. : 0
  9968. ;
  9969. // calculate screen boundaries
  9970. screen = calculations.screen;
  9971. calculations.boundary = {
  9972. top : screen.top + screen.scroll.top,
  9973. bottom : screen.top + screen.scroll.top + screen.height,
  9974. left : screen.left + screen.scroll.left,
  9975. right : screen.left + screen.scroll.left + screen.width
  9976. };
  9977. return calculations;
  9978. },
  9979. id: function() {
  9980. return id;
  9981. },
  9982. startEvent: function() {
  9983. if(settings.on == 'hover') {
  9984. return 'mouseenter';
  9985. }
  9986. else if(settings.on == 'focus') {
  9987. return 'focus';
  9988. }
  9989. return false;
  9990. },
  9991. scrollEvent: function() {
  9992. return 'scroll';
  9993. },
  9994. endEvent: function() {
  9995. if(settings.on == 'hover') {
  9996. return 'mouseleave';
  9997. }
  9998. else if(settings.on == 'focus') {
  9999. return 'blur';
  10000. }
  10001. return false;
  10002. },
  10003. distanceFromBoundary: function(offset, calculations) {
  10004. var
  10005. distanceFromBoundary = {},
  10006. popup,
  10007. boundary
  10008. ;
  10009. calculations = calculations || module.get.calculations();
  10010. // shorthand
  10011. popup = calculations.popup;
  10012. boundary = calculations.boundary;
  10013. if(offset) {
  10014. distanceFromBoundary = {
  10015. top : (offset.top - boundary.top),
  10016. left : (offset.left - boundary.left),
  10017. right : (boundary.right - (offset.left + popup.width) ),
  10018. bottom : (boundary.bottom - (offset.top + popup.height) )
  10019. };
  10020. module.verbose('Distance from boundaries determined', offset, distanceFromBoundary);
  10021. }
  10022. return distanceFromBoundary;
  10023. },
  10024. offsetParent: function($target) {
  10025. var
  10026. element = ($target !== undefined)
  10027. ? $target[0]
  10028. : $module[0],
  10029. parentNode = element.parentNode,
  10030. $node = $(parentNode)
  10031. ;
  10032. if(parentNode) {
  10033. var
  10034. is2D = ($node.css('transform') === 'none'),
  10035. isStatic = ($node.css('position') === 'static'),
  10036. isHTML = $node.is('html')
  10037. ;
  10038. while(parentNode && !isHTML && isStatic && is2D) {
  10039. parentNode = parentNode.parentNode;
  10040. $node = $(parentNode);
  10041. is2D = ($node.css('transform') === 'none');
  10042. isStatic = ($node.css('position') === 'static');
  10043. isHTML = $node.is('html');
  10044. }
  10045. }
  10046. return ($node && $node.length > 0)
  10047. ? $node
  10048. : $()
  10049. ;
  10050. },
  10051. positions: function() {
  10052. return {
  10053. 'top left' : false,
  10054. 'top center' : false,
  10055. 'top right' : false,
  10056. 'bottom left' : false,
  10057. 'bottom center' : false,
  10058. 'bottom right' : false,
  10059. 'left center' : false,
  10060. 'right center' : false
  10061. };
  10062. },
  10063. nextPosition: function(position) {
  10064. var
  10065. positions = position.split(' '),
  10066. verticalPosition = positions[0],
  10067. horizontalPosition = positions[1],
  10068. opposite = {
  10069. top : 'bottom',
  10070. bottom : 'top',
  10071. left : 'right',
  10072. right : 'left'
  10073. },
  10074. adjacent = {
  10075. left : 'center',
  10076. center : 'right',
  10077. right : 'left'
  10078. },
  10079. backup = {
  10080. 'top left' : 'top center',
  10081. 'top center' : 'top right',
  10082. 'top right' : 'right center',
  10083. 'right center' : 'bottom right',
  10084. 'bottom right' : 'bottom center',
  10085. 'bottom center' : 'bottom left',
  10086. 'bottom left' : 'left center',
  10087. 'left center' : 'top left'
  10088. },
  10089. adjacentsAvailable = (verticalPosition == 'top' || verticalPosition == 'bottom'),
  10090. oppositeTried = false,
  10091. adjacentTried = false,
  10092. nextPosition = false
  10093. ;
  10094. if(!triedPositions) {
  10095. module.verbose('All available positions available');
  10096. triedPositions = module.get.positions();
  10097. }
  10098. module.debug('Recording last position tried', position);
  10099. triedPositions[position] = true;
  10100. if(settings.prefer === 'opposite') {
  10101. nextPosition = [opposite[verticalPosition], horizontalPosition];
  10102. nextPosition = nextPosition.join(' ');
  10103. oppositeTried = (triedPositions[nextPosition] === true);
  10104. module.debug('Trying opposite strategy', nextPosition);
  10105. }
  10106. if((settings.prefer === 'adjacent') && adjacentsAvailable ) {
  10107. nextPosition = [verticalPosition, adjacent[horizontalPosition]];
  10108. nextPosition = nextPosition.join(' ');
  10109. adjacentTried = (triedPositions[nextPosition] === true);
  10110. module.debug('Trying adjacent strategy', nextPosition);
  10111. }
  10112. if(adjacentTried || oppositeTried) {
  10113. module.debug('Using backup position', nextPosition);
  10114. nextPosition = backup[position];
  10115. }
  10116. return nextPosition;
  10117. }
  10118. },
  10119. set: {
  10120. position: function(position, calculations) {
  10121. // exit conditions
  10122. if($target.length === 0 || $popup.length === 0) {
  10123. module.error(error.notFound);
  10124. return;
  10125. }
  10126. var
  10127. offset,
  10128. distanceAway,
  10129. target,
  10130. popup,
  10131. parent,
  10132. positioning,
  10133. popupOffset,
  10134. distanceFromBoundary
  10135. ;
  10136. calculations = calculations || module.get.calculations();
  10137. position = position || $module.data(metadata.position) || settings.position;
  10138. offset = $module.data(metadata.offset) || settings.offset;
  10139. distanceAway = settings.distanceAway;
  10140. // shorthand
  10141. target = calculations.target;
  10142. popup = calculations.popup;
  10143. parent = calculations.parent;
  10144. if(target.width === 0 && target.height === 0 && !module.is.svg(target.element)) {
  10145. module.debug('Popup target is hidden, no action taken');
  10146. return false;
  10147. }
  10148. if(settings.inline) {
  10149. module.debug('Adding margin to calculation', target.margin);
  10150. if(position == 'left center' || position == 'right center') {
  10151. offset += target.margin.top;
  10152. distanceAway += -target.margin.left;
  10153. }
  10154. else if (position == 'top left' || position == 'top center' || position == 'top right') {
  10155. offset += target.margin.left;
  10156. distanceAway -= target.margin.top;
  10157. }
  10158. else {
  10159. offset += target.margin.left;
  10160. distanceAway += target.margin.top;
  10161. }
  10162. }
  10163. module.debug('Determining popup position from calculations', position, calculations);
  10164. if (module.is.rtl()) {
  10165. position = position.replace(/left|right/g, function (match) {
  10166. return (match == 'left')
  10167. ? 'right'
  10168. : 'left'
  10169. ;
  10170. });
  10171. module.debug('RTL: Popup position updated', position);
  10172. }
  10173. // if last attempt use specified last resort position
  10174. if(searchDepth == settings.maxSearchDepth && typeof settings.lastResort === 'string') {
  10175. position = settings.lastResort;
  10176. }
  10177. switch (position) {
  10178. case 'top left':
  10179. positioning = {
  10180. top : 'auto',
  10181. bottom : parent.height - target.top + distanceAway,
  10182. left : target.left + offset,
  10183. right : 'auto'
  10184. };
  10185. break;
  10186. case 'top center':
  10187. positioning = {
  10188. bottom : parent.height - target.top + distanceAway,
  10189. left : target.left + (target.width / 2) - (popup.width / 2) + offset,
  10190. top : 'auto',
  10191. right : 'auto'
  10192. };
  10193. break;
  10194. case 'top right':
  10195. positioning = {
  10196. bottom : parent.height - target.top + distanceAway,
  10197. right : parent.width - target.left - target.width - offset,
  10198. top : 'auto',
  10199. left : 'auto'
  10200. };
  10201. break;
  10202. case 'left center':
  10203. positioning = {
  10204. top : target.top + (target.height / 2) - (popup.height / 2) + offset,
  10205. right : parent.width - target.left + distanceAway,
  10206. left : 'auto',
  10207. bottom : 'auto'
  10208. };
  10209. break;
  10210. case 'right center':
  10211. positioning = {
  10212. top : target.top + (target.height / 2) - (popup.height / 2) + offset,
  10213. left : target.left + target.width + distanceAway,
  10214. bottom : 'auto',
  10215. right : 'auto'
  10216. };
  10217. break;
  10218. case 'bottom left':
  10219. positioning = {
  10220. top : target.top + target.height + distanceAway,
  10221. left : target.left + offset,
  10222. bottom : 'auto',
  10223. right : 'auto'
  10224. };
  10225. break;
  10226. case 'bottom center':
  10227. positioning = {
  10228. top : target.top + target.height + distanceAway,
  10229. left : target.left + (target.width / 2) - (popup.width / 2) + offset,
  10230. bottom : 'auto',
  10231. right : 'auto'
  10232. };
  10233. break;
  10234. case 'bottom right':
  10235. positioning = {
  10236. top : target.top + target.height + distanceAway,
  10237. right : parent.width - target.left - target.width - offset,
  10238. left : 'auto',
  10239. bottom : 'auto'
  10240. };
  10241. break;
  10242. }
  10243. if(positioning === undefined) {
  10244. module.error(error.invalidPosition, position);
  10245. }
  10246. module.debug('Calculated popup positioning values', positioning);
  10247. // tentatively place on stage
  10248. $popup
  10249. .css(positioning)
  10250. .removeClass(className.position)
  10251. .addClass(position)
  10252. .addClass(className.loading)
  10253. ;
  10254. popupOffset = module.get.popupOffset();
  10255. // see if any boundaries are surpassed with this tentative position
  10256. distanceFromBoundary = module.get.distanceFromBoundary(popupOffset, calculations);
  10257. if( module.is.offstage(distanceFromBoundary, position) ) {
  10258. module.debug('Position is outside viewport', position);
  10259. if(searchDepth < settings.maxSearchDepth) {
  10260. searchDepth++;
  10261. position = module.get.nextPosition(position);
  10262. module.debug('Trying new position', position);
  10263. return ($popup)
  10264. ? module.set.position(position, calculations)
  10265. : false
  10266. ;
  10267. }
  10268. else {
  10269. if(settings.lastResort) {
  10270. module.debug('No position found, showing with last position');
  10271. }
  10272. else {
  10273. module.debug('Popup could not find a position to display', $popup);
  10274. module.error(error.cannotPlace, element);
  10275. module.remove.attempts();
  10276. module.remove.loading();
  10277. module.reset();
  10278. settings.onUnplaceable.call($popup, element);
  10279. return false;
  10280. }
  10281. }
  10282. }
  10283. module.debug('Position is on stage', position);
  10284. module.remove.attempts();
  10285. module.remove.loading();
  10286. if( settings.setFluidWidth && module.is.fluid() ) {
  10287. module.set.fluidWidth(calculations);
  10288. }
  10289. return true;
  10290. },
  10291. fluidWidth: function(calculations) {
  10292. calculations = calculations || module.get.calculations();
  10293. module.debug('Automatically setting element width to parent width', calculations.parent.width);
  10294. $popup.css('width', calculations.container.width);
  10295. },
  10296. variation: function(variation) {
  10297. variation = variation || module.get.variation();
  10298. if(variation && module.has.popup() ) {
  10299. module.verbose('Adding variation to popup', variation);
  10300. $popup.addClass(variation);
  10301. }
  10302. },
  10303. visible: function() {
  10304. $module.addClass(className.visible);
  10305. }
  10306. },
  10307. remove: {
  10308. loading: function() {
  10309. $popup.removeClass(className.loading);
  10310. },
  10311. variation: function(variation) {
  10312. variation = variation || module.get.variation();
  10313. if(variation) {
  10314. module.verbose('Removing variation', variation);
  10315. $popup.removeClass(variation);
  10316. }
  10317. },
  10318. visible: function() {
  10319. $module.removeClass(className.visible);
  10320. },
  10321. attempts: function() {
  10322. module.verbose('Resetting all searched positions');
  10323. searchDepth = 0;
  10324. triedPositions = false;
  10325. }
  10326. },
  10327. bind: {
  10328. events: function() {
  10329. module.debug('Binding popup events to module');
  10330. if(settings.on == 'click') {
  10331. $module
  10332. .on('click' + eventNamespace, module.toggle)
  10333. ;
  10334. }
  10335. if(settings.on == 'hover' && hasTouch) {
  10336. $module
  10337. .on('touchstart' + eventNamespace, module.event.touchstart)
  10338. ;
  10339. }
  10340. if( module.get.startEvent() ) {
  10341. $module
  10342. .on(module.get.startEvent() + eventNamespace, module.event.start)
  10343. .on(module.get.endEvent() + eventNamespace, module.event.end)
  10344. ;
  10345. }
  10346. if(settings.target) {
  10347. module.debug('Target set to element', $target);
  10348. }
  10349. $window.on('resize' + elementNamespace, module.event.resize);
  10350. },
  10351. popup: function() {
  10352. module.verbose('Allowing hover events on popup to prevent closing');
  10353. if( $popup && module.has.popup() ) {
  10354. $popup
  10355. .on('mouseenter' + eventNamespace, module.event.start)
  10356. .on('mouseleave' + eventNamespace, module.event.end)
  10357. ;
  10358. }
  10359. },
  10360. close: function() {
  10361. if(settings.hideOnScroll === true || (settings.hideOnScroll == 'auto' && settings.on != 'click')) {
  10362. $scrollContext
  10363. .one(module.get.scrollEvent() + elementNamespace, module.event.hideGracefully)
  10364. ;
  10365. }
  10366. if(settings.on == 'hover' && openedWithTouch) {
  10367. module.verbose('Binding popup close event to document');
  10368. $document
  10369. .on('touchstart' + elementNamespace, function(event) {
  10370. module.verbose('Touched away from popup');
  10371. module.event.hideGracefully.call(element, event);
  10372. })
  10373. ;
  10374. }
  10375. if(settings.on == 'click' && settings.closable) {
  10376. module.verbose('Binding popup close event to document');
  10377. $document
  10378. .on('click' + elementNamespace, function(event) {
  10379. module.verbose('Clicked away from popup');
  10380. module.event.hideGracefully.call(element, event);
  10381. })
  10382. ;
  10383. }
  10384. }
  10385. },
  10386. unbind: {
  10387. events: function() {
  10388. $window
  10389. .off(elementNamespace)
  10390. ;
  10391. $module
  10392. .off(eventNamespace)
  10393. ;
  10394. },
  10395. close: function() {
  10396. $document
  10397. .off(elementNamespace)
  10398. ;
  10399. $scrollContext
  10400. .off(elementNamespace)
  10401. ;
  10402. },
  10403. },
  10404. has: {
  10405. popup: function() {
  10406. return ($popup && $popup.length > 0);
  10407. }
  10408. },
  10409. is: {
  10410. offstage: function(distanceFromBoundary, position) {
  10411. var
  10412. offstage = []
  10413. ;
  10414. // return boundaries that have been surpassed
  10415. $.each(distanceFromBoundary, function(direction, distance) {
  10416. if(distance < -settings.jitter) {
  10417. module.debug('Position exceeds allowable distance from edge', direction, distance, position);
  10418. offstage.push(direction);
  10419. }
  10420. });
  10421. if(offstage.length > 0) {
  10422. return true;
  10423. }
  10424. else {
  10425. return false;
  10426. }
  10427. },
  10428. svg: function(element) {
  10429. return module.supports.svg() && (element instanceof SVGGraphicsElement);
  10430. },
  10431. active: function() {
  10432. return $module.hasClass(className.active);
  10433. },
  10434. animating: function() {
  10435. return ($popup !== undefined && $popup.hasClass(className.animating) );
  10436. },
  10437. fluid: function() {
  10438. return ($popup !== undefined && $popup.hasClass(className.fluid));
  10439. },
  10440. visible: function() {
  10441. return ($popup !== undefined && $popup.hasClass(className.visible));
  10442. },
  10443. dropdown: function() {
  10444. return $module.hasClass(className.dropdown);
  10445. },
  10446. hidden: function() {
  10447. return !module.is.visible();
  10448. },
  10449. rtl: function () {
  10450. return $module.css('direction') == 'rtl';
  10451. }
  10452. },
  10453. reset: function() {
  10454. module.remove.visible();
  10455. if(settings.preserve) {
  10456. if($.fn.transition !== undefined) {
  10457. $popup
  10458. .transition('remove transition')
  10459. ;
  10460. }
  10461. }
  10462. else {
  10463. module.removePopup();
  10464. }
  10465. },
  10466. setting: function(name, value) {
  10467. if( $.isPlainObject(name) ) {
  10468. $.extend(true, settings, name);
  10469. }
  10470. else if(value !== undefined) {
  10471. settings[name] = value;
  10472. }
  10473. else {
  10474. return settings[name];
  10475. }
  10476. },
  10477. internal: function(name, value) {
  10478. if( $.isPlainObject(name) ) {
  10479. $.extend(true, module, name);
  10480. }
  10481. else if(value !== undefined) {
  10482. module[name] = value;
  10483. }
  10484. else {
  10485. return module[name];
  10486. }
  10487. },
  10488. debug: function() {
  10489. if(!settings.silent && settings.debug) {
  10490. if(settings.performance) {
  10491. module.performance.log(arguments);
  10492. }
  10493. else {
  10494. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  10495. module.debug.apply(console, arguments);
  10496. }
  10497. }
  10498. },
  10499. verbose: function() {
  10500. if(!settings.silent && settings.verbose && settings.debug) {
  10501. if(settings.performance) {
  10502. module.performance.log(arguments);
  10503. }
  10504. else {
  10505. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  10506. module.verbose.apply(console, arguments);
  10507. }
  10508. }
  10509. },
  10510. error: function() {
  10511. if(!settings.silent) {
  10512. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  10513. module.error.apply(console, arguments);
  10514. }
  10515. },
  10516. performance: {
  10517. log: function(message) {
  10518. var
  10519. currentTime,
  10520. executionTime,
  10521. previousTime
  10522. ;
  10523. if(settings.performance) {
  10524. currentTime = new Date().getTime();
  10525. previousTime = time || currentTime;
  10526. executionTime = currentTime - previousTime;
  10527. time = currentTime;
  10528. performance.push({
  10529. 'Name' : message[0],
  10530. 'Arguments' : [].slice.call(message, 1) || '',
  10531. 'Element' : element,
  10532. 'Execution Time' : executionTime
  10533. });
  10534. }
  10535. clearTimeout(module.performance.timer);
  10536. module.performance.timer = setTimeout(module.performance.display, 500);
  10537. },
  10538. display: function() {
  10539. var
  10540. title = settings.name + ':',
  10541. totalTime = 0
  10542. ;
  10543. time = false;
  10544. clearTimeout(module.performance.timer);
  10545. $.each(performance, function(index, data) {
  10546. totalTime += data['Execution Time'];
  10547. });
  10548. title += ' ' + totalTime + 'ms';
  10549. if(moduleSelector) {
  10550. title += ' \'' + moduleSelector + '\'';
  10551. }
  10552. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  10553. console.groupCollapsed(title);
  10554. if(console.table) {
  10555. console.table(performance);
  10556. }
  10557. else {
  10558. $.each(performance, function(index, data) {
  10559. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  10560. });
  10561. }
  10562. console.groupEnd();
  10563. }
  10564. performance = [];
  10565. }
  10566. },
  10567. invoke: function(query, passedArguments, context) {
  10568. var
  10569. object = instance,
  10570. maxDepth,
  10571. found,
  10572. response
  10573. ;
  10574. passedArguments = passedArguments || queryArguments;
  10575. context = element || context;
  10576. if(typeof query == 'string' && object !== undefined) {
  10577. query = query.split(/[\. ]/);
  10578. maxDepth = query.length - 1;
  10579. $.each(query, function(depth, value) {
  10580. var camelCaseValue = (depth != maxDepth)
  10581. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  10582. : query
  10583. ;
  10584. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  10585. object = object[camelCaseValue];
  10586. }
  10587. else if( object[camelCaseValue] !== undefined ) {
  10588. found = object[camelCaseValue];
  10589. return false;
  10590. }
  10591. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  10592. object = object[value];
  10593. }
  10594. else if( object[value] !== undefined ) {
  10595. found = object[value];
  10596. return false;
  10597. }
  10598. else {
  10599. return false;
  10600. }
  10601. });
  10602. }
  10603. if ( $.isFunction( found ) ) {
  10604. response = found.apply(context, passedArguments);
  10605. }
  10606. else if(found !== undefined) {
  10607. response = found;
  10608. }
  10609. if($.isArray(returnedValue)) {
  10610. returnedValue.push(response);
  10611. }
  10612. else if(returnedValue !== undefined) {
  10613. returnedValue = [returnedValue, response];
  10614. }
  10615. else if(response !== undefined) {
  10616. returnedValue = response;
  10617. }
  10618. return found;
  10619. }
  10620. };
  10621. if(methodInvoked) {
  10622. if(instance === undefined) {
  10623. module.initialize();
  10624. }
  10625. module.invoke(query);
  10626. }
  10627. else {
  10628. if(instance !== undefined) {
  10629. instance.invoke('destroy');
  10630. }
  10631. module.initialize();
  10632. }
  10633. })
  10634. ;
  10635. return (returnedValue !== undefined)
  10636. ? returnedValue
  10637. : this
  10638. ;
  10639. };
  10640. $.fn.popup.settings = {
  10641. name : 'Popup',
  10642. // module settings
  10643. silent : false,
  10644. debug : false,
  10645. verbose : false,
  10646. performance : true,
  10647. namespace : 'popup',
  10648. // whether it should use dom mutation observers
  10649. observeChanges : true,
  10650. // callback only when element added to dom
  10651. onCreate : function(){},
  10652. // callback before element removed from dom
  10653. onRemove : function(){},
  10654. // callback before show animation
  10655. onShow : function(){},
  10656. // callback after show animation
  10657. onVisible : function(){},
  10658. // callback before hide animation
  10659. onHide : function(){},
  10660. // callback when popup cannot be positioned in visible screen
  10661. onUnplaceable : function(){},
  10662. // callback after hide animation
  10663. onHidden : function(){},
  10664. // when to show popup
  10665. on : 'hover',
  10666. // element to use to determine if popup is out of boundary
  10667. boundary : window,
  10668. // whether to add touchstart events when using hover
  10669. addTouchEvents : true,
  10670. // default position relative to element
  10671. position : 'top left',
  10672. // name of variation to use
  10673. variation : '',
  10674. // whether popup should be moved to context
  10675. movePopup : true,
  10676. // element which popup should be relative to
  10677. target : false,
  10678. // jq selector or element that should be used as popup
  10679. popup : false,
  10680. // popup should remain inline next to activator
  10681. inline : false,
  10682. // popup should be removed from page on hide
  10683. preserve : false,
  10684. // popup should not close when being hovered on
  10685. hoverable : false,
  10686. // explicitly set content
  10687. content : false,
  10688. // explicitly set html
  10689. html : false,
  10690. // explicitly set title
  10691. title : false,
  10692. // whether automatically close on clickaway when on click
  10693. closable : true,
  10694. // automatically hide on scroll
  10695. hideOnScroll : 'auto',
  10696. // hide other popups on show
  10697. exclusive : false,
  10698. // context to attach popups
  10699. context : 'body',
  10700. // context for binding scroll events
  10701. scrollContext : window,
  10702. // position to prefer when calculating new position
  10703. prefer : 'opposite',
  10704. // specify position to appear even if it doesn't fit
  10705. lastResort : false,
  10706. // delay used to prevent accidental refiring of animations due to user error
  10707. delay : {
  10708. show : 50,
  10709. hide : 70
  10710. },
  10711. // whether fluid variation should assign width explicitly
  10712. setFluidWidth : true,
  10713. // transition settings
  10714. duration : 200,
  10715. transition : 'scale',
  10716. // distance away from activating element in px
  10717. distanceAway : 0,
  10718. // number of pixels an element is allowed to be "offstage" for a position to be chosen (allows for rounding)
  10719. jitter : 2,
  10720. // offset on aligning axis from calculated position
  10721. offset : 0,
  10722. // maximum times to look for a position before failing (9 positions total)
  10723. maxSearchDepth : 15,
  10724. error: {
  10725. invalidPosition : 'The position you specified is not a valid position',
  10726. cannotPlace : 'Popup does not fit within the boundaries of the viewport',
  10727. method : 'The method you called is not defined.',
  10728. noTransition : 'This module requires ui transitions <https://github.com/Semantic-Org/UI-Transition>',
  10729. notFound : 'The target or popup you specified does not exist on the page'
  10730. },
  10731. metadata: {
  10732. activator : 'activator',
  10733. content : 'content',
  10734. html : 'html',
  10735. offset : 'offset',
  10736. position : 'position',
  10737. title : 'title',
  10738. variation : 'variation'
  10739. },
  10740. className : {
  10741. active : 'active',
  10742. animating : 'animating',
  10743. dropdown : 'dropdown',
  10744. fluid : 'fluid',
  10745. loading : 'loading',
  10746. popup : 'ui popup',
  10747. position : 'top left center bottom right',
  10748. visible : 'visible'
  10749. },
  10750. selector : {
  10751. popup : '.ui.popup'
  10752. },
  10753. templates: {
  10754. escape: function(string) {
  10755. var
  10756. badChars = /[&<>"'`]/g,
  10757. shouldEscape = /[&<>"'`]/,
  10758. escape = {
  10759. "&": "&amp;",
  10760. "<": "&lt;",
  10761. ">": "&gt;",
  10762. '"': "&quot;",
  10763. "'": "&#x27;",
  10764. "`": "&#x60;"
  10765. },
  10766. escapedChar = function(chr) {
  10767. return escape[chr];
  10768. }
  10769. ;
  10770. if(shouldEscape.test(string)) {
  10771. return string.replace(badChars, escapedChar);
  10772. }
  10773. return string;
  10774. },
  10775. popup: function(text) {
  10776. var
  10777. html = '',
  10778. escape = $.fn.popup.settings.templates.escape
  10779. ;
  10780. if(typeof text !== undefined) {
  10781. if(typeof text.title !== undefined && text.title) {
  10782. text.title = escape(text.title);
  10783. html += '<div class="header">' + text.title + '</div>';
  10784. }
  10785. if(typeof text.content !== undefined && text.content) {
  10786. text.content = escape(text.content);
  10787. html += '<div class="content">' + text.content + '</div>';
  10788. }
  10789. }
  10790. return html;
  10791. }
  10792. }
  10793. };
  10794. })( jQuery, window, document );
  10795. /*!
  10796. * # Semantic UI 2.2.6 - Progress
  10797. * http://github.com/semantic-org/semantic-ui/
  10798. *
  10799. *
  10800. * Released under the MIT license
  10801. * http://opensource.org/licenses/MIT
  10802. *
  10803. */
  10804. ;(function ($, window, document, undefined) {
  10805. "use strict";
  10806. window = (typeof window != 'undefined' && window.Math == Math)
  10807. ? window
  10808. : (typeof self != 'undefined' && self.Math == Math)
  10809. ? self
  10810. : Function('return this')()
  10811. ;
  10812. var
  10813. global = (typeof window != 'undefined' && window.Math == Math)
  10814. ? window
  10815. : (typeof self != 'undefined' && self.Math == Math)
  10816. ? self
  10817. : Function('return this')()
  10818. ;
  10819. $.fn.progress = function(parameters) {
  10820. var
  10821. $allModules = $(this),
  10822. moduleSelector = $allModules.selector || '',
  10823. time = new Date().getTime(),
  10824. performance = [],
  10825. query = arguments[0],
  10826. methodInvoked = (typeof query == 'string'),
  10827. queryArguments = [].slice.call(arguments, 1),
  10828. returnedValue
  10829. ;
  10830. $allModules
  10831. .each(function() {
  10832. var
  10833. settings = ( $.isPlainObject(parameters) )
  10834. ? $.extend(true, {}, $.fn.progress.settings, parameters)
  10835. : $.extend({}, $.fn.progress.settings),
  10836. className = settings.className,
  10837. metadata = settings.metadata,
  10838. namespace = settings.namespace,
  10839. selector = settings.selector,
  10840. error = settings.error,
  10841. eventNamespace = '.' + namespace,
  10842. moduleNamespace = 'module-' + namespace,
  10843. $module = $(this),
  10844. $bar = $(this).find(selector.bar),
  10845. $progress = $(this).find(selector.progress),
  10846. $label = $(this).find(selector.label),
  10847. element = this,
  10848. instance = $module.data(moduleNamespace),
  10849. animating = false,
  10850. transitionEnd,
  10851. module
  10852. ;
  10853. module = {
  10854. initialize: function() {
  10855. module.debug('Initializing progress bar', settings);
  10856. module.set.duration();
  10857. module.set.transitionEvent();
  10858. module.read.metadata();
  10859. module.read.settings();
  10860. module.instantiate();
  10861. },
  10862. instantiate: function() {
  10863. module.verbose('Storing instance of progress', module);
  10864. instance = module;
  10865. $module
  10866. .data(moduleNamespace, module)
  10867. ;
  10868. },
  10869. destroy: function() {
  10870. module.verbose('Destroying previous progress for', $module);
  10871. clearInterval(instance.interval);
  10872. module.remove.state();
  10873. $module.removeData(moduleNamespace);
  10874. instance = undefined;
  10875. },
  10876. reset: function() {
  10877. module.remove.nextValue();
  10878. module.update.progress(0);
  10879. },
  10880. complete: function() {
  10881. if(module.percent === undefined || module.percent < 100) {
  10882. module.remove.progressPoll();
  10883. module.set.percent(100);
  10884. }
  10885. },
  10886. read: {
  10887. metadata: function() {
  10888. var
  10889. data = {
  10890. percent : $module.data(metadata.percent),
  10891. total : $module.data(metadata.total),
  10892. value : $module.data(metadata.value)
  10893. }
  10894. ;
  10895. if(data.percent) {
  10896. module.debug('Current percent value set from metadata', data.percent);
  10897. module.set.percent(data.percent);
  10898. }
  10899. if(data.total) {
  10900. module.debug('Total value set from metadata', data.total);
  10901. module.set.total(data.total);
  10902. }
  10903. if(data.value) {
  10904. module.debug('Current value set from metadata', data.value);
  10905. module.set.value(data.value);
  10906. module.set.progress(data.value);
  10907. }
  10908. },
  10909. settings: function() {
  10910. if(settings.total !== false) {
  10911. module.debug('Current total set in settings', settings.total);
  10912. module.set.total(settings.total);
  10913. }
  10914. if(settings.value !== false) {
  10915. module.debug('Current value set in settings', settings.value);
  10916. module.set.value(settings.value);
  10917. module.set.progress(module.value);
  10918. }
  10919. if(settings.percent !== false) {
  10920. module.debug('Current percent set in settings', settings.percent);
  10921. module.set.percent(settings.percent);
  10922. }
  10923. }
  10924. },
  10925. bind: {
  10926. transitionEnd: function(callback) {
  10927. var
  10928. transitionEnd = module.get.transitionEnd()
  10929. ;
  10930. $bar
  10931. .one(transitionEnd + eventNamespace, function(event) {
  10932. clearTimeout(module.failSafeTimer);
  10933. callback.call(this, event);
  10934. })
  10935. ;
  10936. module.failSafeTimer = setTimeout(function() {
  10937. $bar.triggerHandler(transitionEnd);
  10938. }, settings.duration + settings.failSafeDelay);
  10939. module.verbose('Adding fail safe timer', module.timer);
  10940. }
  10941. },
  10942. increment: function(incrementValue) {
  10943. var
  10944. maxValue,
  10945. startValue,
  10946. newValue
  10947. ;
  10948. if( module.has.total() ) {
  10949. startValue = module.get.value();
  10950. incrementValue = incrementValue || 1;
  10951. newValue = startValue + incrementValue;
  10952. }
  10953. else {
  10954. startValue = module.get.percent();
  10955. incrementValue = incrementValue || module.get.randomValue();
  10956. newValue = startValue + incrementValue;
  10957. maxValue = 100;
  10958. module.debug('Incrementing percentage by', startValue, newValue);
  10959. }
  10960. newValue = module.get.normalizedValue(newValue);
  10961. module.set.progress(newValue);
  10962. },
  10963. decrement: function(decrementValue) {
  10964. var
  10965. total = module.get.total(),
  10966. startValue,
  10967. newValue
  10968. ;
  10969. if(total) {
  10970. startValue = module.get.value();
  10971. decrementValue = decrementValue || 1;
  10972. newValue = startValue - decrementValue;
  10973. module.debug('Decrementing value by', decrementValue, startValue);
  10974. }
  10975. else {
  10976. startValue = module.get.percent();
  10977. decrementValue = decrementValue || module.get.randomValue();
  10978. newValue = startValue - decrementValue;
  10979. module.debug('Decrementing percentage by', decrementValue, startValue);
  10980. }
  10981. newValue = module.get.normalizedValue(newValue);
  10982. module.set.progress(newValue);
  10983. },
  10984. has: {
  10985. progressPoll: function() {
  10986. return module.progressPoll;
  10987. },
  10988. total: function() {
  10989. return (module.get.total() !== false);
  10990. }
  10991. },
  10992. get: {
  10993. text: function(templateText) {
  10994. var
  10995. value = module.value || 0,
  10996. total = module.total || 0,
  10997. percent = (animating)
  10998. ? module.get.displayPercent()
  10999. : module.percent || 0,
  11000. left = (module.total > 0)
  11001. ? (total - value)
  11002. : (100 - percent)
  11003. ;
  11004. templateText = templateText || '';
  11005. templateText = templateText
  11006. .replace('{value}', value)
  11007. .replace('{total}', total)
  11008. .replace('{left}', left)
  11009. .replace('{percent}', percent)
  11010. ;
  11011. module.verbose('Adding variables to progress bar text', templateText);
  11012. return templateText;
  11013. },
  11014. normalizedValue: function(value) {
  11015. if(value < 0) {
  11016. module.debug('Value cannot decrement below 0');
  11017. return 0;
  11018. }
  11019. if(module.has.total()) {
  11020. if(value > module.total) {
  11021. module.debug('Value cannot increment above total', module.total);
  11022. return module.total;
  11023. }
  11024. }
  11025. else if(value > 100 ) {
  11026. module.debug('Value cannot increment above 100 percent');
  11027. return 100;
  11028. }
  11029. return value;
  11030. },
  11031. updateInterval: function() {
  11032. if(settings.updateInterval == 'auto') {
  11033. return settings.duration;
  11034. }
  11035. return settings.updateInterval;
  11036. },
  11037. randomValue: function() {
  11038. module.debug('Generating random increment percentage');
  11039. return Math.floor((Math.random() * settings.random.max) + settings.random.min);
  11040. },
  11041. numericValue: function(value) {
  11042. return (typeof value === 'string')
  11043. ? (value.replace(/[^\d.]/g, '') !== '')
  11044. ? +(value.replace(/[^\d.]/g, ''))
  11045. : false
  11046. : value
  11047. ;
  11048. },
  11049. transitionEnd: function() {
  11050. var
  11051. element = document.createElement('element'),
  11052. transitions = {
  11053. 'transition' :'transitionend',
  11054. 'OTransition' :'oTransitionEnd',
  11055. 'MozTransition' :'transitionend',
  11056. 'WebkitTransition' :'webkitTransitionEnd'
  11057. },
  11058. transition
  11059. ;
  11060. for(transition in transitions){
  11061. if( element.style[transition] !== undefined ){
  11062. return transitions[transition];
  11063. }
  11064. }
  11065. },
  11066. // gets current displayed percentage (if animating values this is the intermediary value)
  11067. displayPercent: function() {
  11068. var
  11069. barWidth = $bar.width(),
  11070. totalWidth = $module.width(),
  11071. minDisplay = parseInt($bar.css('min-width'), 10),
  11072. displayPercent = (barWidth > minDisplay)
  11073. ? (barWidth / totalWidth * 100)
  11074. : module.percent
  11075. ;
  11076. return (settings.precision > 0)
  11077. ? Math.round(displayPercent * (10 * settings.precision)) / (10 * settings.precision)
  11078. : Math.round(displayPercent)
  11079. ;
  11080. },
  11081. percent: function() {
  11082. return module.percent || 0;
  11083. },
  11084. value: function() {
  11085. return module.nextValue || module.value || 0;
  11086. },
  11087. total: function() {
  11088. return module.total || false;
  11089. }
  11090. },
  11091. create: {
  11092. progressPoll: function() {
  11093. module.progressPoll = setTimeout(function() {
  11094. module.update.toNextValue();
  11095. module.remove.progressPoll();
  11096. }, module.get.updateInterval());
  11097. },
  11098. },
  11099. is: {
  11100. complete: function() {
  11101. return module.is.success() || module.is.warning() || module.is.error();
  11102. },
  11103. success: function() {
  11104. return $module.hasClass(className.success);
  11105. },
  11106. warning: function() {
  11107. return $module.hasClass(className.warning);
  11108. },
  11109. error: function() {
  11110. return $module.hasClass(className.error);
  11111. },
  11112. active: function() {
  11113. return $module.hasClass(className.active);
  11114. },
  11115. visible: function() {
  11116. return $module.is(':visible');
  11117. }
  11118. },
  11119. remove: {
  11120. progressPoll: function() {
  11121. module.verbose('Removing progress poll timer');
  11122. if(module.progressPoll) {
  11123. clearTimeout(module.progressPoll);
  11124. delete module.progressPoll;
  11125. }
  11126. },
  11127. nextValue: function() {
  11128. module.verbose('Removing progress value stored for next update');
  11129. delete module.nextValue;
  11130. },
  11131. state: function() {
  11132. module.verbose('Removing stored state');
  11133. delete module.total;
  11134. delete module.percent;
  11135. delete module.value;
  11136. },
  11137. active: function() {
  11138. module.verbose('Removing active state');
  11139. $module.removeClass(className.active);
  11140. },
  11141. success: function() {
  11142. module.verbose('Removing success state');
  11143. $module.removeClass(className.success);
  11144. },
  11145. warning: function() {
  11146. module.verbose('Removing warning state');
  11147. $module.removeClass(className.warning);
  11148. },
  11149. error: function() {
  11150. module.verbose('Removing error state');
  11151. $module.removeClass(className.error);
  11152. }
  11153. },
  11154. set: {
  11155. barWidth: function(value) {
  11156. if(value > 100) {
  11157. module.error(error.tooHigh, value);
  11158. }
  11159. else if (value < 0) {
  11160. module.error(error.tooLow, value);
  11161. }
  11162. else {
  11163. $bar
  11164. .css('width', value + '%')
  11165. ;
  11166. $module
  11167. .attr('data-percent', parseInt(value, 10))
  11168. ;
  11169. }
  11170. },
  11171. duration: function(duration) {
  11172. duration = duration || settings.duration;
  11173. duration = (typeof duration == 'number')
  11174. ? duration + 'ms'
  11175. : duration
  11176. ;
  11177. module.verbose('Setting progress bar transition duration', duration);
  11178. $bar
  11179. .css({
  11180. 'transition-duration': duration
  11181. })
  11182. ;
  11183. },
  11184. percent: function(percent) {
  11185. percent = (typeof percent == 'string')
  11186. ? +(percent.replace('%', ''))
  11187. : percent
  11188. ;
  11189. // round display percentage
  11190. percent = (settings.precision > 0)
  11191. ? Math.round(percent * (10 * settings.precision)) / (10 * settings.precision)
  11192. : Math.round(percent)
  11193. ;
  11194. module.percent = percent;
  11195. if( !module.has.total() ) {
  11196. module.value = (settings.precision > 0)
  11197. ? Math.round( (percent / 100) * module.total * (10 * settings.precision)) / (10 * settings.precision)
  11198. : Math.round( (percent / 100) * module.total * 10) / 10
  11199. ;
  11200. if(settings.limitValues) {
  11201. module.value = (module.value > 100)
  11202. ? 100
  11203. : (module.value < 0)
  11204. ? 0
  11205. : module.value
  11206. ;
  11207. }
  11208. }
  11209. module.set.barWidth(percent);
  11210. module.set.labelInterval();
  11211. module.set.labels();
  11212. settings.onChange.call(element, percent, module.value, module.total);
  11213. },
  11214. labelInterval: function() {
  11215. var
  11216. animationCallback = function() {
  11217. module.verbose('Bar finished animating, removing continuous label updates');
  11218. clearInterval(module.interval);
  11219. animating = false;
  11220. module.set.labels();
  11221. }
  11222. ;
  11223. clearInterval(module.interval);
  11224. module.bind.transitionEnd(animationCallback);
  11225. animating = true;
  11226. module.interval = setInterval(function() {
  11227. var
  11228. isInDOM = $.contains(document.documentElement, element)
  11229. ;
  11230. if(!isInDOM) {
  11231. clearInterval(module.interval);
  11232. animating = false;
  11233. }
  11234. module.set.labels();
  11235. }, settings.framerate);
  11236. },
  11237. labels: function() {
  11238. module.verbose('Setting both bar progress and outer label text');
  11239. module.set.barLabel();
  11240. module.set.state();
  11241. },
  11242. label: function(text) {
  11243. text = text || '';
  11244. if(text) {
  11245. text = module.get.text(text);
  11246. module.verbose('Setting label to text', text);
  11247. $label.text(text);
  11248. }
  11249. },
  11250. state: function(percent) {
  11251. percent = (percent !== undefined)
  11252. ? percent
  11253. : module.percent
  11254. ;
  11255. if(percent === 100) {
  11256. if(settings.autoSuccess && !(module.is.warning() || module.is.error() || module.is.success())) {
  11257. module.set.success();
  11258. module.debug('Automatically triggering success at 100%');
  11259. }
  11260. else {
  11261. module.verbose('Reached 100% removing active state');
  11262. module.remove.active();
  11263. module.remove.progressPoll();
  11264. }
  11265. }
  11266. else if(percent > 0) {
  11267. module.verbose('Adjusting active progress bar label', percent);
  11268. module.set.active();
  11269. }
  11270. else {
  11271. module.remove.active();
  11272. module.set.label(settings.text.active);
  11273. }
  11274. },
  11275. barLabel: function(text) {
  11276. if(text !== undefined) {
  11277. $progress.text( module.get.text(text) );
  11278. }
  11279. else if(settings.label == 'ratio' && module.total) {
  11280. module.verbose('Adding ratio to bar label');
  11281. $progress.text( module.get.text(settings.text.ratio) );
  11282. }
  11283. else if(settings.label == 'percent') {
  11284. module.verbose('Adding percentage to bar label');
  11285. $progress.text( module.get.text(settings.text.percent) );
  11286. }
  11287. },
  11288. active: function(text) {
  11289. text = text || settings.text.active;
  11290. module.debug('Setting active state');
  11291. if(settings.showActivity && !module.is.active() ) {
  11292. $module.addClass(className.active);
  11293. }
  11294. module.remove.warning();
  11295. module.remove.error();
  11296. module.remove.success();
  11297. text = settings.onLabelUpdate('active', text, module.value, module.total);
  11298. if(text) {
  11299. module.set.label(text);
  11300. }
  11301. module.bind.transitionEnd(function() {
  11302. settings.onActive.call(element, module.value, module.total);
  11303. });
  11304. },
  11305. success : function(text) {
  11306. text = text || settings.text.success || settings.text.active;
  11307. module.debug('Setting success state');
  11308. $module.addClass(className.success);
  11309. module.remove.active();
  11310. module.remove.warning();
  11311. module.remove.error();
  11312. module.complete();
  11313. if(settings.text.success) {
  11314. text = settings.onLabelUpdate('success', text, module.value, module.total);
  11315. module.set.label(text);
  11316. }
  11317. else {
  11318. text = settings.onLabelUpdate('active', text, module.value, module.total);
  11319. module.set.label(text);
  11320. }
  11321. module.bind.transitionEnd(function() {
  11322. settings.onSuccess.call(element, module.total);
  11323. });
  11324. },
  11325. warning : function(text) {
  11326. text = text || settings.text.warning;
  11327. module.debug('Setting warning state');
  11328. $module.addClass(className.warning);
  11329. module.remove.active();
  11330. module.remove.success();
  11331. module.remove.error();
  11332. module.complete();
  11333. text = settings.onLabelUpdate('warning', text, module.value, module.total);
  11334. if(text) {
  11335. module.set.label(text);
  11336. }
  11337. module.bind.transitionEnd(function() {
  11338. settings.onWarning.call(element, module.value, module.total);
  11339. });
  11340. },
  11341. error : function(text) {
  11342. text = text || settings.text.error;
  11343. module.debug('Setting error state');
  11344. $module.addClass(className.error);
  11345. module.remove.active();
  11346. module.remove.success();
  11347. module.remove.warning();
  11348. module.complete();
  11349. text = settings.onLabelUpdate('error', text, module.value, module.total);
  11350. if(text) {
  11351. module.set.label(text);
  11352. }
  11353. module.bind.transitionEnd(function() {
  11354. settings.onError.call(element, module.value, module.total);
  11355. });
  11356. },
  11357. transitionEvent: function() {
  11358. transitionEnd = module.get.transitionEnd();
  11359. },
  11360. total: function(totalValue) {
  11361. module.total = totalValue;
  11362. },
  11363. value: function(value) {
  11364. module.value = value;
  11365. },
  11366. progress: function(value) {
  11367. if(!module.has.progressPoll()) {
  11368. module.debug('First update in progress update interval, immediately updating', value);
  11369. module.update.progress(value);
  11370. module.create.progressPoll();
  11371. }
  11372. else {
  11373. module.debug('Updated within interval, setting next update to use new value', value);
  11374. module.set.nextValue(value);
  11375. }
  11376. },
  11377. nextValue: function(value) {
  11378. module.nextValue = value;
  11379. }
  11380. },
  11381. update: {
  11382. toNextValue: function() {
  11383. var
  11384. nextValue = module.nextValue
  11385. ;
  11386. if(nextValue) {
  11387. module.debug('Update interval complete using last updated value', nextValue);
  11388. module.update.progress(nextValue);
  11389. module.remove.nextValue();
  11390. }
  11391. },
  11392. progress: function(value) {
  11393. var
  11394. percentComplete
  11395. ;
  11396. value = module.get.numericValue(value);
  11397. if(value === false) {
  11398. module.error(error.nonNumeric, value);
  11399. }
  11400. value = module.get.normalizedValue(value);
  11401. if( module.has.total() ) {
  11402. module.set.value(value);
  11403. percentComplete = (value / module.total) * 100;
  11404. module.debug('Calculating percent complete from total', percentComplete);
  11405. module.set.percent( percentComplete );
  11406. }
  11407. else {
  11408. percentComplete = value;
  11409. module.debug('Setting value to exact percentage value', percentComplete);
  11410. module.set.percent( percentComplete );
  11411. }
  11412. }
  11413. },
  11414. setting: function(name, value) {
  11415. module.debug('Changing setting', name, value);
  11416. if( $.isPlainObject(name) ) {
  11417. $.extend(true, settings, name);
  11418. }
  11419. else if(value !== undefined) {
  11420. if($.isPlainObject(settings[name])) {
  11421. $.extend(true, settings[name], value);
  11422. }
  11423. else {
  11424. settings[name] = value;
  11425. }
  11426. }
  11427. else {
  11428. return settings[name];
  11429. }
  11430. },
  11431. internal: function(name, value) {
  11432. if( $.isPlainObject(name) ) {
  11433. $.extend(true, module, name);
  11434. }
  11435. else if(value !== undefined) {
  11436. module[name] = value;
  11437. }
  11438. else {
  11439. return module[name];
  11440. }
  11441. },
  11442. debug: function() {
  11443. if(!settings.silent && settings.debug) {
  11444. if(settings.performance) {
  11445. module.performance.log(arguments);
  11446. }
  11447. else {
  11448. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  11449. module.debug.apply(console, arguments);
  11450. }
  11451. }
  11452. },
  11453. verbose: function() {
  11454. if(!settings.silent && settings.verbose && settings.debug) {
  11455. if(settings.performance) {
  11456. module.performance.log(arguments);
  11457. }
  11458. else {
  11459. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  11460. module.verbose.apply(console, arguments);
  11461. }
  11462. }
  11463. },
  11464. error: function() {
  11465. if(!settings.silent) {
  11466. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  11467. module.error.apply(console, arguments);
  11468. }
  11469. },
  11470. performance: {
  11471. log: function(message) {
  11472. var
  11473. currentTime,
  11474. executionTime,
  11475. previousTime
  11476. ;
  11477. if(settings.performance) {
  11478. currentTime = new Date().getTime();
  11479. previousTime = time || currentTime;
  11480. executionTime = currentTime - previousTime;
  11481. time = currentTime;
  11482. performance.push({
  11483. 'Name' : message[0],
  11484. 'Arguments' : [].slice.call(message, 1) || '',
  11485. 'Element' : element,
  11486. 'Execution Time' : executionTime
  11487. });
  11488. }
  11489. clearTimeout(module.performance.timer);
  11490. module.performance.timer = setTimeout(module.performance.display, 500);
  11491. },
  11492. display: function() {
  11493. var
  11494. title = settings.name + ':',
  11495. totalTime = 0
  11496. ;
  11497. time = false;
  11498. clearTimeout(module.performance.timer);
  11499. $.each(performance, function(index, data) {
  11500. totalTime += data['Execution Time'];
  11501. });
  11502. title += ' ' + totalTime + 'ms';
  11503. if(moduleSelector) {
  11504. title += ' \'' + moduleSelector + '\'';
  11505. }
  11506. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  11507. console.groupCollapsed(title);
  11508. if(console.table) {
  11509. console.table(performance);
  11510. }
  11511. else {
  11512. $.each(performance, function(index, data) {
  11513. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  11514. });
  11515. }
  11516. console.groupEnd();
  11517. }
  11518. performance = [];
  11519. }
  11520. },
  11521. invoke: function(query, passedArguments, context) {
  11522. var
  11523. object = instance,
  11524. maxDepth,
  11525. found,
  11526. response
  11527. ;
  11528. passedArguments = passedArguments || queryArguments;
  11529. context = element || context;
  11530. if(typeof query == 'string' && object !== undefined) {
  11531. query = query.split(/[\. ]/);
  11532. maxDepth = query.length - 1;
  11533. $.each(query, function(depth, value) {
  11534. var camelCaseValue = (depth != maxDepth)
  11535. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  11536. : query
  11537. ;
  11538. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  11539. object = object[camelCaseValue];
  11540. }
  11541. else if( object[camelCaseValue] !== undefined ) {
  11542. found = object[camelCaseValue];
  11543. return false;
  11544. }
  11545. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  11546. object = object[value];
  11547. }
  11548. else if( object[value] !== undefined ) {
  11549. found = object[value];
  11550. return false;
  11551. }
  11552. else {
  11553. module.error(error.method, query);
  11554. return false;
  11555. }
  11556. });
  11557. }
  11558. if ( $.isFunction( found ) ) {
  11559. response = found.apply(context, passedArguments);
  11560. }
  11561. else if(found !== undefined) {
  11562. response = found;
  11563. }
  11564. if($.isArray(returnedValue)) {
  11565. returnedValue.push(response);
  11566. }
  11567. else if(returnedValue !== undefined) {
  11568. returnedValue = [returnedValue, response];
  11569. }
  11570. else if(response !== undefined) {
  11571. returnedValue = response;
  11572. }
  11573. return found;
  11574. }
  11575. };
  11576. if(methodInvoked) {
  11577. if(instance === undefined) {
  11578. module.initialize();
  11579. }
  11580. module.invoke(query);
  11581. }
  11582. else {
  11583. if(instance !== undefined) {
  11584. instance.invoke('destroy');
  11585. }
  11586. module.initialize();
  11587. }
  11588. })
  11589. ;
  11590. return (returnedValue !== undefined)
  11591. ? returnedValue
  11592. : this
  11593. ;
  11594. };
  11595. $.fn.progress.settings = {
  11596. name : 'Progress',
  11597. namespace : 'progress',
  11598. silent : false,
  11599. debug : false,
  11600. verbose : false,
  11601. performance : true,
  11602. random : {
  11603. min : 2,
  11604. max : 5
  11605. },
  11606. duration : 300,
  11607. updateInterval : 'auto',
  11608. autoSuccess : true,
  11609. showActivity : true,
  11610. limitValues : true,
  11611. label : 'percent',
  11612. precision : 0,
  11613. framerate : (1000 / 30), /// 30 fps
  11614. percent : false,
  11615. total : false,
  11616. value : false,
  11617. // delay in ms for fail safe animation callback
  11618. failSafeDelay : 100,
  11619. onLabelUpdate : function(state, text, value, total){
  11620. return text;
  11621. },
  11622. onChange : function(percent, value, total){},
  11623. onSuccess : function(total){},
  11624. onActive : function(value, total){},
  11625. onError : function(value, total){},
  11626. onWarning : function(value, total){},
  11627. error : {
  11628. method : 'The method you called is not defined.',
  11629. nonNumeric : 'Progress value is non numeric',
  11630. tooHigh : 'Value specified is above 100%',
  11631. tooLow : 'Value specified is below 0%'
  11632. },
  11633. regExp: {
  11634. variable: /\{\$*[A-z0-9]+\}/g
  11635. },
  11636. metadata: {
  11637. percent : 'percent',
  11638. total : 'total',
  11639. value : 'value'
  11640. },
  11641. selector : {
  11642. bar : '> .bar',
  11643. label : '> .label',
  11644. progress : '.bar > .progress'
  11645. },
  11646. text : {
  11647. active : false,
  11648. error : false,
  11649. success : false,
  11650. warning : false,
  11651. percent : '{percent}%',
  11652. ratio : '{value} of {total}'
  11653. },
  11654. className : {
  11655. active : 'active',
  11656. error : 'error',
  11657. success : 'success',
  11658. warning : 'warning'
  11659. }
  11660. };
  11661. })( jQuery, window, document );
  11662. /*!
  11663. * # Semantic UI 2.2.6 - Rating
  11664. * http://github.com/semantic-org/semantic-ui/
  11665. *
  11666. *
  11667. * Released under the MIT license
  11668. * http://opensource.org/licenses/MIT
  11669. *
  11670. */
  11671. ;(function ($, window, document, undefined) {
  11672. "use strict";
  11673. window = (typeof window != 'undefined' && window.Math == Math)
  11674. ? window
  11675. : (typeof self != 'undefined' && self.Math == Math)
  11676. ? self
  11677. : Function('return this')()
  11678. ;
  11679. $.fn.rating = function(parameters) {
  11680. var
  11681. $allModules = $(this),
  11682. moduleSelector = $allModules.selector || '',
  11683. time = new Date().getTime(),
  11684. performance = [],
  11685. query = arguments[0],
  11686. methodInvoked = (typeof query == 'string'),
  11687. queryArguments = [].slice.call(arguments, 1),
  11688. returnedValue
  11689. ;
  11690. $allModules
  11691. .each(function() {
  11692. var
  11693. settings = ( $.isPlainObject(parameters) )
  11694. ? $.extend(true, {}, $.fn.rating.settings, parameters)
  11695. : $.extend({}, $.fn.rating.settings),
  11696. namespace = settings.namespace,
  11697. className = settings.className,
  11698. metadata = settings.metadata,
  11699. selector = settings.selector,
  11700. error = settings.error,
  11701. eventNamespace = '.' + namespace,
  11702. moduleNamespace = 'module-' + namespace,
  11703. element = this,
  11704. instance = $(this).data(moduleNamespace),
  11705. $module = $(this),
  11706. $icon = $module.find(selector.icon),
  11707. initialLoad,
  11708. module
  11709. ;
  11710. module = {
  11711. initialize: function() {
  11712. module.verbose('Initializing rating module', settings);
  11713. if($icon.length === 0) {
  11714. module.setup.layout();
  11715. }
  11716. if(settings.interactive) {
  11717. module.enable();
  11718. }
  11719. else {
  11720. module.disable();
  11721. }
  11722. module.set.initialLoad();
  11723. module.set.rating( module.get.initialRating() );
  11724. module.remove.initialLoad();
  11725. module.instantiate();
  11726. },
  11727. instantiate: function() {
  11728. module.verbose('Instantiating module', settings);
  11729. instance = module;
  11730. $module
  11731. .data(moduleNamespace, module)
  11732. ;
  11733. },
  11734. destroy: function() {
  11735. module.verbose('Destroying previous instance', instance);
  11736. module.remove.events();
  11737. $module
  11738. .removeData(moduleNamespace)
  11739. ;
  11740. },
  11741. refresh: function() {
  11742. $icon = $module.find(selector.icon);
  11743. },
  11744. setup: {
  11745. layout: function() {
  11746. var
  11747. maxRating = module.get.maxRating(),
  11748. html = $.fn.rating.settings.templates.icon(maxRating)
  11749. ;
  11750. module.debug('Generating icon html dynamically');
  11751. $module
  11752. .html(html)
  11753. ;
  11754. module.refresh();
  11755. }
  11756. },
  11757. event: {
  11758. mouseenter: function() {
  11759. var
  11760. $activeIcon = $(this)
  11761. ;
  11762. $activeIcon
  11763. .nextAll()
  11764. .removeClass(className.selected)
  11765. ;
  11766. $module
  11767. .addClass(className.selected)
  11768. ;
  11769. $activeIcon
  11770. .addClass(className.selected)
  11771. .prevAll()
  11772. .addClass(className.selected)
  11773. ;
  11774. },
  11775. mouseleave: function() {
  11776. $module
  11777. .removeClass(className.selected)
  11778. ;
  11779. $icon
  11780. .removeClass(className.selected)
  11781. ;
  11782. },
  11783. click: function() {
  11784. var
  11785. $activeIcon = $(this),
  11786. currentRating = module.get.rating(),
  11787. rating = $icon.index($activeIcon) + 1,
  11788. canClear = (settings.clearable == 'auto')
  11789. ? ($icon.length === 1)
  11790. : settings.clearable
  11791. ;
  11792. if(canClear && currentRating == rating) {
  11793. module.clearRating();
  11794. }
  11795. else {
  11796. module.set.rating( rating );
  11797. }
  11798. }
  11799. },
  11800. clearRating: function() {
  11801. module.debug('Clearing current rating');
  11802. module.set.rating(0);
  11803. },
  11804. bind: {
  11805. events: function() {
  11806. module.verbose('Binding events');
  11807. $module
  11808. .on('mouseenter' + eventNamespace, selector.icon, module.event.mouseenter)
  11809. .on('mouseleave' + eventNamespace, selector.icon, module.event.mouseleave)
  11810. .on('click' + eventNamespace, selector.icon, module.event.click)
  11811. ;
  11812. }
  11813. },
  11814. remove: {
  11815. events: function() {
  11816. module.verbose('Removing events');
  11817. $module
  11818. .off(eventNamespace)
  11819. ;
  11820. },
  11821. initialLoad: function() {
  11822. initialLoad = false;
  11823. }
  11824. },
  11825. enable: function() {
  11826. module.debug('Setting rating to interactive mode');
  11827. module.bind.events();
  11828. $module
  11829. .removeClass(className.disabled)
  11830. ;
  11831. },
  11832. disable: function() {
  11833. module.debug('Setting rating to read-only mode');
  11834. module.remove.events();
  11835. $module
  11836. .addClass(className.disabled)
  11837. ;
  11838. },
  11839. is: {
  11840. initialLoad: function() {
  11841. return initialLoad;
  11842. }
  11843. },
  11844. get: {
  11845. initialRating: function() {
  11846. if($module.data(metadata.rating) !== undefined) {
  11847. $module.removeData(metadata.rating);
  11848. return $module.data(metadata.rating);
  11849. }
  11850. return settings.initialRating;
  11851. },
  11852. maxRating: function() {
  11853. if($module.data(metadata.maxRating) !== undefined) {
  11854. $module.removeData(metadata.maxRating);
  11855. return $module.data(metadata.maxRating);
  11856. }
  11857. return settings.maxRating;
  11858. },
  11859. rating: function() {
  11860. var
  11861. currentRating = $icon.filter('.' + className.active).length
  11862. ;
  11863. module.verbose('Current rating retrieved', currentRating);
  11864. return currentRating;
  11865. }
  11866. },
  11867. set: {
  11868. rating: function(rating) {
  11869. var
  11870. ratingIndex = (rating - 1 >= 0)
  11871. ? (rating - 1)
  11872. : 0,
  11873. $activeIcon = $icon.eq(ratingIndex)
  11874. ;
  11875. $module
  11876. .removeClass(className.selected)
  11877. ;
  11878. $icon
  11879. .removeClass(className.selected)
  11880. .removeClass(className.active)
  11881. ;
  11882. if(rating > 0) {
  11883. module.verbose('Setting current rating to', rating);
  11884. $activeIcon
  11885. .prevAll()
  11886. .addBack()
  11887. .addClass(className.active)
  11888. ;
  11889. }
  11890. if(!module.is.initialLoad()) {
  11891. settings.onRate.call(element, rating);
  11892. }
  11893. },
  11894. initialLoad: function() {
  11895. initialLoad = true;
  11896. }
  11897. },
  11898. setting: function(name, value) {
  11899. module.debug('Changing setting', name, value);
  11900. if( $.isPlainObject(name) ) {
  11901. $.extend(true, settings, name);
  11902. }
  11903. else if(value !== undefined) {
  11904. if($.isPlainObject(settings[name])) {
  11905. $.extend(true, settings[name], value);
  11906. }
  11907. else {
  11908. settings[name] = value;
  11909. }
  11910. }
  11911. else {
  11912. return settings[name];
  11913. }
  11914. },
  11915. internal: function(name, value) {
  11916. if( $.isPlainObject(name) ) {
  11917. $.extend(true, module, name);
  11918. }
  11919. else if(value !== undefined) {
  11920. module[name] = value;
  11921. }
  11922. else {
  11923. return module[name];
  11924. }
  11925. },
  11926. debug: function() {
  11927. if(!settings.silent && settings.debug) {
  11928. if(settings.performance) {
  11929. module.performance.log(arguments);
  11930. }
  11931. else {
  11932. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  11933. module.debug.apply(console, arguments);
  11934. }
  11935. }
  11936. },
  11937. verbose: function() {
  11938. if(!settings.silent && settings.verbose && settings.debug) {
  11939. if(settings.performance) {
  11940. module.performance.log(arguments);
  11941. }
  11942. else {
  11943. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  11944. module.verbose.apply(console, arguments);
  11945. }
  11946. }
  11947. },
  11948. error: function() {
  11949. if(!settings.silent) {
  11950. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  11951. module.error.apply(console, arguments);
  11952. }
  11953. },
  11954. performance: {
  11955. log: function(message) {
  11956. var
  11957. currentTime,
  11958. executionTime,
  11959. previousTime
  11960. ;
  11961. if(settings.performance) {
  11962. currentTime = new Date().getTime();
  11963. previousTime = time || currentTime;
  11964. executionTime = currentTime - previousTime;
  11965. time = currentTime;
  11966. performance.push({
  11967. 'Name' : message[0],
  11968. 'Arguments' : [].slice.call(message, 1) || '',
  11969. 'Element' : element,
  11970. 'Execution Time' : executionTime
  11971. });
  11972. }
  11973. clearTimeout(module.performance.timer);
  11974. module.performance.timer = setTimeout(module.performance.display, 500);
  11975. },
  11976. display: function() {
  11977. var
  11978. title = settings.name + ':',
  11979. totalTime = 0
  11980. ;
  11981. time = false;
  11982. clearTimeout(module.performance.timer);
  11983. $.each(performance, function(index, data) {
  11984. totalTime += data['Execution Time'];
  11985. });
  11986. title += ' ' + totalTime + 'ms';
  11987. if(moduleSelector) {
  11988. title += ' \'' + moduleSelector + '\'';
  11989. }
  11990. if($allModules.length > 1) {
  11991. title += ' ' + '(' + $allModules.length + ')';
  11992. }
  11993. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  11994. console.groupCollapsed(title);
  11995. if(console.table) {
  11996. console.table(performance);
  11997. }
  11998. else {
  11999. $.each(performance, function(index, data) {
  12000. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  12001. });
  12002. }
  12003. console.groupEnd();
  12004. }
  12005. performance = [];
  12006. }
  12007. },
  12008. invoke: function(query, passedArguments, context) {
  12009. var
  12010. object = instance,
  12011. maxDepth,
  12012. found,
  12013. response
  12014. ;
  12015. passedArguments = passedArguments || queryArguments;
  12016. context = element || context;
  12017. if(typeof query == 'string' && object !== undefined) {
  12018. query = query.split(/[\. ]/);
  12019. maxDepth = query.length - 1;
  12020. $.each(query, function(depth, value) {
  12021. var camelCaseValue = (depth != maxDepth)
  12022. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  12023. : query
  12024. ;
  12025. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  12026. object = object[camelCaseValue];
  12027. }
  12028. else if( object[camelCaseValue] !== undefined ) {
  12029. found = object[camelCaseValue];
  12030. return false;
  12031. }
  12032. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  12033. object = object[value];
  12034. }
  12035. else if( object[value] !== undefined ) {
  12036. found = object[value];
  12037. return false;
  12038. }
  12039. else {
  12040. return false;
  12041. }
  12042. });
  12043. }
  12044. if ( $.isFunction( found ) ) {
  12045. response = found.apply(context, passedArguments);
  12046. }
  12047. else if(found !== undefined) {
  12048. response = found;
  12049. }
  12050. if($.isArray(returnedValue)) {
  12051. returnedValue.push(response);
  12052. }
  12053. else if(returnedValue !== undefined) {
  12054. returnedValue = [returnedValue, response];
  12055. }
  12056. else if(response !== undefined) {
  12057. returnedValue = response;
  12058. }
  12059. return found;
  12060. }
  12061. };
  12062. if(methodInvoked) {
  12063. if(instance === undefined) {
  12064. module.initialize();
  12065. }
  12066. module.invoke(query);
  12067. }
  12068. else {
  12069. if(instance !== undefined) {
  12070. instance.invoke('destroy');
  12071. }
  12072. module.initialize();
  12073. }
  12074. })
  12075. ;
  12076. return (returnedValue !== undefined)
  12077. ? returnedValue
  12078. : this
  12079. ;
  12080. };
  12081. $.fn.rating.settings = {
  12082. name : 'Rating',
  12083. namespace : 'rating',
  12084. slent : false,
  12085. debug : false,
  12086. verbose : false,
  12087. performance : true,
  12088. initialRating : 0,
  12089. interactive : true,
  12090. maxRating : 4,
  12091. clearable : 'auto',
  12092. fireOnInit : false,
  12093. onRate : function(rating){},
  12094. error : {
  12095. method : 'The method you called is not defined',
  12096. noMaximum : 'No maximum rating specified. Cannot generate HTML automatically'
  12097. },
  12098. metadata: {
  12099. rating : 'rating',
  12100. maxRating : 'maxRating'
  12101. },
  12102. className : {
  12103. active : 'active',
  12104. disabled : 'disabled',
  12105. selected : 'selected',
  12106. loading : 'loading'
  12107. },
  12108. selector : {
  12109. icon : '.icon'
  12110. },
  12111. templates: {
  12112. icon: function(maxRating) {
  12113. var
  12114. icon = 1,
  12115. html = ''
  12116. ;
  12117. while(icon <= maxRating) {
  12118. html += '<i class="icon"></i>';
  12119. icon++;
  12120. }
  12121. return html;
  12122. }
  12123. }
  12124. };
  12125. })( jQuery, window, document );
  12126. /*!
  12127. * # Semantic UI 2.2.6 - Search
  12128. * http://github.com/semantic-org/semantic-ui/
  12129. *
  12130. *
  12131. * Released under the MIT license
  12132. * http://opensource.org/licenses/MIT
  12133. *
  12134. */
  12135. ;(function ($, window, document, undefined) {
  12136. "use strict";
  12137. window = (typeof window != 'undefined' && window.Math == Math)
  12138. ? window
  12139. : (typeof self != 'undefined' && self.Math == Math)
  12140. ? self
  12141. : Function('return this')()
  12142. ;
  12143. $.fn.search = function(parameters) {
  12144. var
  12145. $allModules = $(this),
  12146. moduleSelector = $allModules.selector || '',
  12147. time = new Date().getTime(),
  12148. performance = [],
  12149. query = arguments[0],
  12150. methodInvoked = (typeof query == 'string'),
  12151. queryArguments = [].slice.call(arguments, 1),
  12152. returnedValue
  12153. ;
  12154. $(this)
  12155. .each(function() {
  12156. var
  12157. settings = ( $.isPlainObject(parameters) )
  12158. ? $.extend(true, {}, $.fn.search.settings, parameters)
  12159. : $.extend({}, $.fn.search.settings),
  12160. className = settings.className,
  12161. metadata = settings.metadata,
  12162. regExp = settings.regExp,
  12163. fields = settings.fields,
  12164. selector = settings.selector,
  12165. error = settings.error,
  12166. namespace = settings.namespace,
  12167. eventNamespace = '.' + namespace,
  12168. moduleNamespace = namespace + '-module',
  12169. $module = $(this),
  12170. $prompt = $module.find(selector.prompt),
  12171. $searchButton = $module.find(selector.searchButton),
  12172. $results = $module.find(selector.results),
  12173. $result = $module.find(selector.result),
  12174. $category = $module.find(selector.category),
  12175. element = this,
  12176. instance = $module.data(moduleNamespace),
  12177. disabledBubbled = false,
  12178. module
  12179. ;
  12180. module = {
  12181. initialize: function() {
  12182. module.verbose('Initializing module');
  12183. module.determine.searchFields();
  12184. module.bind.events();
  12185. module.set.type();
  12186. module.create.results();
  12187. module.instantiate();
  12188. },
  12189. instantiate: function() {
  12190. module.verbose('Storing instance of module', module);
  12191. instance = module;
  12192. $module
  12193. .data(moduleNamespace, module)
  12194. ;
  12195. },
  12196. destroy: function() {
  12197. module.verbose('Destroying instance');
  12198. $module
  12199. .off(eventNamespace)
  12200. .removeData(moduleNamespace)
  12201. ;
  12202. },
  12203. refresh: function() {
  12204. module.debug('Refreshing selector cache');
  12205. $prompt = $module.find(selector.prompt);
  12206. $searchButton = $module.find(selector.searchButton);
  12207. $category = $module.find(selector.category);
  12208. $results = $module.find(selector.results);
  12209. $result = $module.find(selector.result);
  12210. },
  12211. refreshResults: function() {
  12212. $results = $module.find(selector.results);
  12213. $result = $module.find(selector.result);
  12214. },
  12215. bind: {
  12216. events: function() {
  12217. module.verbose('Binding events to search');
  12218. if(settings.automatic) {
  12219. $module
  12220. .on(module.get.inputEvent() + eventNamespace, selector.prompt, module.event.input)
  12221. ;
  12222. $prompt
  12223. .attr('autocomplete', 'off')
  12224. ;
  12225. }
  12226. $module
  12227. // prompt
  12228. .on('focus' + eventNamespace, selector.prompt, module.event.focus)
  12229. .on('blur' + eventNamespace, selector.prompt, module.event.blur)
  12230. .on('keydown' + eventNamespace, selector.prompt, module.handleKeyboard)
  12231. // search button
  12232. .on('click' + eventNamespace, selector.searchButton, module.query)
  12233. // results
  12234. .on('mousedown' + eventNamespace, selector.results, module.event.result.mousedown)
  12235. .on('mouseup' + eventNamespace, selector.results, module.event.result.mouseup)
  12236. .on('click' + eventNamespace, selector.result, module.event.result.click)
  12237. ;
  12238. }
  12239. },
  12240. determine: {
  12241. searchFields: function() {
  12242. // this makes sure $.extend does not add specified search fields to default fields
  12243. // this is the only setting which should not extend defaults
  12244. if(parameters && parameters.searchFields !== undefined) {
  12245. settings.searchFields = parameters.searchFields;
  12246. }
  12247. }
  12248. },
  12249. event: {
  12250. input: function() {
  12251. clearTimeout(module.timer);
  12252. module.timer = setTimeout(module.query, settings.searchDelay);
  12253. },
  12254. focus: function() {
  12255. module.set.focus();
  12256. if( module.has.minimumCharacters() ) {
  12257. module.query();
  12258. if( module.can.show() ) {
  12259. module.showResults();
  12260. }
  12261. }
  12262. },
  12263. blur: function(event) {
  12264. var
  12265. pageLostFocus = (document.activeElement === this),
  12266. callback = function() {
  12267. module.cancel.query();
  12268. module.remove.focus();
  12269. module.timer = setTimeout(module.hideResults, settings.hideDelay);
  12270. }
  12271. ;
  12272. if(pageLostFocus) {
  12273. return;
  12274. }
  12275. if(module.resultsClicked) {
  12276. module.debug('Determining if user action caused search to close');
  12277. $module
  12278. .one('click.close' + eventNamespace, selector.results, function(event) {
  12279. if(module.is.inMessage(event) || disabledBubbled) {
  12280. $prompt.focus();
  12281. return;
  12282. }
  12283. disabledBubbled = false;
  12284. if( !module.is.animating() && !module.is.hidden()) {
  12285. callback();
  12286. }
  12287. })
  12288. ;
  12289. }
  12290. else {
  12291. module.debug('Input blurred without user action, closing results');
  12292. callback();
  12293. }
  12294. },
  12295. result: {
  12296. mousedown: function() {
  12297. module.resultsClicked = true;
  12298. },
  12299. mouseup: function() {
  12300. module.resultsClicked = false;
  12301. },
  12302. click: function(event) {
  12303. module.debug('Search result selected');
  12304. var
  12305. $result = $(this),
  12306. $title = $result.find(selector.title).eq(0),
  12307. $link = $result.is('a[href]')
  12308. ? $result
  12309. : $result.find('a[href]').eq(0),
  12310. href = $link.attr('href') || false,
  12311. target = $link.attr('target') || false,
  12312. title = $title.html(),
  12313. // title is used for result lookup
  12314. value = ($title.length > 0)
  12315. ? $title.text()
  12316. : false,
  12317. results = module.get.results(),
  12318. result = $result.data(metadata.result) || module.get.result(value, results),
  12319. returnedValue
  12320. ;
  12321. if( $.isFunction(settings.onSelect) ) {
  12322. if(settings.onSelect.call(element, result, results) === false) {
  12323. module.debug('Custom onSelect callback cancelled default select action');
  12324. disabledBubbled = true;
  12325. return;
  12326. }
  12327. }
  12328. module.hideResults();
  12329. if(value) {
  12330. module.set.value(value);
  12331. }
  12332. if(href) {
  12333. module.verbose('Opening search link found in result', $link);
  12334. if(target == '_blank' || event.ctrlKey) {
  12335. window.open(href);
  12336. }
  12337. else {
  12338. window.location.href = (href);
  12339. }
  12340. }
  12341. }
  12342. }
  12343. },
  12344. handleKeyboard: function(event) {
  12345. var
  12346. // force selector refresh
  12347. $result = $module.find(selector.result),
  12348. $category = $module.find(selector.category),
  12349. $activeResult = $result.filter('.' + className.active),
  12350. currentIndex = $result.index( $activeResult ),
  12351. resultSize = $result.length,
  12352. hasActiveResult = $activeResult.length > 0,
  12353. keyCode = event.which,
  12354. keys = {
  12355. backspace : 8,
  12356. enter : 13,
  12357. escape : 27,
  12358. upArrow : 38,
  12359. downArrow : 40
  12360. },
  12361. newIndex
  12362. ;
  12363. // search shortcuts
  12364. if(keyCode == keys.escape) {
  12365. module.verbose('Escape key pressed, blurring search field');
  12366. module.trigger.blur();
  12367. }
  12368. if( module.is.visible() ) {
  12369. if(keyCode == keys.enter) {
  12370. module.verbose('Enter key pressed, selecting active result');
  12371. if( $result.filter('.' + className.active).length > 0 ) {
  12372. module.event.result.click.call($result.filter('.' + className.active), event);
  12373. event.preventDefault();
  12374. return false;
  12375. }
  12376. }
  12377. else if(keyCode == keys.upArrow && hasActiveResult) {
  12378. module.verbose('Up key pressed, changing active result');
  12379. newIndex = (currentIndex - 1 < 0)
  12380. ? currentIndex
  12381. : currentIndex - 1
  12382. ;
  12383. $category
  12384. .removeClass(className.active)
  12385. ;
  12386. $result
  12387. .removeClass(className.active)
  12388. .eq(newIndex)
  12389. .addClass(className.active)
  12390. .closest($category)
  12391. .addClass(className.active)
  12392. ;
  12393. event.preventDefault();
  12394. }
  12395. else if(keyCode == keys.downArrow) {
  12396. module.verbose('Down key pressed, changing active result');
  12397. newIndex = (currentIndex + 1 >= resultSize)
  12398. ? currentIndex
  12399. : currentIndex + 1
  12400. ;
  12401. $category
  12402. .removeClass(className.active)
  12403. ;
  12404. $result
  12405. .removeClass(className.active)
  12406. .eq(newIndex)
  12407. .addClass(className.active)
  12408. .closest($category)
  12409. .addClass(className.active)
  12410. ;
  12411. event.preventDefault();
  12412. }
  12413. }
  12414. else {
  12415. // query shortcuts
  12416. if(keyCode == keys.enter) {
  12417. module.verbose('Enter key pressed, executing query');
  12418. module.query();
  12419. module.set.buttonPressed();
  12420. $prompt.one('keyup', module.remove.buttonFocus);
  12421. }
  12422. }
  12423. },
  12424. setup: {
  12425. api: function(searchTerm) {
  12426. var
  12427. apiSettings = {
  12428. debug : settings.debug,
  12429. on : false,
  12430. cache : true,
  12431. action : 'search',
  12432. urlData : {
  12433. query : searchTerm
  12434. },
  12435. onSuccess : function(response) {
  12436. module.parse.response.call(element, response, searchTerm);
  12437. },
  12438. onAbort : function(response) {
  12439. },
  12440. onFailure : function() {
  12441. module.displayMessage(error.serverError);
  12442. },
  12443. onError : module.error
  12444. },
  12445. searchHTML
  12446. ;
  12447. $.extend(true, apiSettings, settings.apiSettings);
  12448. module.verbose('Setting up API request', apiSettings);
  12449. $module.api(apiSettings);
  12450. }
  12451. },
  12452. can: {
  12453. useAPI: function() {
  12454. return $.fn.api !== undefined;
  12455. },
  12456. show: function() {
  12457. return module.is.focused() && !module.is.visible() && !module.is.empty();
  12458. },
  12459. transition: function() {
  12460. return settings.transition && $.fn.transition !== undefined && $module.transition('is supported');
  12461. }
  12462. },
  12463. is: {
  12464. animating: function() {
  12465. return $results.hasClass(className.animating);
  12466. },
  12467. hidden: function() {
  12468. return $results.hasClass(className.hidden);
  12469. },
  12470. inMessage: function(event) {
  12471. if(!event.target) {
  12472. return;
  12473. }
  12474. var
  12475. $target = $(event.target),
  12476. isInDOM = $.contains(document.documentElement, event.target)
  12477. ;
  12478. return (isInDOM && $target.closest(selector.message).length > 0);
  12479. },
  12480. empty: function() {
  12481. return ($results.html() === '');
  12482. },
  12483. visible: function() {
  12484. return ($results.filter(':visible').length > 0);
  12485. },
  12486. focused: function() {
  12487. return ($prompt.filter(':focus').length > 0);
  12488. }
  12489. },
  12490. trigger: {
  12491. blur: function() {
  12492. var
  12493. events = document.createEvent('HTMLEvents'),
  12494. promptElement = $prompt[0]
  12495. ;
  12496. if(promptElement) {
  12497. module.verbose('Triggering native blur event');
  12498. events.initEvent('blur', false, false);
  12499. promptElement.dispatchEvent(events);
  12500. }
  12501. }
  12502. },
  12503. get: {
  12504. inputEvent: function() {
  12505. var
  12506. prompt = $prompt[0],
  12507. inputEvent = (prompt !== undefined && prompt.oninput !== undefined)
  12508. ? 'input'
  12509. : (prompt !== undefined && prompt.onpropertychange !== undefined)
  12510. ? 'propertychange'
  12511. : 'keyup'
  12512. ;
  12513. return inputEvent;
  12514. },
  12515. value: function() {
  12516. return $prompt.val();
  12517. },
  12518. results: function() {
  12519. var
  12520. results = $module.data(metadata.results)
  12521. ;
  12522. return results;
  12523. },
  12524. result: function(value, results) {
  12525. var
  12526. lookupFields = ['title', 'id'],
  12527. result = false
  12528. ;
  12529. value = (value !== undefined)
  12530. ? value
  12531. : module.get.value()
  12532. ;
  12533. results = (results !== undefined)
  12534. ? results
  12535. : module.get.results()
  12536. ;
  12537. if(settings.type === 'category') {
  12538. module.debug('Finding result that matches', value);
  12539. $.each(results, function(index, category) {
  12540. if($.isArray(category.results)) {
  12541. result = module.search.object(value, category.results, lookupFields)[0];
  12542. // don't continue searching if a result is found
  12543. if(result) {
  12544. return false;
  12545. }
  12546. }
  12547. });
  12548. }
  12549. else {
  12550. module.debug('Finding result in results object', value);
  12551. result = module.search.object(value, results, lookupFields)[0];
  12552. }
  12553. return result || false;
  12554. },
  12555. },
  12556. select: {
  12557. firstResult: function() {
  12558. module.verbose('Selecting first result');
  12559. $result.first().addClass(className.active);
  12560. }
  12561. },
  12562. set: {
  12563. focus: function() {
  12564. $module.addClass(className.focus);
  12565. },
  12566. loading: function() {
  12567. $module.addClass(className.loading);
  12568. },
  12569. value: function(value) {
  12570. module.verbose('Setting search input value', value);
  12571. $prompt
  12572. .val(value)
  12573. ;
  12574. },
  12575. type: function(type) {
  12576. type = type || settings.type;
  12577. if(settings.type == 'category') {
  12578. $module.addClass(settings.type);
  12579. }
  12580. },
  12581. buttonPressed: function() {
  12582. $searchButton.addClass(className.pressed);
  12583. }
  12584. },
  12585. remove: {
  12586. loading: function() {
  12587. $module.removeClass(className.loading);
  12588. },
  12589. focus: function() {
  12590. $module.removeClass(className.focus);
  12591. },
  12592. buttonPressed: function() {
  12593. $searchButton.removeClass(className.pressed);
  12594. }
  12595. },
  12596. query: function() {
  12597. var
  12598. searchTerm = module.get.value(),
  12599. cache = module.read.cache(searchTerm)
  12600. ;
  12601. if( module.has.minimumCharacters() ) {
  12602. if(cache) {
  12603. module.debug('Reading result from cache', searchTerm);
  12604. module.save.results(cache.results);
  12605. module.addResults(cache.html);
  12606. module.inject.id(cache.results);
  12607. }
  12608. else {
  12609. module.debug('Querying for', searchTerm);
  12610. if($.isPlainObject(settings.source) || $.isArray(settings.source)) {
  12611. module.search.local(searchTerm);
  12612. }
  12613. else if( module.can.useAPI() ) {
  12614. module.search.remote(searchTerm);
  12615. }
  12616. else {
  12617. module.error(error.source);
  12618. }
  12619. }
  12620. settings.onSearchQuery.call(element, searchTerm);
  12621. }
  12622. else {
  12623. module.hideResults();
  12624. }
  12625. },
  12626. search: {
  12627. local: function(searchTerm) {
  12628. var
  12629. results = module.search.object(searchTerm, settings.content),
  12630. searchHTML
  12631. ;
  12632. module.set.loading();
  12633. module.save.results(results);
  12634. module.debug('Returned local search results', results);
  12635. searchHTML = module.generateResults({
  12636. results: results
  12637. });
  12638. module.remove.loading();
  12639. module.addResults(searchHTML);
  12640. module.inject.id(results);
  12641. module.write.cache(searchTerm, {
  12642. html : searchHTML,
  12643. results : results
  12644. });
  12645. },
  12646. remote: function(searchTerm) {
  12647. if($module.api('is loading')) {
  12648. $module.api('abort');
  12649. }
  12650. module.setup.api(searchTerm);
  12651. $module
  12652. .api('query')
  12653. ;
  12654. },
  12655. object: function(searchTerm, source, searchFields) {
  12656. var
  12657. results = [],
  12658. fuzzyResults = [],
  12659. searchExp = searchTerm.toString().replace(regExp.escape, '\\$&'),
  12660. matchRegExp = new RegExp(regExp.beginsWith + searchExp, 'i'),
  12661. // avoid duplicates when pushing results
  12662. addResult = function(array, result) {
  12663. var
  12664. notResult = ($.inArray(result, results) == -1),
  12665. notFuzzyResult = ($.inArray(result, fuzzyResults) == -1)
  12666. ;
  12667. if(notResult && notFuzzyResult) {
  12668. array.push(result);
  12669. }
  12670. }
  12671. ;
  12672. source = source || settings.source;
  12673. searchFields = (searchFields !== undefined)
  12674. ? searchFields
  12675. : settings.searchFields
  12676. ;
  12677. // search fields should be array to loop correctly
  12678. if(!$.isArray(searchFields)) {
  12679. searchFields = [searchFields];
  12680. }
  12681. // exit conditions if no source
  12682. if(source === undefined || source === false) {
  12683. module.error(error.source);
  12684. return [];
  12685. }
  12686. // iterate through search fields looking for matches
  12687. $.each(searchFields, function(index, field) {
  12688. $.each(source, function(label, content) {
  12689. var
  12690. fieldExists = (typeof content[field] == 'string')
  12691. ;
  12692. if(fieldExists) {
  12693. if( content[field].search(matchRegExp) !== -1) {
  12694. // content starts with value (first in results)
  12695. addResult(results, content);
  12696. }
  12697. else if(settings.searchFullText && module.fuzzySearch(searchTerm, content[field]) ) {
  12698. // content fuzzy matches (last in results)
  12699. addResult(fuzzyResults, content);
  12700. }
  12701. }
  12702. });
  12703. });
  12704. return $.merge(results, fuzzyResults);
  12705. }
  12706. },
  12707. fuzzySearch: function(query, term) {
  12708. var
  12709. termLength = term.length,
  12710. queryLength = query.length
  12711. ;
  12712. if(typeof query !== 'string') {
  12713. return false;
  12714. }
  12715. query = query.toLowerCase();
  12716. term = term.toLowerCase();
  12717. if(queryLength > termLength) {
  12718. return false;
  12719. }
  12720. if(queryLength === termLength) {
  12721. return (query === term);
  12722. }
  12723. search: for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
  12724. var
  12725. queryCharacter = query.charCodeAt(characterIndex)
  12726. ;
  12727. while(nextCharacterIndex < termLength) {
  12728. if(term.charCodeAt(nextCharacterIndex++) === queryCharacter) {
  12729. continue search;
  12730. }
  12731. }
  12732. return false;
  12733. }
  12734. return true;
  12735. },
  12736. parse: {
  12737. response: function(response, searchTerm) {
  12738. var
  12739. searchHTML = module.generateResults(response)
  12740. ;
  12741. module.verbose('Parsing server response', response);
  12742. if(response !== undefined) {
  12743. if(searchTerm !== undefined && response[fields.results] !== undefined) {
  12744. module.addResults(searchHTML);
  12745. module.inject.id(response[fields.results]);
  12746. module.write.cache(searchTerm, {
  12747. html : searchHTML,
  12748. results : response[fields.results]
  12749. });
  12750. module.save.results(response[fields.results]);
  12751. }
  12752. }
  12753. }
  12754. },
  12755. cancel: {
  12756. query: function() {
  12757. if( module.can.useAPI() ) {
  12758. $module.api('abort');
  12759. }
  12760. }
  12761. },
  12762. has: {
  12763. minimumCharacters: function() {
  12764. var
  12765. searchTerm = module.get.value(),
  12766. numCharacters = searchTerm.length
  12767. ;
  12768. return (numCharacters >= settings.minCharacters);
  12769. }
  12770. },
  12771. clear: {
  12772. cache: function(value) {
  12773. var
  12774. cache = $module.data(metadata.cache)
  12775. ;
  12776. if(!value) {
  12777. module.debug('Clearing cache', value);
  12778. $module.removeData(metadata.cache);
  12779. }
  12780. else if(value && cache && cache[value]) {
  12781. module.debug('Removing value from cache', value);
  12782. delete cache[value];
  12783. $module.data(metadata.cache, cache);
  12784. }
  12785. }
  12786. },
  12787. read: {
  12788. cache: function(name) {
  12789. var
  12790. cache = $module.data(metadata.cache)
  12791. ;
  12792. if(settings.cache) {
  12793. module.verbose('Checking cache for generated html for query', name);
  12794. return (typeof cache == 'object') && (cache[name] !== undefined)
  12795. ? cache[name]
  12796. : false
  12797. ;
  12798. }
  12799. return false;
  12800. }
  12801. },
  12802. create: {
  12803. id: function(resultIndex, categoryIndex) {
  12804. var
  12805. resultID = (resultIndex + 1), // not zero indexed
  12806. categoryID = (categoryIndex + 1),
  12807. firstCharCode,
  12808. letterID,
  12809. id
  12810. ;
  12811. if(categoryIndex !== undefined) {
  12812. // start char code for "A"
  12813. letterID = String.fromCharCode(97 + categoryIndex);
  12814. id = letterID + resultID;
  12815. module.verbose('Creating category result id', id);
  12816. }
  12817. else {
  12818. id = resultID;
  12819. module.verbose('Creating result id', id);
  12820. }
  12821. return id;
  12822. },
  12823. results: function() {
  12824. if($results.length === 0) {
  12825. $results = $('<div />')
  12826. .addClass(className.results)
  12827. .appendTo($module)
  12828. ;
  12829. }
  12830. }
  12831. },
  12832. inject: {
  12833. result: function(result, resultIndex, categoryIndex) {
  12834. module.verbose('Injecting result into results');
  12835. var
  12836. $selectedResult = (categoryIndex !== undefined)
  12837. ? $results
  12838. .children().eq(categoryIndex)
  12839. .children(selector.result).eq(resultIndex)
  12840. : $results
  12841. .children(selector.result).eq(resultIndex)
  12842. ;
  12843. module.verbose('Injecting results metadata', $selectedResult);
  12844. $selectedResult
  12845. .data(metadata.result, result)
  12846. ;
  12847. },
  12848. id: function(results) {
  12849. module.debug('Injecting unique ids into results');
  12850. var
  12851. // since results may be object, we must use counters
  12852. categoryIndex = 0,
  12853. resultIndex = 0
  12854. ;
  12855. if(settings.type === 'category') {
  12856. // iterate through each category result
  12857. $.each(results, function(index, category) {
  12858. resultIndex = 0;
  12859. $.each(category.results, function(index, value) {
  12860. var
  12861. result = category.results[index]
  12862. ;
  12863. if(result.id === undefined) {
  12864. result.id = module.create.id(resultIndex, categoryIndex);
  12865. }
  12866. module.inject.result(result, resultIndex, categoryIndex);
  12867. resultIndex++;
  12868. });
  12869. categoryIndex++;
  12870. });
  12871. }
  12872. else {
  12873. // top level
  12874. $.each(results, function(index, value) {
  12875. var
  12876. result = results[index]
  12877. ;
  12878. if(result.id === undefined) {
  12879. result.id = module.create.id(resultIndex);
  12880. }
  12881. module.inject.result(result, resultIndex);
  12882. resultIndex++;
  12883. });
  12884. }
  12885. return results;
  12886. }
  12887. },
  12888. save: {
  12889. results: function(results) {
  12890. module.verbose('Saving current search results to metadata', results);
  12891. $module.data(metadata.results, results);
  12892. }
  12893. },
  12894. write: {
  12895. cache: function(name, value) {
  12896. var
  12897. cache = ($module.data(metadata.cache) !== undefined)
  12898. ? $module.data(metadata.cache)
  12899. : {}
  12900. ;
  12901. if(settings.cache) {
  12902. module.verbose('Writing generated html to cache', name, value);
  12903. cache[name] = value;
  12904. $module
  12905. .data(metadata.cache, cache)
  12906. ;
  12907. }
  12908. }
  12909. },
  12910. addResults: function(html) {
  12911. if( $.isFunction(settings.onResultsAdd) ) {
  12912. if( settings.onResultsAdd.call($results, html) === false ) {
  12913. module.debug('onResultsAdd callback cancelled default action');
  12914. return false;
  12915. }
  12916. }
  12917. if(html) {
  12918. $results
  12919. .html(html)
  12920. ;
  12921. module.refreshResults();
  12922. if(settings.selectFirstResult) {
  12923. module.select.firstResult();
  12924. }
  12925. module.showResults();
  12926. }
  12927. else {
  12928. module.hideResults();
  12929. }
  12930. },
  12931. showResults: function() {
  12932. if(!module.is.visible()) {
  12933. if( module.can.transition() ) {
  12934. module.debug('Showing results with css animations');
  12935. $results
  12936. .transition({
  12937. animation : settings.transition + ' in',
  12938. debug : settings.debug,
  12939. verbose : settings.verbose,
  12940. duration : settings.duration,
  12941. queue : true
  12942. })
  12943. ;
  12944. }
  12945. else {
  12946. module.debug('Showing results with javascript');
  12947. $results
  12948. .stop()
  12949. .fadeIn(settings.duration, settings.easing)
  12950. ;
  12951. }
  12952. settings.onResultsOpen.call($results);
  12953. }
  12954. },
  12955. hideResults: function() {
  12956. if( module.is.visible() ) {
  12957. if( module.can.transition() ) {
  12958. module.debug('Hiding results with css animations');
  12959. $results
  12960. .transition({
  12961. animation : settings.transition + ' out',
  12962. debug : settings.debug,
  12963. verbose : settings.verbose,
  12964. duration : settings.duration,
  12965. queue : true
  12966. })
  12967. ;
  12968. }
  12969. else {
  12970. module.debug('Hiding results with javascript');
  12971. $results
  12972. .stop()
  12973. .fadeOut(settings.duration, settings.easing)
  12974. ;
  12975. }
  12976. settings.onResultsClose.call($results);
  12977. }
  12978. },
  12979. generateResults: function(response) {
  12980. module.debug('Generating html from response', response);
  12981. var
  12982. template = settings.templates[settings.type],
  12983. isProperObject = ($.isPlainObject(response[fields.results]) && !$.isEmptyObject(response[fields.results])),
  12984. isProperArray = ($.isArray(response[fields.results]) && response[fields.results].length > 0),
  12985. html = ''
  12986. ;
  12987. if(isProperObject || isProperArray ) {
  12988. if(settings.maxResults > 0) {
  12989. if(isProperObject) {
  12990. if(settings.type == 'standard') {
  12991. module.error(error.maxResults);
  12992. }
  12993. }
  12994. else {
  12995. response[fields.results] = response[fields.results].slice(0, settings.maxResults);
  12996. }
  12997. }
  12998. if($.isFunction(template)) {
  12999. html = template(response, fields);
  13000. }
  13001. else {
  13002. module.error(error.noTemplate, false);
  13003. }
  13004. }
  13005. else if(settings.showNoResults) {
  13006. html = module.displayMessage(error.noResults, 'empty');
  13007. }
  13008. settings.onResults.call(element, response);
  13009. return html;
  13010. },
  13011. displayMessage: function(text, type) {
  13012. type = type || 'standard';
  13013. module.debug('Displaying message', text, type);
  13014. module.addResults( settings.templates.message(text, type) );
  13015. return settings.templates.message(text, type);
  13016. },
  13017. setting: function(name, value) {
  13018. if( $.isPlainObject(name) ) {
  13019. $.extend(true, settings, name);
  13020. }
  13021. else if(value !== undefined) {
  13022. settings[name] = value;
  13023. }
  13024. else {
  13025. return settings[name];
  13026. }
  13027. },
  13028. internal: function(name, value) {
  13029. if( $.isPlainObject(name) ) {
  13030. $.extend(true, module, name);
  13031. }
  13032. else if(value !== undefined) {
  13033. module[name] = value;
  13034. }
  13035. else {
  13036. return module[name];
  13037. }
  13038. },
  13039. debug: function() {
  13040. if(!settings.silent && settings.debug) {
  13041. if(settings.performance) {
  13042. module.performance.log(arguments);
  13043. }
  13044. else {
  13045. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  13046. module.debug.apply(console, arguments);
  13047. }
  13048. }
  13049. },
  13050. verbose: function() {
  13051. if(!settings.silent && settings.verbose && settings.debug) {
  13052. if(settings.performance) {
  13053. module.performance.log(arguments);
  13054. }
  13055. else {
  13056. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  13057. module.verbose.apply(console, arguments);
  13058. }
  13059. }
  13060. },
  13061. error: function() {
  13062. if(!settings.silent) {
  13063. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  13064. module.error.apply(console, arguments);
  13065. }
  13066. },
  13067. performance: {
  13068. log: function(message) {
  13069. var
  13070. currentTime,
  13071. executionTime,
  13072. previousTime
  13073. ;
  13074. if(settings.performance) {
  13075. currentTime = new Date().getTime();
  13076. previousTime = time || currentTime;
  13077. executionTime = currentTime - previousTime;
  13078. time = currentTime;
  13079. performance.push({
  13080. 'Name' : message[0],
  13081. 'Arguments' : [].slice.call(message, 1) || '',
  13082. 'Element' : element,
  13083. 'Execution Time' : executionTime
  13084. });
  13085. }
  13086. clearTimeout(module.performance.timer);
  13087. module.performance.timer = setTimeout(module.performance.display, 500);
  13088. },
  13089. display: function() {
  13090. var
  13091. title = settings.name + ':',
  13092. totalTime = 0
  13093. ;
  13094. time = false;
  13095. clearTimeout(module.performance.timer);
  13096. $.each(performance, function(index, data) {
  13097. totalTime += data['Execution Time'];
  13098. });
  13099. title += ' ' + totalTime + 'ms';
  13100. if(moduleSelector) {
  13101. title += ' \'' + moduleSelector + '\'';
  13102. }
  13103. if($allModules.length > 1) {
  13104. title += ' ' + '(' + $allModules.length + ')';
  13105. }
  13106. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  13107. console.groupCollapsed(title);
  13108. if(console.table) {
  13109. console.table(performance);
  13110. }
  13111. else {
  13112. $.each(performance, function(index, data) {
  13113. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  13114. });
  13115. }
  13116. console.groupEnd();
  13117. }
  13118. performance = [];
  13119. }
  13120. },
  13121. invoke: function(query, passedArguments, context) {
  13122. var
  13123. object = instance,
  13124. maxDepth,
  13125. found,
  13126. response
  13127. ;
  13128. passedArguments = passedArguments || queryArguments;
  13129. context = element || context;
  13130. if(typeof query == 'string' && object !== undefined) {
  13131. query = query.split(/[\. ]/);
  13132. maxDepth = query.length - 1;
  13133. $.each(query, function(depth, value) {
  13134. var camelCaseValue = (depth != maxDepth)
  13135. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  13136. : query
  13137. ;
  13138. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  13139. object = object[camelCaseValue];
  13140. }
  13141. else if( object[camelCaseValue] !== undefined ) {
  13142. found = object[camelCaseValue];
  13143. return false;
  13144. }
  13145. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  13146. object = object[value];
  13147. }
  13148. else if( object[value] !== undefined ) {
  13149. found = object[value];
  13150. return false;
  13151. }
  13152. else {
  13153. return false;
  13154. }
  13155. });
  13156. }
  13157. if( $.isFunction( found ) ) {
  13158. response = found.apply(context, passedArguments);
  13159. }
  13160. else if(found !== undefined) {
  13161. response = found;
  13162. }
  13163. if($.isArray(returnedValue)) {
  13164. returnedValue.push(response);
  13165. }
  13166. else if(returnedValue !== undefined) {
  13167. returnedValue = [returnedValue, response];
  13168. }
  13169. else if(response !== undefined) {
  13170. returnedValue = response;
  13171. }
  13172. return found;
  13173. }
  13174. };
  13175. if(methodInvoked) {
  13176. if(instance === undefined) {
  13177. module.initialize();
  13178. }
  13179. module.invoke(query);
  13180. }
  13181. else {
  13182. if(instance !== undefined) {
  13183. instance.invoke('destroy');
  13184. }
  13185. module.initialize();
  13186. }
  13187. })
  13188. ;
  13189. return (returnedValue !== undefined)
  13190. ? returnedValue
  13191. : this
  13192. ;
  13193. };
  13194. $.fn.search.settings = {
  13195. name : 'Search',
  13196. namespace : 'search',
  13197. silent : false,
  13198. debug : false,
  13199. verbose : false,
  13200. performance : true,
  13201. // template to use (specified in settings.templates)
  13202. type : 'standard',
  13203. // minimum characters required to search
  13204. minCharacters : 1,
  13205. // whether to select first result after searching automatically
  13206. selectFirstResult : false,
  13207. // API config
  13208. apiSettings : false,
  13209. // object to search
  13210. source : false,
  13211. // fields to search
  13212. searchFields : [
  13213. 'title',
  13214. 'description'
  13215. ],
  13216. // field to display in standard results template
  13217. displayField : '',
  13218. // whether to include fuzzy results in local search
  13219. searchFullText : true,
  13220. // whether to add events to prompt automatically
  13221. automatic : true,
  13222. // delay before hiding menu after blur
  13223. hideDelay : 0,
  13224. // delay before searching
  13225. searchDelay : 200,
  13226. // maximum results returned from local
  13227. maxResults : 7,
  13228. // whether to store lookups in local cache
  13229. cache : true,
  13230. // whether no results errors should be shown
  13231. showNoResults : true,
  13232. // transition settings
  13233. transition : 'scale',
  13234. duration : 200,
  13235. easing : 'easeOutExpo',
  13236. // callbacks
  13237. onSelect : false,
  13238. onResultsAdd : false,
  13239. onSearchQuery : function(query){},
  13240. onResults : function(response){},
  13241. onResultsOpen : function(){},
  13242. onResultsClose : function(){},
  13243. className: {
  13244. animating : 'animating',
  13245. active : 'active',
  13246. empty : 'empty',
  13247. focus : 'focus',
  13248. hidden : 'hidden',
  13249. loading : 'loading',
  13250. results : 'results',
  13251. pressed : 'down'
  13252. },
  13253. error : {
  13254. source : 'Cannot search. No source used, and Semantic API module was not included',
  13255. noResults : 'Your search returned no results',
  13256. logging : 'Error in debug logging, exiting.',
  13257. noEndpoint : 'No search endpoint was specified',
  13258. noTemplate : 'A valid template name was not specified.',
  13259. serverError : 'There was an issue querying the server.',
  13260. maxResults : 'Results must be an array to use maxResults setting',
  13261. method : 'The method you called is not defined.'
  13262. },
  13263. metadata: {
  13264. cache : 'cache',
  13265. results : 'results',
  13266. result : 'result'
  13267. },
  13268. regExp: {
  13269. escape : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,
  13270. beginsWith : '(?:\s|^)'
  13271. },
  13272. // maps api response attributes to internal representation
  13273. fields: {
  13274. categories : 'results', // array of categories (category view)
  13275. categoryName : 'name', // name of category (category view)
  13276. categoryResults : 'results', // array of results (category view)
  13277. description : 'description', // result description
  13278. image : 'image', // result image
  13279. price : 'price', // result price
  13280. results : 'results', // array of results (standard)
  13281. title : 'title', // result title
  13282. url : 'url', // result url
  13283. action : 'action', // "view more" object name
  13284. actionText : 'text', // "view more" text
  13285. actionURL : 'url' // "view more" url
  13286. },
  13287. selector : {
  13288. prompt : '.prompt',
  13289. searchButton : '.search.button',
  13290. results : '.results',
  13291. message : '.results > .message',
  13292. category : '.category',
  13293. result : '.result',
  13294. title : '.title, .name'
  13295. },
  13296. templates: {
  13297. escape: function(string) {
  13298. var
  13299. badChars = /[&<>"'`]/g,
  13300. shouldEscape = /[&<>"'`]/,
  13301. escape = {
  13302. "&": "&amp;",
  13303. "<": "&lt;",
  13304. ">": "&gt;",
  13305. '"': "&quot;",
  13306. "'": "&#x27;",
  13307. "`": "&#x60;"
  13308. },
  13309. escapedChar = function(chr) {
  13310. return escape[chr];
  13311. }
  13312. ;
  13313. if(shouldEscape.test(string)) {
  13314. return string.replace(badChars, escapedChar);
  13315. }
  13316. return string;
  13317. },
  13318. message: function(message, type) {
  13319. var
  13320. html = ''
  13321. ;
  13322. if(message !== undefined && type !== undefined) {
  13323. html += ''
  13324. + '<div class="message ' + type + '">'
  13325. ;
  13326. // message type
  13327. if(type == 'empty') {
  13328. html += ''
  13329. + '<div class="header">No Results</div class="header">'
  13330. + '<div class="description">' + message + '</div class="description">'
  13331. ;
  13332. }
  13333. else {
  13334. html += ' <div class="description">' + message + '</div>';
  13335. }
  13336. html += '</div>';
  13337. }
  13338. return html;
  13339. },
  13340. category: function(response, fields) {
  13341. var
  13342. html = '',
  13343. escape = $.fn.search.settings.templates.escape
  13344. ;
  13345. if(response[fields.categoryResults] !== undefined) {
  13346. // each category
  13347. $.each(response[fields.categoryResults], function(index, category) {
  13348. if(category[fields.results] !== undefined && category.results.length > 0) {
  13349. html += '<div class="category">';
  13350. if(category[fields.categoryName] !== undefined) {
  13351. html += '<div class="name">' + category[fields.categoryName] + '</div>';
  13352. }
  13353. // each item inside category
  13354. $.each(category.results, function(index, result) {
  13355. if(result[fields.url]) {
  13356. html += '<a class="result" href="' + result[fields.url] + '">';
  13357. }
  13358. else {
  13359. html += '<a class="result">';
  13360. }
  13361. if(result[fields.image] !== undefined) {
  13362. html += ''
  13363. + '<div class="image">'
  13364. + ' <img src="' + result[fields.image] + '">'
  13365. + '</div>'
  13366. ;
  13367. }
  13368. html += '<div class="content">';
  13369. if(result[fields.price] !== undefined) {
  13370. html += '<div class="price">' + result[fields.price] + '</div>';
  13371. }
  13372. if(result[fields.title] !== undefined) {
  13373. html += '<div class="title">' + result[fields.title] + '</div>';
  13374. }
  13375. if(result[fields.description] !== undefined) {
  13376. html += '<div class="description">' + result[fields.description] + '</div>';
  13377. }
  13378. html += ''
  13379. + '</div>'
  13380. ;
  13381. html += '</a>';
  13382. });
  13383. html += ''
  13384. + '</div>'
  13385. ;
  13386. }
  13387. });
  13388. if(response[fields.action]) {
  13389. html += ''
  13390. + '<a href="' + response[fields.action][fields.actionURL] + '" class="action">'
  13391. + response[fields.action][fields.actionText]
  13392. + '</a>';
  13393. }
  13394. return html;
  13395. }
  13396. return false;
  13397. },
  13398. standard: function(response, fields) {
  13399. var
  13400. html = ''
  13401. ;
  13402. if(response[fields.results] !== undefined) {
  13403. // each result
  13404. $.each(response[fields.results], function(index, result) {
  13405. if(result[fields.url]) {
  13406. html += '<a class="result" href="' + result[fields.url] + '">';
  13407. }
  13408. else {
  13409. html += '<a class="result">';
  13410. }
  13411. if(result[fields.image] !== undefined) {
  13412. html += ''
  13413. + '<div class="image">'
  13414. + ' <img src="' + result[fields.image] + '">'
  13415. + '</div>'
  13416. ;
  13417. }
  13418. html += '<div class="content">';
  13419. if(result[fields.price] !== undefined) {
  13420. html += '<div class="price">' + result[fields.price] + '</div>';
  13421. }
  13422. if(result[fields.title] !== undefined) {
  13423. html += '<div class="title">' + result[fields.title] + '</div>';
  13424. }
  13425. if(result[fields.description] !== undefined) {
  13426. html += '<div class="description">' + result[fields.description] + '</div>';
  13427. }
  13428. html += ''
  13429. + '</div>'
  13430. ;
  13431. html += '</a>';
  13432. });
  13433. if(response[fields.action]) {
  13434. html += ''
  13435. + '<a href="' + response[fields.action][fields.actionURL] + '" class="action">'
  13436. + response[fields.action][fields.actionText]
  13437. + '</a>';
  13438. }
  13439. return html;
  13440. }
  13441. return false;
  13442. }
  13443. }
  13444. };
  13445. })( jQuery, window, document );
  13446. /*!
  13447. * # Semantic UI 2.2.6 - Shape
  13448. * http://github.com/semantic-org/semantic-ui/
  13449. *
  13450. *
  13451. * Released under the MIT license
  13452. * http://opensource.org/licenses/MIT
  13453. *
  13454. */
  13455. ;(function ($, window, document, undefined) {
  13456. "use strict";
  13457. window = (typeof window != 'undefined' && window.Math == Math)
  13458. ? window
  13459. : (typeof self != 'undefined' && self.Math == Math)
  13460. ? self
  13461. : Function('return this')()
  13462. ;
  13463. $.fn.shape = function(parameters) {
  13464. var
  13465. $allModules = $(this),
  13466. $body = $('body'),
  13467. time = new Date().getTime(),
  13468. performance = [],
  13469. query = arguments[0],
  13470. methodInvoked = (typeof query == 'string'),
  13471. queryArguments = [].slice.call(arguments, 1),
  13472. requestAnimationFrame = window.requestAnimationFrame
  13473. || window.mozRequestAnimationFrame
  13474. || window.webkitRequestAnimationFrame
  13475. || window.msRequestAnimationFrame
  13476. || function(callback) { setTimeout(callback, 0); },
  13477. returnedValue
  13478. ;
  13479. $allModules
  13480. .each(function() {
  13481. var
  13482. moduleSelector = $allModules.selector || '',
  13483. settings = ( $.isPlainObject(parameters) )
  13484. ? $.extend(true, {}, $.fn.shape.settings, parameters)
  13485. : $.extend({}, $.fn.shape.settings),
  13486. // internal aliases
  13487. namespace = settings.namespace,
  13488. selector = settings.selector,
  13489. error = settings.error,
  13490. className = settings.className,
  13491. // define namespaces for modules
  13492. eventNamespace = '.' + namespace,
  13493. moduleNamespace = 'module-' + namespace,
  13494. // selector cache
  13495. $module = $(this),
  13496. $sides = $module.find(selector.sides),
  13497. $side = $module.find(selector.side),
  13498. // private variables
  13499. nextIndex = false,
  13500. $activeSide,
  13501. $nextSide,
  13502. // standard module
  13503. element = this,
  13504. instance = $module.data(moduleNamespace),
  13505. module
  13506. ;
  13507. module = {
  13508. initialize: function() {
  13509. module.verbose('Initializing module for', element);
  13510. module.set.defaultSide();
  13511. module.instantiate();
  13512. },
  13513. instantiate: function() {
  13514. module.verbose('Storing instance of module', module);
  13515. instance = module;
  13516. $module
  13517. .data(moduleNamespace, instance)
  13518. ;
  13519. },
  13520. destroy: function() {
  13521. module.verbose('Destroying previous module for', element);
  13522. $module
  13523. .removeData(moduleNamespace)
  13524. .off(eventNamespace)
  13525. ;
  13526. },
  13527. refresh: function() {
  13528. module.verbose('Refreshing selector cache for', element);
  13529. $module = $(element);
  13530. $sides = $(this).find(selector.shape);
  13531. $side = $(this).find(selector.side);
  13532. },
  13533. repaint: function() {
  13534. module.verbose('Forcing repaint event');
  13535. var
  13536. shape = $sides[0] || document.createElement('div'),
  13537. fakeAssignment = shape.offsetWidth
  13538. ;
  13539. },
  13540. animate: function(propertyObject, callback) {
  13541. module.verbose('Animating box with properties', propertyObject);
  13542. callback = callback || function(event) {
  13543. module.verbose('Executing animation callback');
  13544. if(event !== undefined) {
  13545. event.stopPropagation();
  13546. }
  13547. module.reset();
  13548. module.set.active();
  13549. };
  13550. settings.beforeChange.call($nextSide[0]);
  13551. if(module.get.transitionEvent()) {
  13552. module.verbose('Starting CSS animation');
  13553. $module
  13554. .addClass(className.animating)
  13555. ;
  13556. $sides
  13557. .css(propertyObject)
  13558. .one(module.get.transitionEvent(), callback)
  13559. ;
  13560. module.set.duration(settings.duration);
  13561. requestAnimationFrame(function() {
  13562. $module
  13563. .addClass(className.animating)
  13564. ;
  13565. $activeSide
  13566. .addClass(className.hidden)
  13567. ;
  13568. });
  13569. }
  13570. else {
  13571. callback();
  13572. }
  13573. },
  13574. queue: function(method) {
  13575. module.debug('Queueing animation of', method);
  13576. $sides
  13577. .one(module.get.transitionEvent(), function() {
  13578. module.debug('Executing queued animation');
  13579. setTimeout(function(){
  13580. $module.shape(method);
  13581. }, 0);
  13582. })
  13583. ;
  13584. },
  13585. reset: function() {
  13586. module.verbose('Animating states reset');
  13587. $module
  13588. .removeClass(className.animating)
  13589. .attr('style', '')
  13590. .removeAttr('style')
  13591. ;
  13592. // removeAttr style does not consistently work in safari
  13593. $sides
  13594. .attr('style', '')
  13595. .removeAttr('style')
  13596. ;
  13597. $side
  13598. .attr('style', '')
  13599. .removeAttr('style')
  13600. .removeClass(className.hidden)
  13601. ;
  13602. $nextSide
  13603. .removeClass(className.animating)
  13604. .attr('style', '')
  13605. .removeAttr('style')
  13606. ;
  13607. },
  13608. is: {
  13609. complete: function() {
  13610. return ($side.filter('.' + className.active)[0] == $nextSide[0]);
  13611. },
  13612. animating: function() {
  13613. return $module.hasClass(className.animating);
  13614. }
  13615. },
  13616. set: {
  13617. defaultSide: function() {
  13618. $activeSide = $module.find('.' + settings.className.active);
  13619. $nextSide = ( $activeSide.next(selector.side).length > 0 )
  13620. ? $activeSide.next(selector.side)
  13621. : $module.find(selector.side).first()
  13622. ;
  13623. nextIndex = false;
  13624. module.verbose('Active side set to', $activeSide);
  13625. module.verbose('Next side set to', $nextSide);
  13626. },
  13627. duration: function(duration) {
  13628. duration = duration || settings.duration;
  13629. duration = (typeof duration == 'number')
  13630. ? duration + 'ms'
  13631. : duration
  13632. ;
  13633. module.verbose('Setting animation duration', duration);
  13634. if(settings.duration || settings.duration === 0) {
  13635. $sides.add($side)
  13636. .css({
  13637. '-webkit-transition-duration': duration,
  13638. '-moz-transition-duration': duration,
  13639. '-ms-transition-duration': duration,
  13640. '-o-transition-duration': duration,
  13641. 'transition-duration': duration
  13642. })
  13643. ;
  13644. }
  13645. },
  13646. currentStageSize: function() {
  13647. var
  13648. $activeSide = $module.find('.' + settings.className.active),
  13649. width = $activeSide.outerWidth(true),
  13650. height = $activeSide.outerHeight(true)
  13651. ;
  13652. $module
  13653. .css({
  13654. width: width,
  13655. height: height
  13656. })
  13657. ;
  13658. },
  13659. stageSize: function() {
  13660. var
  13661. $clone = $module.clone().addClass(className.loading),
  13662. $activeSide = $clone.find('.' + settings.className.active),
  13663. $nextSide = (nextIndex)
  13664. ? $clone.find(selector.side).eq(nextIndex)
  13665. : ( $activeSide.next(selector.side).length > 0 )
  13666. ? $activeSide.next(selector.side)
  13667. : $clone.find(selector.side).first(),
  13668. newWidth = (settings.width == 'next')
  13669. ? $nextSide.outerWidth(true)
  13670. : (settings.width == 'initial')
  13671. ? $module.width()
  13672. : settings.width,
  13673. newHeight = (settings.height == 'next')
  13674. ? $nextSide.outerHeight(true)
  13675. : (settings.height == 'initial')
  13676. ? $module.height()
  13677. : settings.height
  13678. ;
  13679. $activeSide.removeClass(className.active);
  13680. $nextSide.addClass(className.active);
  13681. $clone.insertAfter($module);
  13682. $clone.remove();
  13683. if(settings.width != 'auto') {
  13684. $module.css('width', newWidth + settings.jitter);
  13685. module.verbose('Specifying width during animation', newWidth);
  13686. }
  13687. if(settings.height != 'auto') {
  13688. $module.css('height', newHeight + settings.jitter);
  13689. module.verbose('Specifying height during animation', newHeight);
  13690. }
  13691. },
  13692. nextSide: function(selector) {
  13693. nextIndex = selector;
  13694. $nextSide = $side.filter(selector);
  13695. nextIndex = $side.index($nextSide);
  13696. if($nextSide.length === 0) {
  13697. module.set.defaultSide();
  13698. module.error(error.side);
  13699. }
  13700. module.verbose('Next side manually set to', $nextSide);
  13701. },
  13702. active: function() {
  13703. module.verbose('Setting new side to active', $nextSide);
  13704. $side
  13705. .removeClass(className.active)
  13706. ;
  13707. $nextSide
  13708. .addClass(className.active)
  13709. ;
  13710. settings.onChange.call($nextSide[0]);
  13711. module.set.defaultSide();
  13712. }
  13713. },
  13714. flip: {
  13715. up: function() {
  13716. if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
  13717. module.debug('Side already visible', $nextSide);
  13718. return;
  13719. }
  13720. if( !module.is.animating()) {
  13721. module.debug('Flipping up', $nextSide);
  13722. var
  13723. transform = module.get.transform.up()
  13724. ;
  13725. module.set.stageSize();
  13726. module.stage.above();
  13727. module.animate(transform);
  13728. }
  13729. else {
  13730. module.queue('flip up');
  13731. }
  13732. },
  13733. down: function() {
  13734. if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
  13735. module.debug('Side already visible', $nextSide);
  13736. return;
  13737. }
  13738. if( !module.is.animating()) {
  13739. module.debug('Flipping down', $nextSide);
  13740. var
  13741. transform = module.get.transform.down()
  13742. ;
  13743. module.set.stageSize();
  13744. module.stage.below();
  13745. module.animate(transform);
  13746. }
  13747. else {
  13748. module.queue('flip down');
  13749. }
  13750. },
  13751. left: function() {
  13752. if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
  13753. module.debug('Side already visible', $nextSide);
  13754. return;
  13755. }
  13756. if( !module.is.animating()) {
  13757. module.debug('Flipping left', $nextSide);
  13758. var
  13759. transform = module.get.transform.left()
  13760. ;
  13761. module.set.stageSize();
  13762. module.stage.left();
  13763. module.animate(transform);
  13764. }
  13765. else {
  13766. module.queue('flip left');
  13767. }
  13768. },
  13769. right: function() {
  13770. if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
  13771. module.debug('Side already visible', $nextSide);
  13772. return;
  13773. }
  13774. if( !module.is.animating()) {
  13775. module.debug('Flipping right', $nextSide);
  13776. var
  13777. transform = module.get.transform.right()
  13778. ;
  13779. module.set.stageSize();
  13780. module.stage.right();
  13781. module.animate(transform);
  13782. }
  13783. else {
  13784. module.queue('flip right');
  13785. }
  13786. },
  13787. over: function() {
  13788. if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
  13789. module.debug('Side already visible', $nextSide);
  13790. return;
  13791. }
  13792. if( !module.is.animating()) {
  13793. module.debug('Flipping over', $nextSide);
  13794. module.set.stageSize();
  13795. module.stage.behind();
  13796. module.animate(module.get.transform.over() );
  13797. }
  13798. else {
  13799. module.queue('flip over');
  13800. }
  13801. },
  13802. back: function() {
  13803. if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
  13804. module.debug('Side already visible', $nextSide);
  13805. return;
  13806. }
  13807. if( !module.is.animating()) {
  13808. module.debug('Flipping back', $nextSide);
  13809. module.set.stageSize();
  13810. module.stage.behind();
  13811. module.animate(module.get.transform.back() );
  13812. }
  13813. else {
  13814. module.queue('flip back');
  13815. }
  13816. }
  13817. },
  13818. get: {
  13819. transform: {
  13820. up: function() {
  13821. var
  13822. translate = {
  13823. y: -(($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2),
  13824. z: -($activeSide.outerHeight(true) / 2)
  13825. }
  13826. ;
  13827. return {
  13828. transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(-90deg)'
  13829. };
  13830. },
  13831. down: function() {
  13832. var
  13833. translate = {
  13834. y: -(($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2),
  13835. z: -($activeSide.outerHeight(true) / 2)
  13836. }
  13837. ;
  13838. return {
  13839. transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(90deg)'
  13840. };
  13841. },
  13842. left: function() {
  13843. var
  13844. translate = {
  13845. x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2),
  13846. z : -($activeSide.outerWidth(true) / 2)
  13847. }
  13848. ;
  13849. return {
  13850. transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(90deg)'
  13851. };
  13852. },
  13853. right: function() {
  13854. var
  13855. translate = {
  13856. x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2),
  13857. z : -($activeSide.outerWidth(true) / 2)
  13858. }
  13859. ;
  13860. return {
  13861. transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(-90deg)'
  13862. };
  13863. },
  13864. over: function() {
  13865. var
  13866. translate = {
  13867. x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2)
  13868. }
  13869. ;
  13870. return {
  13871. transform: 'translateX(' + translate.x + 'px) rotateY(180deg)'
  13872. };
  13873. },
  13874. back: function() {
  13875. var
  13876. translate = {
  13877. x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2)
  13878. }
  13879. ;
  13880. return {
  13881. transform: 'translateX(' + translate.x + 'px) rotateY(-180deg)'
  13882. };
  13883. }
  13884. },
  13885. transitionEvent: function() {
  13886. var
  13887. element = document.createElement('element'),
  13888. transitions = {
  13889. 'transition' :'transitionend',
  13890. 'OTransition' :'oTransitionEnd',
  13891. 'MozTransition' :'transitionend',
  13892. 'WebkitTransition' :'webkitTransitionEnd'
  13893. },
  13894. transition
  13895. ;
  13896. for(transition in transitions){
  13897. if( element.style[transition] !== undefined ){
  13898. return transitions[transition];
  13899. }
  13900. }
  13901. },
  13902. nextSide: function() {
  13903. return ( $activeSide.next(selector.side).length > 0 )
  13904. ? $activeSide.next(selector.side)
  13905. : $module.find(selector.side).first()
  13906. ;
  13907. }
  13908. },
  13909. stage: {
  13910. above: function() {
  13911. var
  13912. box = {
  13913. origin : (($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2),
  13914. depth : {
  13915. active : ($nextSide.outerHeight(true) / 2),
  13916. next : ($activeSide.outerHeight(true) / 2)
  13917. }
  13918. }
  13919. ;
  13920. module.verbose('Setting the initial animation position as above', $nextSide, box);
  13921. $sides
  13922. .css({
  13923. 'transform' : 'translateZ(-' + box.depth.active + 'px)'
  13924. })
  13925. ;
  13926. $activeSide
  13927. .css({
  13928. 'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
  13929. })
  13930. ;
  13931. $nextSide
  13932. .addClass(className.animating)
  13933. .css({
  13934. 'top' : box.origin + 'px',
  13935. 'transform' : 'rotateX(90deg) translateZ(' + box.depth.next + 'px)'
  13936. })
  13937. ;
  13938. },
  13939. below: function() {
  13940. var
  13941. box = {
  13942. origin : (($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2),
  13943. depth : {
  13944. active : ($nextSide.outerHeight(true) / 2),
  13945. next : ($activeSide.outerHeight(true) / 2)
  13946. }
  13947. }
  13948. ;
  13949. module.verbose('Setting the initial animation position as below', $nextSide, box);
  13950. $sides
  13951. .css({
  13952. 'transform' : 'translateZ(-' + box.depth.active + 'px)'
  13953. })
  13954. ;
  13955. $activeSide
  13956. .css({
  13957. 'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
  13958. })
  13959. ;
  13960. $nextSide
  13961. .addClass(className.animating)
  13962. .css({
  13963. 'top' : box.origin + 'px',
  13964. 'transform' : 'rotateX(-90deg) translateZ(' + box.depth.next + 'px)'
  13965. })
  13966. ;
  13967. },
  13968. left: function() {
  13969. var
  13970. height = {
  13971. active : $activeSide.outerWidth(true),
  13972. next : $nextSide.outerWidth(true)
  13973. },
  13974. box = {
  13975. origin : ( ( height.active - height.next ) / 2),
  13976. depth : {
  13977. active : (height.next / 2),
  13978. next : (height.active / 2)
  13979. }
  13980. }
  13981. ;
  13982. module.verbose('Setting the initial animation position as left', $nextSide, box);
  13983. $sides
  13984. .css({
  13985. 'transform' : 'translateZ(-' + box.depth.active + 'px)'
  13986. })
  13987. ;
  13988. $activeSide
  13989. .css({
  13990. 'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
  13991. })
  13992. ;
  13993. $nextSide
  13994. .addClass(className.animating)
  13995. .css({
  13996. 'left' : box.origin + 'px',
  13997. 'transform' : 'rotateY(-90deg) translateZ(' + box.depth.next + 'px)'
  13998. })
  13999. ;
  14000. },
  14001. right: function() {
  14002. var
  14003. height = {
  14004. active : $activeSide.outerWidth(true),
  14005. next : $nextSide.outerWidth(true)
  14006. },
  14007. box = {
  14008. origin : ( ( height.active - height.next ) / 2),
  14009. depth : {
  14010. active : (height.next / 2),
  14011. next : (height.active / 2)
  14012. }
  14013. }
  14014. ;
  14015. module.verbose('Setting the initial animation position as left', $nextSide, box);
  14016. $sides
  14017. .css({
  14018. 'transform' : 'translateZ(-' + box.depth.active + 'px)'
  14019. })
  14020. ;
  14021. $activeSide
  14022. .css({
  14023. 'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
  14024. })
  14025. ;
  14026. $nextSide
  14027. .addClass(className.animating)
  14028. .css({
  14029. 'left' : box.origin + 'px',
  14030. 'transform' : 'rotateY(90deg) translateZ(' + box.depth.next + 'px)'
  14031. })
  14032. ;
  14033. },
  14034. behind: function() {
  14035. var
  14036. height = {
  14037. active : $activeSide.outerWidth(true),
  14038. next : $nextSide.outerWidth(true)
  14039. },
  14040. box = {
  14041. origin : ( ( height.active - height.next ) / 2),
  14042. depth : {
  14043. active : (height.next / 2),
  14044. next : (height.active / 2)
  14045. }
  14046. }
  14047. ;
  14048. module.verbose('Setting the initial animation position as behind', $nextSide, box);
  14049. $activeSide
  14050. .css({
  14051. 'transform' : 'rotateY(0deg)'
  14052. })
  14053. ;
  14054. $nextSide
  14055. .addClass(className.animating)
  14056. .css({
  14057. 'left' : box.origin + 'px',
  14058. 'transform' : 'rotateY(-180deg)'
  14059. })
  14060. ;
  14061. }
  14062. },
  14063. setting: function(name, value) {
  14064. module.debug('Changing setting', name, value);
  14065. if( $.isPlainObject(name) ) {
  14066. $.extend(true, settings, name);
  14067. }
  14068. else if(value !== undefined) {
  14069. if($.isPlainObject(settings[name])) {
  14070. $.extend(true, settings[name], value);
  14071. }
  14072. else {
  14073. settings[name] = value;
  14074. }
  14075. }
  14076. else {
  14077. return settings[name];
  14078. }
  14079. },
  14080. internal: function(name, value) {
  14081. if( $.isPlainObject(name) ) {
  14082. $.extend(true, module, name);
  14083. }
  14084. else if(value !== undefined) {
  14085. module[name] = value;
  14086. }
  14087. else {
  14088. return module[name];
  14089. }
  14090. },
  14091. debug: function() {
  14092. if(!settings.silent && settings.debug) {
  14093. if(settings.performance) {
  14094. module.performance.log(arguments);
  14095. }
  14096. else {
  14097. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  14098. module.debug.apply(console, arguments);
  14099. }
  14100. }
  14101. },
  14102. verbose: function() {
  14103. if(!settings.silent && settings.verbose && settings.debug) {
  14104. if(settings.performance) {
  14105. module.performance.log(arguments);
  14106. }
  14107. else {
  14108. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  14109. module.verbose.apply(console, arguments);
  14110. }
  14111. }
  14112. },
  14113. error: function() {
  14114. if(!settings.silent) {
  14115. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  14116. module.error.apply(console, arguments);
  14117. }
  14118. },
  14119. performance: {
  14120. log: function(message) {
  14121. var
  14122. currentTime,
  14123. executionTime,
  14124. previousTime
  14125. ;
  14126. if(settings.performance) {
  14127. currentTime = new Date().getTime();
  14128. previousTime = time || currentTime;
  14129. executionTime = currentTime - previousTime;
  14130. time = currentTime;
  14131. performance.push({
  14132. 'Name' : message[0],
  14133. 'Arguments' : [].slice.call(message, 1) || '',
  14134. 'Element' : element,
  14135. 'Execution Time' : executionTime
  14136. });
  14137. }
  14138. clearTimeout(module.performance.timer);
  14139. module.performance.timer = setTimeout(module.performance.display, 500);
  14140. },
  14141. display: function() {
  14142. var
  14143. title = settings.name + ':',
  14144. totalTime = 0
  14145. ;
  14146. time = false;
  14147. clearTimeout(module.performance.timer);
  14148. $.each(performance, function(index, data) {
  14149. totalTime += data['Execution Time'];
  14150. });
  14151. title += ' ' + totalTime + 'ms';
  14152. if(moduleSelector) {
  14153. title += ' \'' + moduleSelector + '\'';
  14154. }
  14155. if($allModules.length > 1) {
  14156. title += ' ' + '(' + $allModules.length + ')';
  14157. }
  14158. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  14159. console.groupCollapsed(title);
  14160. if(console.table) {
  14161. console.table(performance);
  14162. }
  14163. else {
  14164. $.each(performance, function(index, data) {
  14165. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  14166. });
  14167. }
  14168. console.groupEnd();
  14169. }
  14170. performance = [];
  14171. }
  14172. },
  14173. invoke: function(query, passedArguments, context) {
  14174. var
  14175. object = instance,
  14176. maxDepth,
  14177. found,
  14178. response
  14179. ;
  14180. passedArguments = passedArguments || queryArguments;
  14181. context = element || context;
  14182. if(typeof query == 'string' && object !== undefined) {
  14183. query = query.split(/[\. ]/);
  14184. maxDepth = query.length - 1;
  14185. $.each(query, function(depth, value) {
  14186. var camelCaseValue = (depth != maxDepth)
  14187. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  14188. : query
  14189. ;
  14190. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  14191. object = object[camelCaseValue];
  14192. }
  14193. else if( object[camelCaseValue] !== undefined ) {
  14194. found = object[camelCaseValue];
  14195. return false;
  14196. }
  14197. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  14198. object = object[value];
  14199. }
  14200. else if( object[value] !== undefined ) {
  14201. found = object[value];
  14202. return false;
  14203. }
  14204. else {
  14205. return false;
  14206. }
  14207. });
  14208. }
  14209. if ( $.isFunction( found ) ) {
  14210. response = found.apply(context, passedArguments);
  14211. }
  14212. else if(found !== undefined) {
  14213. response = found;
  14214. }
  14215. if($.isArray(returnedValue)) {
  14216. returnedValue.push(response);
  14217. }
  14218. else if(returnedValue !== undefined) {
  14219. returnedValue = [returnedValue, response];
  14220. }
  14221. else if(response !== undefined) {
  14222. returnedValue = response;
  14223. }
  14224. return found;
  14225. }
  14226. };
  14227. if(methodInvoked) {
  14228. if(instance === undefined) {
  14229. module.initialize();
  14230. }
  14231. module.invoke(query);
  14232. }
  14233. else {
  14234. if(instance !== undefined) {
  14235. instance.invoke('destroy');
  14236. }
  14237. module.initialize();
  14238. }
  14239. })
  14240. ;
  14241. return (returnedValue !== undefined)
  14242. ? returnedValue
  14243. : this
  14244. ;
  14245. };
  14246. $.fn.shape.settings = {
  14247. // module info
  14248. name : 'Shape',
  14249. // hide all debug content
  14250. silent : false,
  14251. // debug content outputted to console
  14252. debug : false,
  14253. // verbose debug output
  14254. verbose : false,
  14255. // fudge factor in pixels when swapping from 2d to 3d (can be useful to correct rounding errors)
  14256. jitter : 0,
  14257. // performance data output
  14258. performance: true,
  14259. // event namespace
  14260. namespace : 'shape',
  14261. // width during animation, can be set to 'auto', initial', 'next' or pixel amount
  14262. width: 'initial',
  14263. // height during animation, can be set to 'auto', 'initial', 'next' or pixel amount
  14264. height: 'initial',
  14265. // callback occurs on side change
  14266. beforeChange : function() {},
  14267. onChange : function() {},
  14268. // allow animation to same side
  14269. allowRepeats: false,
  14270. // animation duration
  14271. duration : false,
  14272. // possible errors
  14273. error: {
  14274. side : 'You tried to switch to a side that does not exist.',
  14275. method : 'The method you called is not defined'
  14276. },
  14277. // classnames used
  14278. className : {
  14279. animating : 'animating',
  14280. hidden : 'hidden',
  14281. loading : 'loading',
  14282. active : 'active'
  14283. },
  14284. // selectors used
  14285. selector : {
  14286. sides : '.sides',
  14287. side : '.side'
  14288. }
  14289. };
  14290. })( jQuery, window, document );
  14291. /*!
  14292. * # Semantic UI 2.2.6 - Sidebar
  14293. * http://github.com/semantic-org/semantic-ui/
  14294. *
  14295. *
  14296. * Released under the MIT license
  14297. * http://opensource.org/licenses/MIT
  14298. *
  14299. */
  14300. ;(function ($, window, document, undefined) {
  14301. "use strict";
  14302. window = (typeof window != 'undefined' && window.Math == Math)
  14303. ? window
  14304. : (typeof self != 'undefined' && self.Math == Math)
  14305. ? self
  14306. : Function('return this')()
  14307. ;
  14308. $.fn.sidebar = function(parameters) {
  14309. var
  14310. $allModules = $(this),
  14311. $window = $(window),
  14312. $document = $(document),
  14313. $html = $('html'),
  14314. $head = $('head'),
  14315. moduleSelector = $allModules.selector || '',
  14316. time = new Date().getTime(),
  14317. performance = [],
  14318. query = arguments[0],
  14319. methodInvoked = (typeof query == 'string'),
  14320. queryArguments = [].slice.call(arguments, 1),
  14321. requestAnimationFrame = window.requestAnimationFrame
  14322. || window.mozRequestAnimationFrame
  14323. || window.webkitRequestAnimationFrame
  14324. || window.msRequestAnimationFrame
  14325. || function(callback) { setTimeout(callback, 0); },
  14326. returnedValue
  14327. ;
  14328. $allModules
  14329. .each(function() {
  14330. var
  14331. settings = ( $.isPlainObject(parameters) )
  14332. ? $.extend(true, {}, $.fn.sidebar.settings, parameters)
  14333. : $.extend({}, $.fn.sidebar.settings),
  14334. selector = settings.selector,
  14335. className = settings.className,
  14336. namespace = settings.namespace,
  14337. regExp = settings.regExp,
  14338. error = settings.error,
  14339. eventNamespace = '.' + namespace,
  14340. moduleNamespace = 'module-' + namespace,
  14341. $module = $(this),
  14342. $context = $(settings.context),
  14343. $sidebars = $module.children(selector.sidebar),
  14344. $fixed = $context.children(selector.fixed),
  14345. $pusher = $context.children(selector.pusher),
  14346. $style,
  14347. element = this,
  14348. instance = $module.data(moduleNamespace),
  14349. elementNamespace,
  14350. id,
  14351. currentScroll,
  14352. transitionEvent,
  14353. module
  14354. ;
  14355. module = {
  14356. initialize: function() {
  14357. module.debug('Initializing sidebar', parameters);
  14358. module.create.id();
  14359. transitionEvent = module.get.transitionEvent();
  14360. if(module.is.ios()) {
  14361. module.set.ios();
  14362. }
  14363. // avoids locking rendering if initialized in onReady
  14364. if(settings.delaySetup) {
  14365. requestAnimationFrame(module.setup.layout);
  14366. }
  14367. else {
  14368. module.setup.layout();
  14369. }
  14370. requestAnimationFrame(function() {
  14371. module.setup.cache();
  14372. });
  14373. module.instantiate();
  14374. },
  14375. instantiate: function() {
  14376. module.verbose('Storing instance of module', module);
  14377. instance = module;
  14378. $module
  14379. .data(moduleNamespace, module)
  14380. ;
  14381. },
  14382. create: {
  14383. id: function() {
  14384. id = (Math.random().toString(16) + '000000000').substr(2,8);
  14385. elementNamespace = '.' + id;
  14386. module.verbose('Creating unique id for element', id);
  14387. }
  14388. },
  14389. destroy: function() {
  14390. module.verbose('Destroying previous module for', $module);
  14391. $module
  14392. .off(eventNamespace)
  14393. .removeData(moduleNamespace)
  14394. ;
  14395. if(module.is.ios()) {
  14396. module.remove.ios();
  14397. }
  14398. // bound by uuid
  14399. $context.off(elementNamespace);
  14400. $window.off(elementNamespace);
  14401. $document.off(elementNamespace);
  14402. },
  14403. event: {
  14404. clickaway: function(event) {
  14405. var
  14406. clickedInPusher = ($pusher.find(event.target).length > 0 || $pusher.is(event.target)),
  14407. clickedContext = ($context.is(event.target))
  14408. ;
  14409. if(clickedInPusher) {
  14410. module.verbose('User clicked on dimmed page');
  14411. module.hide();
  14412. }
  14413. if(clickedContext) {
  14414. module.verbose('User clicked on dimmable context (scaled out page)');
  14415. module.hide();
  14416. }
  14417. },
  14418. touch: function(event) {
  14419. //event.stopPropagation();
  14420. },
  14421. containScroll: function(event) {
  14422. if(element.scrollTop <= 0) {
  14423. element.scrollTop = 1;
  14424. }
  14425. if((element.scrollTop + element.offsetHeight) >= element.scrollHeight) {
  14426. element.scrollTop = element.scrollHeight - element.offsetHeight - 1;
  14427. }
  14428. },
  14429. scroll: function(event) {
  14430. if( $(event.target).closest(selector.sidebar).length === 0 ) {
  14431. event.preventDefault();
  14432. }
  14433. }
  14434. },
  14435. bind: {
  14436. clickaway: function() {
  14437. module.verbose('Adding clickaway events to context', $context);
  14438. if(settings.closable) {
  14439. $context
  14440. .on('click' + elementNamespace, module.event.clickaway)
  14441. .on('touchend' + elementNamespace, module.event.clickaway)
  14442. ;
  14443. }
  14444. },
  14445. scrollLock: function() {
  14446. if(settings.scrollLock) {
  14447. module.debug('Disabling page scroll');
  14448. $window
  14449. .on('DOMMouseScroll' + elementNamespace, module.event.scroll)
  14450. ;
  14451. }
  14452. module.verbose('Adding events to contain sidebar scroll');
  14453. $document
  14454. .on('touchmove' + elementNamespace, module.event.touch)
  14455. ;
  14456. $module
  14457. .on('scroll' + eventNamespace, module.event.containScroll)
  14458. ;
  14459. }
  14460. },
  14461. unbind: {
  14462. clickaway: function() {
  14463. module.verbose('Removing clickaway events from context', $context);
  14464. $context.off(elementNamespace);
  14465. },
  14466. scrollLock: function() {
  14467. module.verbose('Removing scroll lock from page');
  14468. $document.off(elementNamespace);
  14469. $window.off(elementNamespace);
  14470. $module.off('scroll' + eventNamespace);
  14471. }
  14472. },
  14473. add: {
  14474. inlineCSS: function() {
  14475. var
  14476. width = module.cache.width || $module.outerWidth(),
  14477. height = module.cache.height || $module.outerHeight(),
  14478. isRTL = module.is.rtl(),
  14479. direction = module.get.direction(),
  14480. distance = {
  14481. left : width,
  14482. right : -width,
  14483. top : height,
  14484. bottom : -height
  14485. },
  14486. style
  14487. ;
  14488. if(isRTL){
  14489. module.verbose('RTL detected, flipping widths');
  14490. distance.left = -width;
  14491. distance.right = width;
  14492. }
  14493. style = '<style>';
  14494. if(direction === 'left' || direction === 'right') {
  14495. module.debug('Adding CSS rules for animation distance', width);
  14496. style += ''
  14497. + ' .ui.visible.' + direction + '.sidebar ~ .fixed,'
  14498. + ' .ui.visible.' + direction + '.sidebar ~ .pusher {'
  14499. + ' -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);'
  14500. + ' transform: translate3d('+ distance[direction] + 'px, 0, 0);'
  14501. + ' }'
  14502. ;
  14503. }
  14504. else if(direction === 'top' || direction == 'bottom') {
  14505. style += ''
  14506. + ' .ui.visible.' + direction + '.sidebar ~ .fixed,'
  14507. + ' .ui.visible.' + direction + '.sidebar ~ .pusher {'
  14508. + ' -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);'
  14509. + ' transform: translate3d(0, ' + distance[direction] + 'px, 0);'
  14510. + ' }'
  14511. ;
  14512. }
  14513. /* IE is only browser not to create context with transforms */
  14514. /* https://www.w3.org/Bugs/Public/show_bug.cgi?id=16328 */
  14515. if( module.is.ie() ) {
  14516. if(direction === 'left' || direction === 'right') {
  14517. module.debug('Adding CSS rules for animation distance', width);
  14518. style += ''
  14519. + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {'
  14520. + ' -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);'
  14521. + ' transform: translate3d('+ distance[direction] + 'px, 0, 0);'
  14522. + ' }'
  14523. ;
  14524. }
  14525. else if(direction === 'top' || direction == 'bottom') {
  14526. style += ''
  14527. + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {'
  14528. + ' -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);'
  14529. + ' transform: translate3d(0, ' + distance[direction] + 'px, 0);'
  14530. + ' }'
  14531. ;
  14532. }
  14533. /* opposite sides visible forces content overlay */
  14534. style += ''
  14535. + ' body.pushable > .ui.visible.left.sidebar ~ .ui.visible.right.sidebar ~ .pusher:after,'
  14536. + ' body.pushable > .ui.visible.right.sidebar ~ .ui.visible.left.sidebar ~ .pusher:after {'
  14537. + ' -webkit-transform: translate3d(0px, 0, 0);'
  14538. + ' transform: translate3d(0px, 0, 0);'
  14539. + ' }'
  14540. ;
  14541. }
  14542. style += '</style>';
  14543. $style = $(style)
  14544. .appendTo($head)
  14545. ;
  14546. module.debug('Adding sizing css to head', $style);
  14547. }
  14548. },
  14549. refresh: function() {
  14550. module.verbose('Refreshing selector cache');
  14551. $context = $(settings.context);
  14552. $sidebars = $context.children(selector.sidebar);
  14553. $pusher = $context.children(selector.pusher);
  14554. $fixed = $context.children(selector.fixed);
  14555. module.clear.cache();
  14556. },
  14557. refreshSidebars: function() {
  14558. module.verbose('Refreshing other sidebars');
  14559. $sidebars = $context.children(selector.sidebar);
  14560. },
  14561. repaint: function() {
  14562. module.verbose('Forcing repaint event');
  14563. element.style.display = 'none';
  14564. var ignored = element.offsetHeight;
  14565. element.scrollTop = element.scrollTop;
  14566. element.style.display = '';
  14567. },
  14568. setup: {
  14569. cache: function() {
  14570. module.cache = {
  14571. width : $module.outerWidth(),
  14572. height : $module.outerHeight(),
  14573. rtl : ($module.css('direction') == 'rtl')
  14574. };
  14575. },
  14576. layout: function() {
  14577. if( $context.children(selector.pusher).length === 0 ) {
  14578. module.debug('Adding wrapper element for sidebar');
  14579. module.error(error.pusher);
  14580. $pusher = $('<div class="pusher" />');
  14581. $context
  14582. .children()
  14583. .not(selector.omitted)
  14584. .not($sidebars)
  14585. .wrapAll($pusher)
  14586. ;
  14587. module.refresh();
  14588. }
  14589. if($module.nextAll(selector.pusher).length === 0 || $module.nextAll(selector.pusher)[0] !== $pusher[0]) {
  14590. module.debug('Moved sidebar to correct parent element');
  14591. module.error(error.movedSidebar, element);
  14592. $module.detach().prependTo($context);
  14593. module.refresh();
  14594. }
  14595. module.clear.cache();
  14596. module.set.pushable();
  14597. module.set.direction();
  14598. }
  14599. },
  14600. attachEvents: function(selector, event) {
  14601. var
  14602. $toggle = $(selector)
  14603. ;
  14604. event = $.isFunction(module[event])
  14605. ? module[event]
  14606. : module.toggle
  14607. ;
  14608. if($toggle.length > 0) {
  14609. module.debug('Attaching sidebar events to element', selector, event);
  14610. $toggle
  14611. .on('click' + eventNamespace, event)
  14612. ;
  14613. }
  14614. else {
  14615. module.error(error.notFound, selector);
  14616. }
  14617. },
  14618. show: function(callback) {
  14619. callback = $.isFunction(callback)
  14620. ? callback
  14621. : function(){}
  14622. ;
  14623. if(module.is.hidden()) {
  14624. module.refreshSidebars();
  14625. if(settings.overlay) {
  14626. module.error(error.overlay);
  14627. settings.transition = 'overlay';
  14628. }
  14629. module.refresh();
  14630. if(module.othersActive()) {
  14631. module.debug('Other sidebars currently visible');
  14632. if(settings.exclusive) {
  14633. // if not overlay queue animation after hide
  14634. if(settings.transition != 'overlay') {
  14635. module.hideOthers(module.show);
  14636. return;
  14637. }
  14638. else {
  14639. module.hideOthers();
  14640. }
  14641. }
  14642. else {
  14643. settings.transition = 'overlay';
  14644. }
  14645. }
  14646. module.pushPage(function() {
  14647. callback.call(element);
  14648. settings.onShow.call(element);
  14649. });
  14650. settings.onChange.call(element);
  14651. settings.onVisible.call(element);
  14652. }
  14653. else {
  14654. module.debug('Sidebar is already visible');
  14655. }
  14656. },
  14657. hide: function(callback) {
  14658. callback = $.isFunction(callback)
  14659. ? callback
  14660. : function(){}
  14661. ;
  14662. if(module.is.visible() || module.is.animating()) {
  14663. module.debug('Hiding sidebar', callback);
  14664. module.refreshSidebars();
  14665. module.pullPage(function() {
  14666. callback.call(element);
  14667. settings.onHidden.call(element);
  14668. });
  14669. settings.onChange.call(element);
  14670. settings.onHide.call(element);
  14671. }
  14672. },
  14673. othersAnimating: function() {
  14674. return ($sidebars.not($module).filter('.' + className.animating).length > 0);
  14675. },
  14676. othersVisible: function() {
  14677. return ($sidebars.not($module).filter('.' + className.visible).length > 0);
  14678. },
  14679. othersActive: function() {
  14680. return(module.othersVisible() || module.othersAnimating());
  14681. },
  14682. hideOthers: function(callback) {
  14683. var
  14684. $otherSidebars = $sidebars.not($module).filter('.' + className.visible),
  14685. sidebarCount = $otherSidebars.length,
  14686. callbackCount = 0
  14687. ;
  14688. callback = callback || function(){};
  14689. $otherSidebars
  14690. .sidebar('hide', function() {
  14691. callbackCount++;
  14692. if(callbackCount == sidebarCount) {
  14693. callback();
  14694. }
  14695. })
  14696. ;
  14697. },
  14698. toggle: function() {
  14699. module.verbose('Determining toggled direction');
  14700. if(module.is.hidden()) {
  14701. module.show();
  14702. }
  14703. else {
  14704. module.hide();
  14705. }
  14706. },
  14707. pushPage: function(callback) {
  14708. var
  14709. transition = module.get.transition(),
  14710. $transition = (transition === 'overlay' || module.othersActive())
  14711. ? $module
  14712. : $pusher,
  14713. animate,
  14714. dim,
  14715. transitionEnd
  14716. ;
  14717. callback = $.isFunction(callback)
  14718. ? callback
  14719. : function(){}
  14720. ;
  14721. if(settings.transition == 'scale down') {
  14722. module.scrollToTop();
  14723. }
  14724. module.set.transition(transition);
  14725. module.repaint();
  14726. animate = function() {
  14727. module.bind.clickaway();
  14728. module.add.inlineCSS();
  14729. module.set.animating();
  14730. module.set.visible();
  14731. };
  14732. dim = function() {
  14733. module.set.dimmed();
  14734. };
  14735. transitionEnd = function(event) {
  14736. if( event.target == $transition[0] ) {
  14737. $transition.off(transitionEvent + elementNamespace, transitionEnd);
  14738. module.remove.animating();
  14739. module.bind.scrollLock();
  14740. callback.call(element);
  14741. }
  14742. };
  14743. $transition.off(transitionEvent + elementNamespace);
  14744. $transition.on(transitionEvent + elementNamespace, transitionEnd);
  14745. requestAnimationFrame(animate);
  14746. if(settings.dimPage && !module.othersVisible()) {
  14747. requestAnimationFrame(dim);
  14748. }
  14749. },
  14750. pullPage: function(callback) {
  14751. var
  14752. transition = module.get.transition(),
  14753. $transition = (transition == 'overlay' || module.othersActive())
  14754. ? $module
  14755. : $pusher,
  14756. animate,
  14757. transitionEnd
  14758. ;
  14759. callback = $.isFunction(callback)
  14760. ? callback
  14761. : function(){}
  14762. ;
  14763. module.verbose('Removing context push state', module.get.direction());
  14764. module.unbind.clickaway();
  14765. module.unbind.scrollLock();
  14766. animate = function() {
  14767. module.set.transition(transition);
  14768. module.set.animating();
  14769. module.remove.visible();
  14770. if(settings.dimPage && !module.othersVisible()) {
  14771. $pusher.removeClass(className.dimmed);
  14772. }
  14773. };
  14774. transitionEnd = function(event) {
  14775. if( event.target == $transition[0] ) {
  14776. $transition.off(transitionEvent + elementNamespace, transitionEnd);
  14777. module.remove.animating();
  14778. module.remove.transition();
  14779. module.remove.inlineCSS();
  14780. if(transition == 'scale down' || (settings.returnScroll && module.is.mobile()) ) {
  14781. module.scrollBack();
  14782. }
  14783. callback.call(element);
  14784. }
  14785. };
  14786. $transition.off(transitionEvent + elementNamespace);
  14787. $transition.on(transitionEvent + elementNamespace, transitionEnd);
  14788. requestAnimationFrame(animate);
  14789. },
  14790. scrollToTop: function() {
  14791. module.verbose('Scrolling to top of page to avoid animation issues');
  14792. currentScroll = $(window).scrollTop();
  14793. $module.scrollTop(0);
  14794. window.scrollTo(0, 0);
  14795. },
  14796. scrollBack: function() {
  14797. module.verbose('Scrolling back to original page position');
  14798. window.scrollTo(0, currentScroll);
  14799. },
  14800. clear: {
  14801. cache: function() {
  14802. module.verbose('Clearing cached dimensions');
  14803. module.cache = {};
  14804. }
  14805. },
  14806. set: {
  14807. // ios only (scroll on html not document). This prevent auto-resize canvas/scroll in ios
  14808. ios: function() {
  14809. $html.addClass(className.ios);
  14810. },
  14811. // container
  14812. pushed: function() {
  14813. $context.addClass(className.pushed);
  14814. },
  14815. pushable: function() {
  14816. $context.addClass(className.pushable);
  14817. },
  14818. // pusher
  14819. dimmed: function() {
  14820. $pusher.addClass(className.dimmed);
  14821. },
  14822. // sidebar
  14823. active: function() {
  14824. $module.addClass(className.active);
  14825. },
  14826. animating: function() {
  14827. $module.addClass(className.animating);
  14828. },
  14829. transition: function(transition) {
  14830. transition = transition || module.get.transition();
  14831. $module.addClass(transition);
  14832. },
  14833. direction: function(direction) {
  14834. direction = direction || module.get.direction();
  14835. $module.addClass(className[direction]);
  14836. },
  14837. visible: function() {
  14838. $module.addClass(className.visible);
  14839. },
  14840. overlay: function() {
  14841. $module.addClass(className.overlay);
  14842. }
  14843. },
  14844. remove: {
  14845. inlineCSS: function() {
  14846. module.debug('Removing inline css styles', $style);
  14847. if($style && $style.length > 0) {
  14848. $style.remove();
  14849. }
  14850. },
  14851. // ios scroll on html not document
  14852. ios: function() {
  14853. $html.removeClass(className.ios);
  14854. },
  14855. // context
  14856. pushed: function() {
  14857. $context.removeClass(className.pushed);
  14858. },
  14859. pushable: function() {
  14860. $context.removeClass(className.pushable);
  14861. },
  14862. // sidebar
  14863. active: function() {
  14864. $module.removeClass(className.active);
  14865. },
  14866. animating: function() {
  14867. $module.removeClass(className.animating);
  14868. },
  14869. transition: function(transition) {
  14870. transition = transition || module.get.transition();
  14871. $module.removeClass(transition);
  14872. },
  14873. direction: function(direction) {
  14874. direction = direction || module.get.direction();
  14875. $module.removeClass(className[direction]);
  14876. },
  14877. visible: function() {
  14878. $module.removeClass(className.visible);
  14879. },
  14880. overlay: function() {
  14881. $module.removeClass(className.overlay);
  14882. }
  14883. },
  14884. get: {
  14885. direction: function() {
  14886. if($module.hasClass(className.top)) {
  14887. return className.top;
  14888. }
  14889. else if($module.hasClass(className.right)) {
  14890. return className.right;
  14891. }
  14892. else if($module.hasClass(className.bottom)) {
  14893. return className.bottom;
  14894. }
  14895. return className.left;
  14896. },
  14897. transition: function() {
  14898. var
  14899. direction = module.get.direction(),
  14900. transition
  14901. ;
  14902. transition = ( module.is.mobile() )
  14903. ? (settings.mobileTransition == 'auto')
  14904. ? settings.defaultTransition.mobile[direction]
  14905. : settings.mobileTransition
  14906. : (settings.transition == 'auto')
  14907. ? settings.defaultTransition.computer[direction]
  14908. : settings.transition
  14909. ;
  14910. module.verbose('Determined transition', transition);
  14911. return transition;
  14912. },
  14913. transitionEvent: function() {
  14914. var
  14915. element = document.createElement('element'),
  14916. transitions = {
  14917. 'transition' :'transitionend',
  14918. 'OTransition' :'oTransitionEnd',
  14919. 'MozTransition' :'transitionend',
  14920. 'WebkitTransition' :'webkitTransitionEnd'
  14921. },
  14922. transition
  14923. ;
  14924. for(transition in transitions){
  14925. if( element.style[transition] !== undefined ){
  14926. return transitions[transition];
  14927. }
  14928. }
  14929. }
  14930. },
  14931. is: {
  14932. ie: function() {
  14933. var
  14934. isIE11 = (!(window.ActiveXObject) && 'ActiveXObject' in window),
  14935. isIE = ('ActiveXObject' in window)
  14936. ;
  14937. return (isIE11 || isIE);
  14938. },
  14939. ios: function() {
  14940. var
  14941. userAgent = navigator.userAgent,
  14942. isIOS = userAgent.match(regExp.ios),
  14943. isMobileChrome = userAgent.match(regExp.mobileChrome)
  14944. ;
  14945. if(isIOS && !isMobileChrome) {
  14946. module.verbose('Browser was found to be iOS', userAgent);
  14947. return true;
  14948. }
  14949. else {
  14950. return false;
  14951. }
  14952. },
  14953. mobile: function() {
  14954. var
  14955. userAgent = navigator.userAgent,
  14956. isMobile = userAgent.match(regExp.mobile)
  14957. ;
  14958. if(isMobile) {
  14959. module.verbose('Browser was found to be mobile', userAgent);
  14960. return true;
  14961. }
  14962. else {
  14963. module.verbose('Browser is not mobile, using regular transition', userAgent);
  14964. return false;
  14965. }
  14966. },
  14967. hidden: function() {
  14968. return !module.is.visible();
  14969. },
  14970. visible: function() {
  14971. return $module.hasClass(className.visible);
  14972. },
  14973. // alias
  14974. open: function() {
  14975. return module.is.visible();
  14976. },
  14977. closed: function() {
  14978. return module.is.hidden();
  14979. },
  14980. vertical: function() {
  14981. return $module.hasClass(className.top);
  14982. },
  14983. animating: function() {
  14984. return $context.hasClass(className.animating);
  14985. },
  14986. rtl: function () {
  14987. if(module.cache.rtl === undefined) {
  14988. module.cache.rtl = ($module.css('direction') == 'rtl');
  14989. }
  14990. return module.cache.rtl;
  14991. }
  14992. },
  14993. setting: function(name, value) {
  14994. module.debug('Changing setting', name, value);
  14995. if( $.isPlainObject(name) ) {
  14996. $.extend(true, settings, name);
  14997. }
  14998. else if(value !== undefined) {
  14999. if($.isPlainObject(settings[name])) {
  15000. $.extend(true, settings[name], value);
  15001. }
  15002. else {
  15003. settings[name] = value;
  15004. }
  15005. }
  15006. else {
  15007. return settings[name];
  15008. }
  15009. },
  15010. internal: function(name, value) {
  15011. if( $.isPlainObject(name) ) {
  15012. $.extend(true, module, name);
  15013. }
  15014. else if(value !== undefined) {
  15015. module[name] = value;
  15016. }
  15017. else {
  15018. return module[name];
  15019. }
  15020. },
  15021. debug: function() {
  15022. if(!settings.silent && settings.debug) {
  15023. if(settings.performance) {
  15024. module.performance.log(arguments);
  15025. }
  15026. else {
  15027. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  15028. module.debug.apply(console, arguments);
  15029. }
  15030. }
  15031. },
  15032. verbose: function() {
  15033. if(!settings.silent && settings.verbose && settings.debug) {
  15034. if(settings.performance) {
  15035. module.performance.log(arguments);
  15036. }
  15037. else {
  15038. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  15039. module.verbose.apply(console, arguments);
  15040. }
  15041. }
  15042. },
  15043. error: function() {
  15044. if(!settings.silent) {
  15045. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  15046. module.error.apply(console, arguments);
  15047. }
  15048. },
  15049. performance: {
  15050. log: function(message) {
  15051. var
  15052. currentTime,
  15053. executionTime,
  15054. previousTime
  15055. ;
  15056. if(settings.performance) {
  15057. currentTime = new Date().getTime();
  15058. previousTime = time || currentTime;
  15059. executionTime = currentTime - previousTime;
  15060. time = currentTime;
  15061. performance.push({
  15062. 'Name' : message[0],
  15063. 'Arguments' : [].slice.call(message, 1) || '',
  15064. 'Element' : element,
  15065. 'Execution Time' : executionTime
  15066. });
  15067. }
  15068. clearTimeout(module.performance.timer);
  15069. module.performance.timer = setTimeout(module.performance.display, 500);
  15070. },
  15071. display: function() {
  15072. var
  15073. title = settings.name + ':',
  15074. totalTime = 0
  15075. ;
  15076. time = false;
  15077. clearTimeout(module.performance.timer);
  15078. $.each(performance, function(index, data) {
  15079. totalTime += data['Execution Time'];
  15080. });
  15081. title += ' ' + totalTime + 'ms';
  15082. if(moduleSelector) {
  15083. title += ' \'' + moduleSelector + '\'';
  15084. }
  15085. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  15086. console.groupCollapsed(title);
  15087. if(console.table) {
  15088. console.table(performance);
  15089. }
  15090. else {
  15091. $.each(performance, function(index, data) {
  15092. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  15093. });
  15094. }
  15095. console.groupEnd();
  15096. }
  15097. performance = [];
  15098. }
  15099. },
  15100. invoke: function(query, passedArguments, context) {
  15101. var
  15102. object = instance,
  15103. maxDepth,
  15104. found,
  15105. response
  15106. ;
  15107. passedArguments = passedArguments || queryArguments;
  15108. context = element || context;
  15109. if(typeof query == 'string' && object !== undefined) {
  15110. query = query.split(/[\. ]/);
  15111. maxDepth = query.length - 1;
  15112. $.each(query, function(depth, value) {
  15113. var camelCaseValue = (depth != maxDepth)
  15114. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  15115. : query
  15116. ;
  15117. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  15118. object = object[camelCaseValue];
  15119. }
  15120. else if( object[camelCaseValue] !== undefined ) {
  15121. found = object[camelCaseValue];
  15122. return false;
  15123. }
  15124. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  15125. object = object[value];
  15126. }
  15127. else if( object[value] !== undefined ) {
  15128. found = object[value];
  15129. return false;
  15130. }
  15131. else {
  15132. module.error(error.method, query);
  15133. return false;
  15134. }
  15135. });
  15136. }
  15137. if ( $.isFunction( found ) ) {
  15138. response = found.apply(context, passedArguments);
  15139. }
  15140. else if(found !== undefined) {
  15141. response = found;
  15142. }
  15143. if($.isArray(returnedValue)) {
  15144. returnedValue.push(response);
  15145. }
  15146. else if(returnedValue !== undefined) {
  15147. returnedValue = [returnedValue, response];
  15148. }
  15149. else if(response !== undefined) {
  15150. returnedValue = response;
  15151. }
  15152. return found;
  15153. }
  15154. }
  15155. ;
  15156. if(methodInvoked) {
  15157. if(instance === undefined) {
  15158. module.initialize();
  15159. }
  15160. module.invoke(query);
  15161. }
  15162. else {
  15163. if(instance !== undefined) {
  15164. module.invoke('destroy');
  15165. }
  15166. module.initialize();
  15167. }
  15168. });
  15169. return (returnedValue !== undefined)
  15170. ? returnedValue
  15171. : this
  15172. ;
  15173. };
  15174. $.fn.sidebar.settings = {
  15175. name : 'Sidebar',
  15176. namespace : 'sidebar',
  15177. silent : false,
  15178. debug : false,
  15179. verbose : false,
  15180. performance : true,
  15181. transition : 'auto',
  15182. mobileTransition : 'auto',
  15183. defaultTransition : {
  15184. computer: {
  15185. left : 'uncover',
  15186. right : 'uncover',
  15187. top : 'overlay',
  15188. bottom : 'overlay'
  15189. },
  15190. mobile: {
  15191. left : 'uncover',
  15192. right : 'uncover',
  15193. top : 'overlay',
  15194. bottom : 'overlay'
  15195. }
  15196. },
  15197. context : 'body',
  15198. exclusive : false,
  15199. closable : true,
  15200. dimPage : true,
  15201. scrollLock : false,
  15202. returnScroll : false,
  15203. delaySetup : false,
  15204. duration : 500,
  15205. onChange : function(){},
  15206. onShow : function(){},
  15207. onHide : function(){},
  15208. onHidden : function(){},
  15209. onVisible : function(){},
  15210. className : {
  15211. active : 'active',
  15212. animating : 'animating',
  15213. dimmed : 'dimmed',
  15214. ios : 'ios',
  15215. pushable : 'pushable',
  15216. pushed : 'pushed',
  15217. right : 'right',
  15218. top : 'top',
  15219. left : 'left',
  15220. bottom : 'bottom',
  15221. visible : 'visible'
  15222. },
  15223. selector: {
  15224. fixed : '.fixed',
  15225. omitted : 'script, link, style, .ui.modal, .ui.dimmer, .ui.nag, .ui.fixed',
  15226. pusher : '.pusher',
  15227. sidebar : '.ui.sidebar'
  15228. },
  15229. regExp: {
  15230. ios : /(iPad|iPhone|iPod)/g,
  15231. mobileChrome : /(CriOS)/g,
  15232. mobile : /Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/g
  15233. },
  15234. error : {
  15235. method : 'The method you called is not defined.',
  15236. pusher : 'Had to add pusher element. For optimal performance make sure body content is inside a pusher element',
  15237. movedSidebar : 'Had to move sidebar. For optimal performance make sure sidebar and pusher are direct children of your body tag',
  15238. overlay : 'The overlay setting is no longer supported, use animation: overlay',
  15239. notFound : 'There were no elements that matched the specified selector'
  15240. }
  15241. };
  15242. })( jQuery, window, document );
  15243. /*!
  15244. * # Semantic UI 2.2.6 - Sticky
  15245. * http://github.com/semantic-org/semantic-ui/
  15246. *
  15247. *
  15248. * Released under the MIT license
  15249. * http://opensource.org/licenses/MIT
  15250. *
  15251. */
  15252. ;(function ($, window, document, undefined) {
  15253. "use strict";
  15254. window = (typeof window != 'undefined' && window.Math == Math)
  15255. ? window
  15256. : (typeof self != 'undefined' && self.Math == Math)
  15257. ? self
  15258. : Function('return this')()
  15259. ;
  15260. $.fn.sticky = function(parameters) {
  15261. var
  15262. $allModules = $(this),
  15263. moduleSelector = $allModules.selector || '',
  15264. time = new Date().getTime(),
  15265. performance = [],
  15266. query = arguments[0],
  15267. methodInvoked = (typeof query == 'string'),
  15268. queryArguments = [].slice.call(arguments, 1),
  15269. returnedValue
  15270. ;
  15271. $allModules
  15272. .each(function() {
  15273. var
  15274. settings = ( $.isPlainObject(parameters) )
  15275. ? $.extend(true, {}, $.fn.sticky.settings, parameters)
  15276. : $.extend({}, $.fn.sticky.settings),
  15277. className = settings.className,
  15278. namespace = settings.namespace,
  15279. error = settings.error,
  15280. eventNamespace = '.' + namespace,
  15281. moduleNamespace = 'module-' + namespace,
  15282. $module = $(this),
  15283. $window = $(window),
  15284. $scroll = $(settings.scrollContext),
  15285. $container,
  15286. $context,
  15287. selector = $module.selector || '',
  15288. instance = $module.data(moduleNamespace),
  15289. requestAnimationFrame = window.requestAnimationFrame
  15290. || window.mozRequestAnimationFrame
  15291. || window.webkitRequestAnimationFrame
  15292. || window.msRequestAnimationFrame
  15293. || function(callback) { setTimeout(callback, 0); },
  15294. element = this,
  15295. documentObserver,
  15296. observer,
  15297. module
  15298. ;
  15299. module = {
  15300. initialize: function() {
  15301. module.determineContainer();
  15302. module.determineContext();
  15303. module.verbose('Initializing sticky', settings, $container);
  15304. module.save.positions();
  15305. module.checkErrors();
  15306. module.bind.events();
  15307. if(settings.observeChanges) {
  15308. module.observeChanges();
  15309. }
  15310. module.instantiate();
  15311. },
  15312. instantiate: function() {
  15313. module.verbose('Storing instance of module', module);
  15314. instance = module;
  15315. $module
  15316. .data(moduleNamespace, module)
  15317. ;
  15318. },
  15319. destroy: function() {
  15320. module.verbose('Destroying previous instance');
  15321. module.reset();
  15322. if(documentObserver) {
  15323. documentObserver.disconnect();
  15324. }
  15325. if(observer) {
  15326. observer.disconnect();
  15327. }
  15328. $window
  15329. .off('load' + eventNamespace, module.event.load)
  15330. .off('resize' + eventNamespace, module.event.resize)
  15331. ;
  15332. $scroll
  15333. .off('scrollchange' + eventNamespace, module.event.scrollchange)
  15334. ;
  15335. $module.removeData(moduleNamespace);
  15336. },
  15337. observeChanges: function() {
  15338. if('MutationObserver' in window) {
  15339. documentObserver = new MutationObserver(module.event.documentChanged);
  15340. observer = new MutationObserver(module.event.changed);
  15341. documentObserver.observe(document, {
  15342. childList : true,
  15343. subtree : true
  15344. });
  15345. observer.observe(element, {
  15346. childList : true,
  15347. subtree : true
  15348. });
  15349. observer.observe($context[0], {
  15350. childList : true,
  15351. subtree : true
  15352. });
  15353. module.debug('Setting up mutation observer', observer);
  15354. }
  15355. },
  15356. determineContainer: function() {
  15357. if(settings.container) {
  15358. $container = $(settings.container);
  15359. }
  15360. else {
  15361. $container = $module.offsetParent();
  15362. }
  15363. },
  15364. determineContext: function() {
  15365. if(settings.context) {
  15366. $context = $(settings.context);
  15367. }
  15368. else {
  15369. $context = $container;
  15370. }
  15371. if($context.length === 0) {
  15372. module.error(error.invalidContext, settings.context, $module);
  15373. return;
  15374. }
  15375. },
  15376. checkErrors: function() {
  15377. if( module.is.hidden() ) {
  15378. module.error(error.visible, $module);
  15379. }
  15380. if(module.cache.element.height > module.cache.context.height) {
  15381. module.reset();
  15382. module.error(error.elementSize, $module);
  15383. return;
  15384. }
  15385. },
  15386. bind: {
  15387. events: function() {
  15388. $window
  15389. .on('load' + eventNamespace, module.event.load)
  15390. .on('resize' + eventNamespace, module.event.resize)
  15391. ;
  15392. // pub/sub pattern
  15393. $scroll
  15394. .off('scroll' + eventNamespace)
  15395. .on('scroll' + eventNamespace, module.event.scroll)
  15396. .on('scrollchange' + eventNamespace, module.event.scrollchange)
  15397. ;
  15398. }
  15399. },
  15400. event: {
  15401. changed: function(mutations) {
  15402. clearTimeout(module.timer);
  15403. module.timer = setTimeout(function() {
  15404. module.verbose('DOM tree modified, updating sticky menu', mutations);
  15405. module.refresh();
  15406. }, 100);
  15407. },
  15408. documentChanged: function(mutations) {
  15409. [].forEach.call(mutations, function(mutation) {
  15410. if(mutation.removedNodes) {
  15411. [].forEach.call(mutation.removedNodes, function(node) {
  15412. if(node == element || $(node).find(element).length > 0) {
  15413. module.debug('Element removed from DOM, tearing down events');
  15414. module.destroy();
  15415. }
  15416. });
  15417. }
  15418. });
  15419. },
  15420. load: function() {
  15421. module.verbose('Page contents finished loading');
  15422. requestAnimationFrame(module.refresh);
  15423. },
  15424. resize: function() {
  15425. module.verbose('Window resized');
  15426. requestAnimationFrame(module.refresh);
  15427. },
  15428. scroll: function() {
  15429. requestAnimationFrame(function() {
  15430. $scroll.triggerHandler('scrollchange' + eventNamespace, $scroll.scrollTop() );
  15431. });
  15432. },
  15433. scrollchange: function(event, scrollPosition) {
  15434. module.stick(scrollPosition);
  15435. settings.onScroll.call(element);
  15436. }
  15437. },
  15438. refresh: function(hardRefresh) {
  15439. module.reset();
  15440. if(!settings.context) {
  15441. module.determineContext();
  15442. }
  15443. if(hardRefresh) {
  15444. module.determineContainer();
  15445. }
  15446. module.save.positions();
  15447. module.stick();
  15448. settings.onReposition.call(element);
  15449. },
  15450. supports: {
  15451. sticky: function() {
  15452. var
  15453. $element = $('<div/>'),
  15454. element = $element[0]
  15455. ;
  15456. $element.addClass(className.supported);
  15457. return($element.css('position').match('sticky'));
  15458. }
  15459. },
  15460. save: {
  15461. lastScroll: function(scroll) {
  15462. module.lastScroll = scroll;
  15463. },
  15464. elementScroll: function(scroll) {
  15465. module.elementScroll = scroll;
  15466. },
  15467. positions: function() {
  15468. var
  15469. scrollContext = {
  15470. height : $scroll.height()
  15471. },
  15472. element = {
  15473. margin: {
  15474. top : parseInt($module.css('margin-top'), 10),
  15475. bottom : parseInt($module.css('margin-bottom'), 10),
  15476. },
  15477. offset : $module.offset(),
  15478. width : $module.outerWidth(),
  15479. height : $module.outerHeight()
  15480. },
  15481. context = {
  15482. offset : $context.offset(),
  15483. height : $context.outerHeight()
  15484. },
  15485. container = {
  15486. height: $container.outerHeight()
  15487. }
  15488. ;
  15489. if( !module.is.standardScroll() ) {
  15490. module.debug('Non-standard scroll. Removing scroll offset from element offset');
  15491. scrollContext.top = $scroll.scrollTop();
  15492. scrollContext.left = $scroll.scrollLeft();
  15493. element.offset.top += scrollContext.top;
  15494. context.offset.top += scrollContext.top;
  15495. element.offset.left += scrollContext.left;
  15496. context.offset.left += scrollContext.left;
  15497. }
  15498. module.cache = {
  15499. fits : ( element.height < scrollContext.height ),
  15500. scrollContext : {
  15501. height : scrollContext.height
  15502. },
  15503. element: {
  15504. margin : element.margin,
  15505. top : element.offset.top - element.margin.top,
  15506. left : element.offset.left,
  15507. width : element.width,
  15508. height : element.height,
  15509. bottom : element.offset.top + element.height
  15510. },
  15511. context: {
  15512. top : context.offset.top,
  15513. height : context.height,
  15514. bottom : context.offset.top + context.height
  15515. }
  15516. };
  15517. module.set.containerSize();
  15518. module.set.size();
  15519. module.stick();
  15520. module.debug('Caching element positions', module.cache);
  15521. }
  15522. },
  15523. get: {
  15524. direction: function(scroll) {
  15525. var
  15526. direction = 'down'
  15527. ;
  15528. scroll = scroll || $scroll.scrollTop();
  15529. if(module.lastScroll !== undefined) {
  15530. if(module.lastScroll < scroll) {
  15531. direction = 'down';
  15532. }
  15533. else if(module.lastScroll > scroll) {
  15534. direction = 'up';
  15535. }
  15536. }
  15537. return direction;
  15538. },
  15539. scrollChange: function(scroll) {
  15540. scroll = scroll || $scroll.scrollTop();
  15541. return (module.lastScroll)
  15542. ? (scroll - module.lastScroll)
  15543. : 0
  15544. ;
  15545. },
  15546. currentElementScroll: function() {
  15547. if(module.elementScroll) {
  15548. return module.elementScroll;
  15549. }
  15550. return ( module.is.top() )
  15551. ? Math.abs(parseInt($module.css('top'), 10)) || 0
  15552. : Math.abs(parseInt($module.css('bottom'), 10)) || 0
  15553. ;
  15554. },
  15555. elementScroll: function(scroll) {
  15556. scroll = scroll || $scroll.scrollTop();
  15557. var
  15558. element = module.cache.element,
  15559. scrollContext = module.cache.scrollContext,
  15560. delta = module.get.scrollChange(scroll),
  15561. maxScroll = (element.height - scrollContext.height + settings.offset),
  15562. elementScroll = module.get.currentElementScroll(),
  15563. possibleScroll = (elementScroll + delta)
  15564. ;
  15565. if(module.cache.fits || possibleScroll < 0) {
  15566. elementScroll = 0;
  15567. }
  15568. else if(possibleScroll > maxScroll ) {
  15569. elementScroll = maxScroll;
  15570. }
  15571. else {
  15572. elementScroll = possibleScroll;
  15573. }
  15574. return elementScroll;
  15575. }
  15576. },
  15577. remove: {
  15578. lastScroll: function() {
  15579. delete module.lastScroll;
  15580. },
  15581. elementScroll: function(scroll) {
  15582. delete module.elementScroll;
  15583. },
  15584. offset: function() {
  15585. $module.css('margin-top', '');
  15586. }
  15587. },
  15588. set: {
  15589. offset: function() {
  15590. module.verbose('Setting offset on element', settings.offset);
  15591. $module
  15592. .css('margin-top', settings.offset)
  15593. ;
  15594. },
  15595. containerSize: function() {
  15596. var
  15597. tagName = $container.get(0).tagName
  15598. ;
  15599. if(tagName === 'HTML' || tagName == 'body') {
  15600. // this can trigger for too many reasons
  15601. //module.error(error.container, tagName, $module);
  15602. module.determineContainer();
  15603. }
  15604. else {
  15605. if( Math.abs($container.outerHeight() - module.cache.context.height) > settings.jitter) {
  15606. module.debug('Context has padding, specifying exact height for container', module.cache.context.height);
  15607. $container.css({
  15608. height: module.cache.context.height
  15609. });
  15610. }
  15611. }
  15612. },
  15613. minimumSize: function() {
  15614. var
  15615. element = module.cache.element
  15616. ;
  15617. $container
  15618. .css('min-height', element.height)
  15619. ;
  15620. },
  15621. scroll: function(scroll) {
  15622. module.debug('Setting scroll on element', scroll);
  15623. if(module.elementScroll == scroll) {
  15624. return;
  15625. }
  15626. if( module.is.top() ) {
  15627. $module
  15628. .css('bottom', '')
  15629. .css('top', -scroll)
  15630. ;
  15631. }
  15632. if( module.is.bottom() ) {
  15633. $module
  15634. .css('top', '')
  15635. .css('bottom', scroll)
  15636. ;
  15637. }
  15638. },
  15639. size: function() {
  15640. if(module.cache.element.height !== 0 && module.cache.element.width !== 0) {
  15641. element.style.setProperty('width', module.cache.element.width + 'px', 'important');
  15642. element.style.setProperty('height', module.cache.element.height + 'px', 'important');
  15643. }
  15644. }
  15645. },
  15646. is: {
  15647. standardScroll: function() {
  15648. return ($scroll[0] == window);
  15649. },
  15650. top: function() {
  15651. return $module.hasClass(className.top);
  15652. },
  15653. bottom: function() {
  15654. return $module.hasClass(className.bottom);
  15655. },
  15656. initialPosition: function() {
  15657. return (!module.is.fixed() && !module.is.bound());
  15658. },
  15659. hidden: function() {
  15660. return (!$module.is(':visible'));
  15661. },
  15662. bound: function() {
  15663. return $module.hasClass(className.bound);
  15664. },
  15665. fixed: function() {
  15666. return $module.hasClass(className.fixed);
  15667. }
  15668. },
  15669. stick: function(scroll) {
  15670. var
  15671. cachedPosition = scroll || $scroll.scrollTop(),
  15672. cache = module.cache,
  15673. fits = cache.fits,
  15674. element = cache.element,
  15675. scrollContext = cache.scrollContext,
  15676. context = cache.context,
  15677. offset = (module.is.bottom() && settings.pushing)
  15678. ? settings.bottomOffset
  15679. : settings.offset,
  15680. scroll = {
  15681. top : cachedPosition + offset,
  15682. bottom : cachedPosition + offset + scrollContext.height
  15683. },
  15684. direction = module.get.direction(scroll.top),
  15685. elementScroll = (fits)
  15686. ? 0
  15687. : module.get.elementScroll(scroll.top),
  15688. // shorthand
  15689. doesntFit = !fits,
  15690. elementVisible = (element.height !== 0)
  15691. ;
  15692. if(elementVisible) {
  15693. if( module.is.initialPosition() ) {
  15694. if(scroll.top >= context.bottom) {
  15695. module.debug('Initial element position is bottom of container');
  15696. module.bindBottom();
  15697. }
  15698. else if(scroll.top > element.top) {
  15699. if( (element.height + scroll.top - elementScroll) >= context.bottom ) {
  15700. module.debug('Initial element position is bottom of container');
  15701. module.bindBottom();
  15702. }
  15703. else {
  15704. module.debug('Initial element position is fixed');
  15705. module.fixTop();
  15706. }
  15707. }
  15708. }
  15709. else if( module.is.fixed() ) {
  15710. // currently fixed top
  15711. if( module.is.top() ) {
  15712. if( scroll.top <= element.top ) {
  15713. module.debug('Fixed element reached top of container');
  15714. module.setInitialPosition();
  15715. }
  15716. else if( (element.height + scroll.top - elementScroll) >= context.bottom ) {
  15717. module.debug('Fixed element reached bottom of container');
  15718. module.bindBottom();
  15719. }
  15720. // scroll element if larger than screen
  15721. else if(doesntFit) {
  15722. module.set.scroll(elementScroll);
  15723. module.save.lastScroll(scroll.top);
  15724. module.save.elementScroll(elementScroll);
  15725. }
  15726. }
  15727. // currently fixed bottom
  15728. else if(module.is.bottom() ) {
  15729. // top edge
  15730. if( (scroll.bottom - element.height) <= element.top) {
  15731. module.debug('Bottom fixed rail has reached top of container');
  15732. module.setInitialPosition();
  15733. }
  15734. // bottom edge
  15735. else if(scroll.bottom >= context.bottom) {
  15736. module.debug('Bottom fixed rail has reached bottom of container');
  15737. module.bindBottom();
  15738. }
  15739. // scroll element if larger than screen
  15740. else if(doesntFit) {
  15741. module.set.scroll(elementScroll);
  15742. module.save.lastScroll(scroll.top);
  15743. module.save.elementScroll(elementScroll);
  15744. }
  15745. }
  15746. }
  15747. else if( module.is.bottom() ) {
  15748. if( scroll.top <= element.top ) {
  15749. module.debug('Jumped from bottom fixed to top fixed, most likely used home/end button');
  15750. module.setInitialPosition();
  15751. }
  15752. else {
  15753. if(settings.pushing) {
  15754. if(module.is.bound() && scroll.bottom <= context.bottom ) {
  15755. module.debug('Fixing bottom attached element to bottom of browser.');
  15756. module.fixBottom();
  15757. }
  15758. }
  15759. else {
  15760. if(module.is.bound() && (scroll.top <= context.bottom - element.height) ) {
  15761. module.debug('Fixing bottom attached element to top of browser.');
  15762. module.fixTop();
  15763. }
  15764. }
  15765. }
  15766. }
  15767. }
  15768. },
  15769. bindTop: function() {
  15770. module.debug('Binding element to top of parent container');
  15771. module.remove.offset();
  15772. $module
  15773. .css({
  15774. left : '',
  15775. top : '',
  15776. marginBottom : ''
  15777. })
  15778. .removeClass(className.fixed)
  15779. .removeClass(className.bottom)
  15780. .addClass(className.bound)
  15781. .addClass(className.top)
  15782. ;
  15783. settings.onTop.call(element);
  15784. settings.onUnstick.call(element);
  15785. },
  15786. bindBottom: function() {
  15787. module.debug('Binding element to bottom of parent container');
  15788. module.remove.offset();
  15789. $module
  15790. .css({
  15791. left : '',
  15792. top : ''
  15793. })
  15794. .removeClass(className.fixed)
  15795. .removeClass(className.top)
  15796. .addClass(className.bound)
  15797. .addClass(className.bottom)
  15798. ;
  15799. settings.onBottom.call(element);
  15800. settings.onUnstick.call(element);
  15801. },
  15802. setInitialPosition: function() {
  15803. module.debug('Returning to initial position');
  15804. module.unfix();
  15805. module.unbind();
  15806. },
  15807. fixTop: function() {
  15808. module.debug('Fixing element to top of page');
  15809. module.set.minimumSize();
  15810. module.set.offset();
  15811. $module
  15812. .css({
  15813. left : module.cache.element.left,
  15814. bottom : '',
  15815. marginBottom : ''
  15816. })
  15817. .removeClass(className.bound)
  15818. .removeClass(className.bottom)
  15819. .addClass(className.fixed)
  15820. .addClass(className.top)
  15821. ;
  15822. settings.onStick.call(element);
  15823. },
  15824. fixBottom: function() {
  15825. module.debug('Sticking element to bottom of page');
  15826. module.set.minimumSize();
  15827. module.set.offset();
  15828. $module
  15829. .css({
  15830. left : module.cache.element.left,
  15831. bottom : '',
  15832. marginBottom : ''
  15833. })
  15834. .removeClass(className.bound)
  15835. .removeClass(className.top)
  15836. .addClass(className.fixed)
  15837. .addClass(className.bottom)
  15838. ;
  15839. settings.onStick.call(element);
  15840. },
  15841. unbind: function() {
  15842. if( module.is.bound() ) {
  15843. module.debug('Removing container bound position on element');
  15844. module.remove.offset();
  15845. $module
  15846. .removeClass(className.bound)
  15847. .removeClass(className.top)
  15848. .removeClass(className.bottom)
  15849. ;
  15850. }
  15851. },
  15852. unfix: function() {
  15853. if( module.is.fixed() ) {
  15854. module.debug('Removing fixed position on element');
  15855. module.remove.offset();
  15856. $module
  15857. .removeClass(className.fixed)
  15858. .removeClass(className.top)
  15859. .removeClass(className.bottom)
  15860. ;
  15861. settings.onUnstick.call(element);
  15862. }
  15863. },
  15864. reset: function() {
  15865. module.debug('Resetting elements position');
  15866. module.unbind();
  15867. module.unfix();
  15868. module.resetCSS();
  15869. module.remove.offset();
  15870. module.remove.lastScroll();
  15871. },
  15872. resetCSS: function() {
  15873. $module
  15874. .css({
  15875. width : '',
  15876. height : ''
  15877. })
  15878. ;
  15879. $container
  15880. .css({
  15881. height: ''
  15882. })
  15883. ;
  15884. },
  15885. setting: function(name, value) {
  15886. if( $.isPlainObject(name) ) {
  15887. $.extend(true, settings, name);
  15888. }
  15889. else if(value !== undefined) {
  15890. settings[name] = value;
  15891. }
  15892. else {
  15893. return settings[name];
  15894. }
  15895. },
  15896. internal: function(name, value) {
  15897. if( $.isPlainObject(name) ) {
  15898. $.extend(true, module, name);
  15899. }
  15900. else if(value !== undefined) {
  15901. module[name] = value;
  15902. }
  15903. else {
  15904. return module[name];
  15905. }
  15906. },
  15907. debug: function() {
  15908. if(!settings.silent && settings.debug) {
  15909. if(settings.performance) {
  15910. module.performance.log(arguments);
  15911. }
  15912. else {
  15913. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  15914. module.debug.apply(console, arguments);
  15915. }
  15916. }
  15917. },
  15918. verbose: function() {
  15919. if(!settings.silent && settings.verbose && settings.debug) {
  15920. if(settings.performance) {
  15921. module.performance.log(arguments);
  15922. }
  15923. else {
  15924. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  15925. module.verbose.apply(console, arguments);
  15926. }
  15927. }
  15928. },
  15929. error: function() {
  15930. if(!settings.silent) {
  15931. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  15932. module.error.apply(console, arguments);
  15933. }
  15934. },
  15935. performance: {
  15936. log: function(message) {
  15937. var
  15938. currentTime,
  15939. executionTime,
  15940. previousTime
  15941. ;
  15942. if(settings.performance) {
  15943. currentTime = new Date().getTime();
  15944. previousTime = time || currentTime;
  15945. executionTime = currentTime - previousTime;
  15946. time = currentTime;
  15947. performance.push({
  15948. 'Name' : message[0],
  15949. 'Arguments' : [].slice.call(message, 1) || '',
  15950. 'Element' : element,
  15951. 'Execution Time' : executionTime
  15952. });
  15953. }
  15954. clearTimeout(module.performance.timer);
  15955. module.performance.timer = setTimeout(module.performance.display, 0);
  15956. },
  15957. display: function() {
  15958. var
  15959. title = settings.name + ':',
  15960. totalTime = 0
  15961. ;
  15962. time = false;
  15963. clearTimeout(module.performance.timer);
  15964. $.each(performance, function(index, data) {
  15965. totalTime += data['Execution Time'];
  15966. });
  15967. title += ' ' + totalTime + 'ms';
  15968. if(moduleSelector) {
  15969. title += ' \'' + moduleSelector + '\'';
  15970. }
  15971. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  15972. console.groupCollapsed(title);
  15973. if(console.table) {
  15974. console.table(performance);
  15975. }
  15976. else {
  15977. $.each(performance, function(index, data) {
  15978. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  15979. });
  15980. }
  15981. console.groupEnd();
  15982. }
  15983. performance = [];
  15984. }
  15985. },
  15986. invoke: function(query, passedArguments, context) {
  15987. var
  15988. object = instance,
  15989. maxDepth,
  15990. found,
  15991. response
  15992. ;
  15993. passedArguments = passedArguments || queryArguments;
  15994. context = element || context;
  15995. if(typeof query == 'string' && object !== undefined) {
  15996. query = query.split(/[\. ]/);
  15997. maxDepth = query.length - 1;
  15998. $.each(query, function(depth, value) {
  15999. var camelCaseValue = (depth != maxDepth)
  16000. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  16001. : query
  16002. ;
  16003. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  16004. object = object[camelCaseValue];
  16005. }
  16006. else if( object[camelCaseValue] !== undefined ) {
  16007. found = object[camelCaseValue];
  16008. return false;
  16009. }
  16010. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  16011. object = object[value];
  16012. }
  16013. else if( object[value] !== undefined ) {
  16014. found = object[value];
  16015. return false;
  16016. }
  16017. else {
  16018. return false;
  16019. }
  16020. });
  16021. }
  16022. if ( $.isFunction( found ) ) {
  16023. response = found.apply(context, passedArguments);
  16024. }
  16025. else if(found !== undefined) {
  16026. response = found;
  16027. }
  16028. if($.isArray(returnedValue)) {
  16029. returnedValue.push(response);
  16030. }
  16031. else if(returnedValue !== undefined) {
  16032. returnedValue = [returnedValue, response];
  16033. }
  16034. else if(response !== undefined) {
  16035. returnedValue = response;
  16036. }
  16037. return found;
  16038. }
  16039. };
  16040. if(methodInvoked) {
  16041. if(instance === undefined) {
  16042. module.initialize();
  16043. }
  16044. module.invoke(query);
  16045. }
  16046. else {
  16047. if(instance !== undefined) {
  16048. instance.invoke('destroy');
  16049. }
  16050. module.initialize();
  16051. }
  16052. })
  16053. ;
  16054. return (returnedValue !== undefined)
  16055. ? returnedValue
  16056. : this
  16057. ;
  16058. };
  16059. $.fn.sticky.settings = {
  16060. name : 'Sticky',
  16061. namespace : 'sticky',
  16062. silent : false,
  16063. debug : false,
  16064. verbose : true,
  16065. performance : true,
  16066. // whether to stick in the opposite direction on scroll up
  16067. pushing : false,
  16068. context : false,
  16069. container : false,
  16070. // Context to watch scroll events
  16071. scrollContext : window,
  16072. // Offset to adjust scroll
  16073. offset : 0,
  16074. // Offset to adjust scroll when attached to bottom of screen
  16075. bottomOffset : 0,
  16076. jitter : 5, // will only set container height if difference between context and container is larger than this number
  16077. // Whether to automatically observe changes with Mutation Observers
  16078. observeChanges : false,
  16079. // Called when position is recalculated
  16080. onReposition : function(){},
  16081. // Called on each scroll
  16082. onScroll : function(){},
  16083. // Called when element is stuck to viewport
  16084. onStick : function(){},
  16085. // Called when element is unstuck from viewport
  16086. onUnstick : function(){},
  16087. // Called when element reaches top of context
  16088. onTop : function(){},
  16089. // Called when element reaches bottom of context
  16090. onBottom : function(){},
  16091. error : {
  16092. container : 'Sticky element must be inside a relative container',
  16093. visible : 'Element is hidden, you must call refresh after element becomes visible. Use silent setting to surpress this warning in production.',
  16094. method : 'The method you called is not defined.',
  16095. invalidContext : 'Context specified does not exist',
  16096. elementSize : 'Sticky element is larger than its container, cannot create sticky.'
  16097. },
  16098. className : {
  16099. bound : 'bound',
  16100. fixed : 'fixed',
  16101. supported : 'native',
  16102. top : 'top',
  16103. bottom : 'bottom'
  16104. }
  16105. };
  16106. })( jQuery, window, document );
  16107. /*!
  16108. * # Semantic UI 2.2.6 - Tab
  16109. * http://github.com/semantic-org/semantic-ui/
  16110. *
  16111. *
  16112. * Released under the MIT license
  16113. * http://opensource.org/licenses/MIT
  16114. *
  16115. */
  16116. ;(function ($, window, document, undefined) {
  16117. "use strict";
  16118. window = (typeof window != 'undefined' && window.Math == Math)
  16119. ? window
  16120. : (typeof self != 'undefined' && self.Math == Math)
  16121. ? self
  16122. : Function('return this')()
  16123. ;
  16124. $.fn.tab = function(parameters) {
  16125. var
  16126. // use window context if none specified
  16127. $allModules = $.isFunction(this)
  16128. ? $(window)
  16129. : $(this),
  16130. moduleSelector = $allModules.selector || '',
  16131. time = new Date().getTime(),
  16132. performance = [],
  16133. query = arguments[0],
  16134. methodInvoked = (typeof query == 'string'),
  16135. queryArguments = [].slice.call(arguments, 1),
  16136. initializedHistory = false,
  16137. returnedValue
  16138. ;
  16139. $allModules
  16140. .each(function() {
  16141. var
  16142. settings = ( $.isPlainObject(parameters) )
  16143. ? $.extend(true, {}, $.fn.tab.settings, parameters)
  16144. : $.extend({}, $.fn.tab.settings),
  16145. className = settings.className,
  16146. metadata = settings.metadata,
  16147. selector = settings.selector,
  16148. error = settings.error,
  16149. eventNamespace = '.' + settings.namespace,
  16150. moduleNamespace = 'module-' + settings.namespace,
  16151. $module = $(this),
  16152. $context,
  16153. $tabs,
  16154. cache = {},
  16155. firstLoad = true,
  16156. recursionDepth = 0,
  16157. element = this,
  16158. instance = $module.data(moduleNamespace),
  16159. activeTabPath,
  16160. parameterArray,
  16161. module,
  16162. historyEvent
  16163. ;
  16164. module = {
  16165. initialize: function() {
  16166. module.debug('Initializing tab menu item', $module);
  16167. module.fix.callbacks();
  16168. module.determineTabs();
  16169. module.debug('Determining tabs', settings.context, $tabs);
  16170. // set up automatic routing
  16171. if(settings.auto) {
  16172. module.set.auto();
  16173. }
  16174. module.bind.events();
  16175. if(settings.history && !initializedHistory) {
  16176. module.initializeHistory();
  16177. initializedHistory = true;
  16178. }
  16179. module.instantiate();
  16180. },
  16181. instantiate: function () {
  16182. module.verbose('Storing instance of module', module);
  16183. instance = module;
  16184. $module
  16185. .data(moduleNamespace, module)
  16186. ;
  16187. },
  16188. destroy: function() {
  16189. module.debug('Destroying tabs', $module);
  16190. $module
  16191. .removeData(moduleNamespace)
  16192. .off(eventNamespace)
  16193. ;
  16194. },
  16195. bind: {
  16196. events: function() {
  16197. // if using $.tab don't add events
  16198. if( !$.isWindow( element ) ) {
  16199. module.debug('Attaching tab activation events to element', $module);
  16200. $module
  16201. .on('click' + eventNamespace, module.event.click)
  16202. ;
  16203. }
  16204. }
  16205. },
  16206. determineTabs: function() {
  16207. var
  16208. $reference
  16209. ;
  16210. // determine tab context
  16211. if(settings.context === 'parent') {
  16212. if($module.closest(selector.ui).length > 0) {
  16213. $reference = $module.closest(selector.ui);
  16214. module.verbose('Using closest UI element as parent', $reference);
  16215. }
  16216. else {
  16217. $reference = $module;
  16218. }
  16219. $context = $reference.parent();
  16220. module.verbose('Determined parent element for creating context', $context);
  16221. }
  16222. else if(settings.context) {
  16223. $context = $(settings.context);
  16224. module.verbose('Using selector for tab context', settings.context, $context);
  16225. }
  16226. else {
  16227. $context = $('body');
  16228. }
  16229. // find tabs
  16230. if(settings.childrenOnly) {
  16231. $tabs = $context.children(selector.tabs);
  16232. module.debug('Searching tab context children for tabs', $context, $tabs);
  16233. }
  16234. else {
  16235. $tabs = $context.find(selector.tabs);
  16236. module.debug('Searching tab context for tabs', $context, $tabs);
  16237. }
  16238. },
  16239. fix: {
  16240. callbacks: function() {
  16241. if( $.isPlainObject(parameters) && (parameters.onTabLoad || parameters.onTabInit) ) {
  16242. if(parameters.onTabLoad) {
  16243. parameters.onLoad = parameters.onTabLoad;
  16244. delete parameters.onTabLoad;
  16245. module.error(error.legacyLoad, parameters.onLoad);
  16246. }
  16247. if(parameters.onTabInit) {
  16248. parameters.onFirstLoad = parameters.onTabInit;
  16249. delete parameters.onTabInit;
  16250. module.error(error.legacyInit, parameters.onFirstLoad);
  16251. }
  16252. settings = $.extend(true, {}, $.fn.tab.settings, parameters);
  16253. }
  16254. }
  16255. },
  16256. initializeHistory: function() {
  16257. module.debug('Initializing page state');
  16258. if( $.address === undefined ) {
  16259. module.error(error.state);
  16260. return false;
  16261. }
  16262. else {
  16263. if(settings.historyType == 'state') {
  16264. module.debug('Using HTML5 to manage state');
  16265. if(settings.path !== false) {
  16266. $.address
  16267. .history(true)
  16268. .state(settings.path)
  16269. ;
  16270. }
  16271. else {
  16272. module.error(error.path);
  16273. return false;
  16274. }
  16275. }
  16276. $.address
  16277. .bind('change', module.event.history.change)
  16278. ;
  16279. }
  16280. },
  16281. event: {
  16282. click: function(event) {
  16283. var
  16284. tabPath = $(this).data(metadata.tab)
  16285. ;
  16286. if(tabPath !== undefined) {
  16287. if(settings.history) {
  16288. module.verbose('Updating page state', event);
  16289. $.address.value(tabPath);
  16290. }
  16291. else {
  16292. module.verbose('Changing tab', event);
  16293. module.changeTab(tabPath);
  16294. }
  16295. event.preventDefault();
  16296. }
  16297. else {
  16298. module.debug('No tab specified');
  16299. }
  16300. },
  16301. history: {
  16302. change: function(event) {
  16303. var
  16304. tabPath = event.pathNames.join('/') || module.get.initialPath(),
  16305. pageTitle = settings.templates.determineTitle(tabPath) || false
  16306. ;
  16307. module.performance.display();
  16308. module.debug('History change event', tabPath, event);
  16309. historyEvent = event;
  16310. if(tabPath !== undefined) {
  16311. module.changeTab(tabPath);
  16312. }
  16313. if(pageTitle) {
  16314. $.address.title(pageTitle);
  16315. }
  16316. }
  16317. }
  16318. },
  16319. refresh: function() {
  16320. if(activeTabPath) {
  16321. module.debug('Refreshing tab', activeTabPath);
  16322. module.changeTab(activeTabPath);
  16323. }
  16324. },
  16325. cache: {
  16326. read: function(cacheKey) {
  16327. return (cacheKey !== undefined)
  16328. ? cache[cacheKey]
  16329. : false
  16330. ;
  16331. },
  16332. add: function(cacheKey, content) {
  16333. cacheKey = cacheKey || activeTabPath;
  16334. module.debug('Adding cached content for', cacheKey);
  16335. cache[cacheKey] = content;
  16336. },
  16337. remove: function(cacheKey) {
  16338. cacheKey = cacheKey || activeTabPath;
  16339. module.debug('Removing cached content for', cacheKey);
  16340. delete cache[cacheKey];
  16341. }
  16342. },
  16343. set: {
  16344. auto: function() {
  16345. var
  16346. url = (typeof settings.path == 'string')
  16347. ? settings.path.replace(/\/$/, '') + '/{$tab}'
  16348. : '/{$tab}'
  16349. ;
  16350. module.verbose('Setting up automatic tab retrieval from server', url);
  16351. if($.isPlainObject(settings.apiSettings)) {
  16352. settings.apiSettings.url = url;
  16353. }
  16354. else {
  16355. settings.apiSettings = {
  16356. url: url
  16357. };
  16358. }
  16359. },
  16360. loading: function(tabPath) {
  16361. var
  16362. $tab = module.get.tabElement(tabPath),
  16363. isLoading = $tab.hasClass(className.loading)
  16364. ;
  16365. if(!isLoading) {
  16366. module.verbose('Setting loading state for', $tab);
  16367. $tab
  16368. .addClass(className.loading)
  16369. .siblings($tabs)
  16370. .removeClass(className.active + ' ' + className.loading)
  16371. ;
  16372. if($tab.length > 0) {
  16373. settings.onRequest.call($tab[0], tabPath);
  16374. }
  16375. }
  16376. },
  16377. state: function(state) {
  16378. $.address.value(state);
  16379. }
  16380. },
  16381. changeTab: function(tabPath) {
  16382. var
  16383. pushStateAvailable = (window.history && window.history.pushState),
  16384. shouldIgnoreLoad = (pushStateAvailable && settings.ignoreFirstLoad && firstLoad),
  16385. remoteContent = (settings.auto || $.isPlainObject(settings.apiSettings) ),
  16386. // only add default path if not remote content
  16387. pathArray = (remoteContent && !shouldIgnoreLoad)
  16388. ? module.utilities.pathToArray(tabPath)
  16389. : module.get.defaultPathArray(tabPath)
  16390. ;
  16391. tabPath = module.utilities.arrayToPath(pathArray);
  16392. $.each(pathArray, function(index, tab) {
  16393. var
  16394. currentPathArray = pathArray.slice(0, index + 1),
  16395. currentPath = module.utilities.arrayToPath(currentPathArray),
  16396. isTab = module.is.tab(currentPath),
  16397. isLastIndex = (index + 1 == pathArray.length),
  16398. $tab = module.get.tabElement(currentPath),
  16399. $anchor,
  16400. nextPathArray,
  16401. nextPath,
  16402. isLastTab
  16403. ;
  16404. module.verbose('Looking for tab', tab);
  16405. if(isTab) {
  16406. module.verbose('Tab was found', tab);
  16407. // scope up
  16408. activeTabPath = currentPath;
  16409. parameterArray = module.utilities.filterArray(pathArray, currentPathArray);
  16410. if(isLastIndex) {
  16411. isLastTab = true;
  16412. }
  16413. else {
  16414. nextPathArray = pathArray.slice(0, index + 2);
  16415. nextPath = module.utilities.arrayToPath(nextPathArray);
  16416. isLastTab = ( !module.is.tab(nextPath) );
  16417. if(isLastTab) {
  16418. module.verbose('Tab parameters found', nextPathArray);
  16419. }
  16420. }
  16421. if(isLastTab && remoteContent) {
  16422. if(!shouldIgnoreLoad) {
  16423. module.activate.navigation(currentPath);
  16424. module.fetch.content(currentPath, tabPath);
  16425. }
  16426. else {
  16427. module.debug('Ignoring remote content on first tab load', currentPath);
  16428. firstLoad = false;
  16429. module.cache.add(tabPath, $tab.html());
  16430. module.activate.all(currentPath);
  16431. settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  16432. settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  16433. }
  16434. return false;
  16435. }
  16436. else {
  16437. module.debug('Opened local tab', currentPath);
  16438. module.activate.all(currentPath);
  16439. if( !module.cache.read(currentPath) ) {
  16440. module.cache.add(currentPath, true);
  16441. module.debug('First time tab loaded calling tab init');
  16442. settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  16443. }
  16444. settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  16445. }
  16446. }
  16447. else if(tabPath.search('/') == -1 && tabPath !== '') {
  16448. // look for in page anchor
  16449. $anchor = $('#' + tabPath + ', a[name="' + tabPath + '"]');
  16450. currentPath = $anchor.closest('[data-tab]').data(metadata.tab);
  16451. $tab = module.get.tabElement(currentPath);
  16452. // if anchor exists use parent tab
  16453. if($anchor && $anchor.length > 0 && currentPath) {
  16454. module.debug('Anchor link used, opening parent tab', $tab, $anchor);
  16455. if( !$tab.hasClass(className.active) ) {
  16456. setTimeout(function() {
  16457. module.scrollTo($anchor);
  16458. }, 0);
  16459. }
  16460. module.activate.all(currentPath);
  16461. if( !module.cache.read(currentPath) ) {
  16462. module.cache.add(currentPath, true);
  16463. module.debug('First time tab loaded calling tab init');
  16464. settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  16465. }
  16466. settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  16467. return false;
  16468. }
  16469. }
  16470. else {
  16471. module.error(error.missingTab, $module, $context, currentPath);
  16472. return false;
  16473. }
  16474. });
  16475. },
  16476. scrollTo: function($element) {
  16477. var
  16478. scrollOffset = ($element && $element.length > 0)
  16479. ? $element.offset().top
  16480. : false
  16481. ;
  16482. if(scrollOffset !== false) {
  16483. module.debug('Forcing scroll to an in-page link in a hidden tab', scrollOffset, $element);
  16484. $(document).scrollTop(scrollOffset);
  16485. }
  16486. },
  16487. update: {
  16488. content: function(tabPath, html, evaluateScripts) {
  16489. var
  16490. $tab = module.get.tabElement(tabPath),
  16491. tab = $tab[0]
  16492. ;
  16493. evaluateScripts = (evaluateScripts !== undefined)
  16494. ? evaluateScripts
  16495. : settings.evaluateScripts
  16496. ;
  16497. if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && typeof html !== 'string') {
  16498. $tab
  16499. .empty()
  16500. .append($(html).clone(true))
  16501. ;
  16502. }
  16503. else {
  16504. if(evaluateScripts) {
  16505. module.debug('Updating HTML and evaluating inline scripts', tabPath, html);
  16506. $tab.html(html);
  16507. }
  16508. else {
  16509. module.debug('Updating HTML', tabPath, html);
  16510. tab.innerHTML = html;
  16511. }
  16512. }
  16513. }
  16514. },
  16515. fetch: {
  16516. content: function(tabPath, fullTabPath) {
  16517. var
  16518. $tab = module.get.tabElement(tabPath),
  16519. apiSettings = {
  16520. dataType : 'html',
  16521. encodeParameters : false,
  16522. on : 'now',
  16523. cache : settings.alwaysRefresh,
  16524. headers : {
  16525. 'X-Remote': true
  16526. },
  16527. onSuccess : function(response) {
  16528. if(settings.cacheType == 'response') {
  16529. module.cache.add(fullTabPath, response);
  16530. }
  16531. module.update.content(tabPath, response);
  16532. if(tabPath == activeTabPath) {
  16533. module.debug('Content loaded', tabPath);
  16534. module.activate.tab(tabPath);
  16535. }
  16536. else {
  16537. module.debug('Content loaded in background', tabPath);
  16538. }
  16539. settings.onFirstLoad.call($tab[0], tabPath, parameterArray, historyEvent);
  16540. settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
  16541. if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && $tab.children().length > 0) {
  16542. setTimeout(function() {
  16543. var
  16544. $clone = $tab.children().clone(true)
  16545. ;
  16546. $clone = $clone.not('script');
  16547. module.cache.add(fullTabPath, $clone);
  16548. }, 0);
  16549. }
  16550. else {
  16551. module.cache.add(fullTabPath, $tab.html());
  16552. }
  16553. },
  16554. urlData: {
  16555. tab: fullTabPath
  16556. }
  16557. },
  16558. request = $tab.api('get request') || false,
  16559. existingRequest = ( request && request.state() === 'pending' ),
  16560. requestSettings,
  16561. cachedContent
  16562. ;
  16563. fullTabPath = fullTabPath || tabPath;
  16564. cachedContent = module.cache.read(fullTabPath);
  16565. if(settings.cache && cachedContent) {
  16566. module.activate.tab(tabPath);
  16567. module.debug('Adding cached content', fullTabPath);
  16568. if(settings.evaluateScripts == 'once') {
  16569. module.update.content(tabPath, cachedContent, false);
  16570. }
  16571. else {
  16572. module.update.content(tabPath, cachedContent);
  16573. }
  16574. settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
  16575. }
  16576. else if(existingRequest) {
  16577. module.set.loading(tabPath);
  16578. module.debug('Content is already loading', fullTabPath);
  16579. }
  16580. else if($.api !== undefined) {
  16581. requestSettings = $.extend(true, {}, settings.apiSettings, apiSettings);
  16582. module.debug('Retrieving remote content', fullTabPath, requestSettings);
  16583. module.set.loading(tabPath);
  16584. $tab.api(requestSettings);
  16585. }
  16586. else {
  16587. module.error(error.api);
  16588. }
  16589. }
  16590. },
  16591. activate: {
  16592. all: function(tabPath) {
  16593. module.activate.tab(tabPath);
  16594. module.activate.navigation(tabPath);
  16595. },
  16596. tab: function(tabPath) {
  16597. var
  16598. $tab = module.get.tabElement(tabPath),
  16599. $deactiveTabs = (settings.deactivate == 'siblings')
  16600. ? $tab.siblings($tabs)
  16601. : $tabs.not($tab),
  16602. isActive = $tab.hasClass(className.active)
  16603. ;
  16604. module.verbose('Showing tab content for', $tab);
  16605. if(!isActive) {
  16606. $tab
  16607. .addClass(className.active)
  16608. ;
  16609. $deactiveTabs
  16610. .removeClass(className.active + ' ' + className.loading)
  16611. ;
  16612. if($tab.length > 0) {
  16613. settings.onVisible.call($tab[0], tabPath);
  16614. }
  16615. }
  16616. },
  16617. navigation: function(tabPath) {
  16618. var
  16619. $navigation = module.get.navElement(tabPath),
  16620. $deactiveNavigation = (settings.deactivate == 'siblings')
  16621. ? $navigation.siblings($allModules)
  16622. : $allModules.not($navigation),
  16623. isActive = $navigation.hasClass(className.active)
  16624. ;
  16625. module.verbose('Activating tab navigation for', $navigation, tabPath);
  16626. if(!isActive) {
  16627. $navigation
  16628. .addClass(className.active)
  16629. ;
  16630. $deactiveNavigation
  16631. .removeClass(className.active + ' ' + className.loading)
  16632. ;
  16633. }
  16634. }
  16635. },
  16636. deactivate: {
  16637. all: function() {
  16638. module.deactivate.navigation();
  16639. module.deactivate.tabs();
  16640. },
  16641. navigation: function() {
  16642. $allModules
  16643. .removeClass(className.active)
  16644. ;
  16645. },
  16646. tabs: function() {
  16647. $tabs
  16648. .removeClass(className.active + ' ' + className.loading)
  16649. ;
  16650. }
  16651. },
  16652. is: {
  16653. tab: function(tabName) {
  16654. return (tabName !== undefined)
  16655. ? ( module.get.tabElement(tabName).length > 0 )
  16656. : false
  16657. ;
  16658. }
  16659. },
  16660. get: {
  16661. initialPath: function() {
  16662. return $allModules.eq(0).data(metadata.tab) || $tabs.eq(0).data(metadata.tab);
  16663. },
  16664. path: function() {
  16665. return $.address.value();
  16666. },
  16667. // adds default tabs to tab path
  16668. defaultPathArray: function(tabPath) {
  16669. return module.utilities.pathToArray( module.get.defaultPath(tabPath) );
  16670. },
  16671. defaultPath: function(tabPath) {
  16672. var
  16673. $defaultNav = $allModules.filter('[data-' + metadata.tab + '^="' + tabPath + '/"]').eq(0),
  16674. defaultTab = $defaultNav.data(metadata.tab) || false
  16675. ;
  16676. if( defaultTab ) {
  16677. module.debug('Found default tab', defaultTab);
  16678. if(recursionDepth < settings.maxDepth) {
  16679. recursionDepth++;
  16680. return module.get.defaultPath(defaultTab);
  16681. }
  16682. module.error(error.recursion);
  16683. }
  16684. else {
  16685. module.debug('No default tabs found for', tabPath, $tabs);
  16686. }
  16687. recursionDepth = 0;
  16688. return tabPath;
  16689. },
  16690. navElement: function(tabPath) {
  16691. tabPath = tabPath || activeTabPath;
  16692. return $allModules.filter('[data-' + metadata.tab + '="' + tabPath + '"]');
  16693. },
  16694. tabElement: function(tabPath) {
  16695. var
  16696. $fullPathTab,
  16697. $simplePathTab,
  16698. tabPathArray,
  16699. lastTab
  16700. ;
  16701. tabPath = tabPath || activeTabPath;
  16702. tabPathArray = module.utilities.pathToArray(tabPath);
  16703. lastTab = module.utilities.last(tabPathArray);
  16704. $fullPathTab = $tabs.filter('[data-' + metadata.tab + '="' + tabPath + '"]');
  16705. $simplePathTab = $tabs.filter('[data-' + metadata.tab + '="' + lastTab + '"]');
  16706. return ($fullPathTab.length > 0)
  16707. ? $fullPathTab
  16708. : $simplePathTab
  16709. ;
  16710. },
  16711. tab: function() {
  16712. return activeTabPath;
  16713. }
  16714. },
  16715. utilities: {
  16716. filterArray: function(keepArray, removeArray) {
  16717. return $.grep(keepArray, function(keepValue) {
  16718. return ( $.inArray(keepValue, removeArray) == -1);
  16719. });
  16720. },
  16721. last: function(array) {
  16722. return $.isArray(array)
  16723. ? array[ array.length - 1]
  16724. : false
  16725. ;
  16726. },
  16727. pathToArray: function(pathName) {
  16728. if(pathName === undefined) {
  16729. pathName = activeTabPath;
  16730. }
  16731. return typeof pathName == 'string'
  16732. ? pathName.split('/')
  16733. : [pathName]
  16734. ;
  16735. },
  16736. arrayToPath: function(pathArray) {
  16737. return $.isArray(pathArray)
  16738. ? pathArray.join('/')
  16739. : false
  16740. ;
  16741. }
  16742. },
  16743. setting: function(name, value) {
  16744. module.debug('Changing setting', name, value);
  16745. if( $.isPlainObject(name) ) {
  16746. $.extend(true, settings, name);
  16747. }
  16748. else if(value !== undefined) {
  16749. if($.isPlainObject(settings[name])) {
  16750. $.extend(true, settings[name], value);
  16751. }
  16752. else {
  16753. settings[name] = value;
  16754. }
  16755. }
  16756. else {
  16757. return settings[name];
  16758. }
  16759. },
  16760. internal: function(name, value) {
  16761. if( $.isPlainObject(name) ) {
  16762. $.extend(true, module, name);
  16763. }
  16764. else if(value !== undefined) {
  16765. module[name] = value;
  16766. }
  16767. else {
  16768. return module[name];
  16769. }
  16770. },
  16771. debug: function() {
  16772. if(!settings.silent && settings.debug) {
  16773. if(settings.performance) {
  16774. module.performance.log(arguments);
  16775. }
  16776. else {
  16777. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  16778. module.debug.apply(console, arguments);
  16779. }
  16780. }
  16781. },
  16782. verbose: function() {
  16783. if(!settings.silent && settings.verbose && settings.debug) {
  16784. if(settings.performance) {
  16785. module.performance.log(arguments);
  16786. }
  16787. else {
  16788. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  16789. module.verbose.apply(console, arguments);
  16790. }
  16791. }
  16792. },
  16793. error: function() {
  16794. if(!settings.silent) {
  16795. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  16796. module.error.apply(console, arguments);
  16797. }
  16798. },
  16799. performance: {
  16800. log: function(message) {
  16801. var
  16802. currentTime,
  16803. executionTime,
  16804. previousTime
  16805. ;
  16806. if(settings.performance) {
  16807. currentTime = new Date().getTime();
  16808. previousTime = time || currentTime;
  16809. executionTime = currentTime - previousTime;
  16810. time = currentTime;
  16811. performance.push({
  16812. 'Name' : message[0],
  16813. 'Arguments' : [].slice.call(message, 1) || '',
  16814. 'Element' : element,
  16815. 'Execution Time' : executionTime
  16816. });
  16817. }
  16818. clearTimeout(module.performance.timer);
  16819. module.performance.timer = setTimeout(module.performance.display, 500);
  16820. },
  16821. display: function() {
  16822. var
  16823. title = settings.name + ':',
  16824. totalTime = 0
  16825. ;
  16826. time = false;
  16827. clearTimeout(module.performance.timer);
  16828. $.each(performance, function(index, data) {
  16829. totalTime += data['Execution Time'];
  16830. });
  16831. title += ' ' + totalTime + 'ms';
  16832. if(moduleSelector) {
  16833. title += ' \'' + moduleSelector + '\'';
  16834. }
  16835. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  16836. console.groupCollapsed(title);
  16837. if(console.table) {
  16838. console.table(performance);
  16839. }
  16840. else {
  16841. $.each(performance, function(index, data) {
  16842. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  16843. });
  16844. }
  16845. console.groupEnd();
  16846. }
  16847. performance = [];
  16848. }
  16849. },
  16850. invoke: function(query, passedArguments, context) {
  16851. var
  16852. object = instance,
  16853. maxDepth,
  16854. found,
  16855. response
  16856. ;
  16857. passedArguments = passedArguments || queryArguments;
  16858. context = element || context;
  16859. if(typeof query == 'string' && object !== undefined) {
  16860. query = query.split(/[\. ]/);
  16861. maxDepth = query.length - 1;
  16862. $.each(query, function(depth, value) {
  16863. var camelCaseValue = (depth != maxDepth)
  16864. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  16865. : query
  16866. ;
  16867. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  16868. object = object[camelCaseValue];
  16869. }
  16870. else if( object[camelCaseValue] !== undefined ) {
  16871. found = object[camelCaseValue];
  16872. return false;
  16873. }
  16874. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  16875. object = object[value];
  16876. }
  16877. else if( object[value] !== undefined ) {
  16878. found = object[value];
  16879. return false;
  16880. }
  16881. else {
  16882. module.error(error.method, query);
  16883. return false;
  16884. }
  16885. });
  16886. }
  16887. if ( $.isFunction( found ) ) {
  16888. response = found.apply(context, passedArguments);
  16889. }
  16890. else if(found !== undefined) {
  16891. response = found;
  16892. }
  16893. if($.isArray(returnedValue)) {
  16894. returnedValue.push(response);
  16895. }
  16896. else if(returnedValue !== undefined) {
  16897. returnedValue = [returnedValue, response];
  16898. }
  16899. else if(response !== undefined) {
  16900. returnedValue = response;
  16901. }
  16902. return found;
  16903. }
  16904. };
  16905. if(methodInvoked) {
  16906. if(instance === undefined) {
  16907. module.initialize();
  16908. }
  16909. module.invoke(query);
  16910. }
  16911. else {
  16912. if(instance !== undefined) {
  16913. instance.invoke('destroy');
  16914. }
  16915. module.initialize();
  16916. }
  16917. })
  16918. ;
  16919. return (returnedValue !== undefined)
  16920. ? returnedValue
  16921. : this
  16922. ;
  16923. };
  16924. // shortcut for tabbed content with no defined navigation
  16925. $.tab = function() {
  16926. $(window).tab.apply(this, arguments);
  16927. };
  16928. $.fn.tab.settings = {
  16929. name : 'Tab',
  16930. namespace : 'tab',
  16931. silent : false,
  16932. debug : false,
  16933. verbose : false,
  16934. performance : true,
  16935. auto : false, // uses pjax style endpoints fetching content from same url with remote-content headers
  16936. history : false, // use browser history
  16937. historyType : 'hash', // #/ or html5 state
  16938. path : false, // base path of url
  16939. context : false, // specify a context that tabs must appear inside
  16940. childrenOnly : false, // use only tabs that are children of context
  16941. maxDepth : 25, // max depth a tab can be nested
  16942. deactivate : 'siblings', // whether tabs should deactivate sibling menu elements or all elements initialized together
  16943. alwaysRefresh : false, // load tab content new every tab click
  16944. cache : true, // cache the content requests to pull locally
  16945. cacheType : 'response', // Whether to cache exact response, or to html cache contents after scripts execute
  16946. ignoreFirstLoad : false, // don't load remote content on first load
  16947. apiSettings : false, // settings for api call
  16948. evaluateScripts : 'once', // whether inline scripts should be parsed (true/false/once). Once will not re-evaluate on cached content
  16949. onFirstLoad : function(tabPath, parameterArray, historyEvent) {}, // called first time loaded
  16950. onLoad : function(tabPath, parameterArray, historyEvent) {}, // called on every load
  16951. onVisible : function(tabPath, parameterArray, historyEvent) {}, // called every time tab visible
  16952. onRequest : function(tabPath, parameterArray, historyEvent) {}, // called ever time a tab beings loading remote content
  16953. templates : {
  16954. determineTitle: function(tabArray) {} // returns page title for path
  16955. },
  16956. error: {
  16957. api : 'You attempted to load content without API module',
  16958. method : 'The method you called is not defined',
  16959. missingTab : 'Activated tab cannot be found. Tabs are case-sensitive.',
  16960. noContent : 'The tab you specified is missing a content url.',
  16961. path : 'History enabled, but no path was specified',
  16962. recursion : 'Max recursive depth reached',
  16963. legacyInit : 'onTabInit has been renamed to onFirstLoad in 2.0, please adjust your code.',
  16964. legacyLoad : 'onTabLoad has been renamed to onLoad in 2.0. Please adjust your code',
  16965. state : 'History requires Asual\'s Address library <https://github.com/asual/jquery-address>'
  16966. },
  16967. metadata : {
  16968. tab : 'tab',
  16969. loaded : 'loaded',
  16970. promise: 'promise'
  16971. },
  16972. className : {
  16973. loading : 'loading',
  16974. active : 'active'
  16975. },
  16976. selector : {
  16977. tabs : '.ui.tab',
  16978. ui : '.ui'
  16979. }
  16980. };
  16981. })( jQuery, window, document );
  16982. /*!
  16983. * # Semantic UI 2.2.6 - Transition
  16984. * http://github.com/semantic-org/semantic-ui/
  16985. *
  16986. *
  16987. * Released under the MIT license
  16988. * http://opensource.org/licenses/MIT
  16989. *
  16990. */
  16991. ;(function ($, window, document, undefined) {
  16992. "use strict";
  16993. window = (typeof window != 'undefined' && window.Math == Math)
  16994. ? window
  16995. : (typeof self != 'undefined' && self.Math == Math)
  16996. ? self
  16997. : Function('return this')()
  16998. ;
  16999. $.fn.transition = function() {
  17000. var
  17001. $allModules = $(this),
  17002. moduleSelector = $allModules.selector || '',
  17003. time = new Date().getTime(),
  17004. performance = [],
  17005. moduleArguments = arguments,
  17006. query = moduleArguments[0],
  17007. queryArguments = [].slice.call(arguments, 1),
  17008. methodInvoked = (typeof query === 'string'),
  17009. requestAnimationFrame = window.requestAnimationFrame
  17010. || window.mozRequestAnimationFrame
  17011. || window.webkitRequestAnimationFrame
  17012. || window.msRequestAnimationFrame
  17013. || function(callback) { setTimeout(callback, 0); },
  17014. returnedValue
  17015. ;
  17016. $allModules
  17017. .each(function(index) {
  17018. var
  17019. $module = $(this),
  17020. element = this,
  17021. // set at run time
  17022. settings,
  17023. instance,
  17024. error,
  17025. className,
  17026. metadata,
  17027. animationEnd,
  17028. animationName,
  17029. namespace,
  17030. moduleNamespace,
  17031. eventNamespace,
  17032. module
  17033. ;
  17034. module = {
  17035. initialize: function() {
  17036. // get full settings
  17037. settings = module.get.settings.apply(element, moduleArguments);
  17038. // shorthand
  17039. className = settings.className;
  17040. error = settings.error;
  17041. metadata = settings.metadata;
  17042. // define namespace
  17043. eventNamespace = '.' + settings.namespace;
  17044. moduleNamespace = 'module-' + settings.namespace;
  17045. instance = $module.data(moduleNamespace) || module;
  17046. // get vendor specific events
  17047. animationEnd = module.get.animationEndEvent();
  17048. if(methodInvoked) {
  17049. methodInvoked = module.invoke(query);
  17050. }
  17051. // method not invoked, lets run an animation
  17052. if(methodInvoked === false) {
  17053. module.verbose('Converted arguments into settings object', settings);
  17054. if(settings.interval) {
  17055. module.delay(settings.animate);
  17056. }
  17057. else {
  17058. module.animate();
  17059. }
  17060. module.instantiate();
  17061. }
  17062. },
  17063. instantiate: function() {
  17064. module.verbose('Storing instance of module', module);
  17065. instance = module;
  17066. $module
  17067. .data(moduleNamespace, instance)
  17068. ;
  17069. },
  17070. destroy: function() {
  17071. module.verbose('Destroying previous module for', element);
  17072. $module
  17073. .removeData(moduleNamespace)
  17074. ;
  17075. },
  17076. refresh: function() {
  17077. module.verbose('Refreshing display type on next animation');
  17078. delete module.displayType;
  17079. },
  17080. forceRepaint: function() {
  17081. module.verbose('Forcing element repaint');
  17082. var
  17083. $parentElement = $module.parent(),
  17084. $nextElement = $module.next()
  17085. ;
  17086. if($nextElement.length === 0) {
  17087. $module.detach().appendTo($parentElement);
  17088. }
  17089. else {
  17090. $module.detach().insertBefore($nextElement);
  17091. }
  17092. },
  17093. repaint: function() {
  17094. module.verbose('Repainting element');
  17095. var
  17096. fakeAssignment = element.offsetWidth
  17097. ;
  17098. },
  17099. delay: function(interval) {
  17100. var
  17101. direction = module.get.animationDirection(),
  17102. shouldReverse,
  17103. delay
  17104. ;
  17105. if(!direction) {
  17106. direction = module.can.transition()
  17107. ? module.get.direction()
  17108. : 'static'
  17109. ;
  17110. }
  17111. interval = (interval !== undefined)
  17112. ? interval
  17113. : settings.interval
  17114. ;
  17115. shouldReverse = (settings.reverse == 'auto' && direction == className.outward);
  17116. delay = (shouldReverse || settings.reverse == true)
  17117. ? ($allModules.length - index) * settings.interval
  17118. : index * settings.interval
  17119. ;
  17120. module.debug('Delaying animation by', delay);
  17121. setTimeout(module.animate, delay);
  17122. },
  17123. animate: function(overrideSettings) {
  17124. settings = overrideSettings || settings;
  17125. if(!module.is.supported()) {
  17126. module.error(error.support);
  17127. return false;
  17128. }
  17129. module.debug('Preparing animation', settings.animation);
  17130. if(module.is.animating()) {
  17131. if(settings.queue) {
  17132. if(!settings.allowRepeats && module.has.direction() && module.is.occurring() && module.queuing !== true) {
  17133. module.debug('Animation is currently occurring, preventing queueing same animation', settings.animation);
  17134. }
  17135. else {
  17136. module.queue(settings.animation);
  17137. }
  17138. return false;
  17139. }
  17140. else if(!settings.allowRepeats && module.is.occurring()) {
  17141. module.debug('Animation is already occurring, will not execute repeated animation', settings.animation);
  17142. return false;
  17143. }
  17144. else {
  17145. module.debug('New animation started, completing previous early', settings.animation);
  17146. instance.complete();
  17147. }
  17148. }
  17149. if( module.can.animate() ) {
  17150. module.set.animating(settings.animation);
  17151. }
  17152. else {
  17153. module.error(error.noAnimation, settings.animation, element);
  17154. }
  17155. },
  17156. reset: function() {
  17157. module.debug('Resetting animation to beginning conditions');
  17158. module.remove.animationCallbacks();
  17159. module.restore.conditions();
  17160. module.remove.animating();
  17161. },
  17162. queue: function(animation) {
  17163. module.debug('Queueing animation of', animation);
  17164. module.queuing = true;
  17165. $module
  17166. .one(animationEnd + '.queue' + eventNamespace, function() {
  17167. module.queuing = false;
  17168. module.repaint();
  17169. module.animate.apply(this, settings);
  17170. })
  17171. ;
  17172. },
  17173. complete: function (event) {
  17174. module.debug('Animation complete', settings.animation);
  17175. module.remove.completeCallback();
  17176. module.remove.failSafe();
  17177. if(!module.is.looping()) {
  17178. if( module.is.outward() ) {
  17179. module.verbose('Animation is outward, hiding element');
  17180. module.restore.conditions();
  17181. module.hide();
  17182. }
  17183. else if( module.is.inward() ) {
  17184. module.verbose('Animation is outward, showing element');
  17185. module.restore.conditions();
  17186. module.show();
  17187. }
  17188. else {
  17189. module.verbose('Static animation completed');
  17190. module.restore.conditions();
  17191. settings.onComplete.call(element);
  17192. }
  17193. }
  17194. },
  17195. force: {
  17196. visible: function() {
  17197. var
  17198. style = $module.attr('style'),
  17199. userStyle = module.get.userStyle(),
  17200. displayType = module.get.displayType(),
  17201. overrideStyle = userStyle + 'display: ' + displayType + ' !important;',
  17202. currentDisplay = $module.css('display'),
  17203. emptyStyle = (style === undefined || style === '')
  17204. ;
  17205. if(currentDisplay !== displayType) {
  17206. module.verbose('Overriding default display to show element', displayType);
  17207. $module
  17208. .attr('style', overrideStyle)
  17209. ;
  17210. }
  17211. else if(emptyStyle) {
  17212. $module.removeAttr('style');
  17213. }
  17214. },
  17215. hidden: function() {
  17216. var
  17217. style = $module.attr('style'),
  17218. currentDisplay = $module.css('display'),
  17219. emptyStyle = (style === undefined || style === '')
  17220. ;
  17221. if(currentDisplay !== 'none' && !module.is.hidden()) {
  17222. module.verbose('Overriding default display to hide element');
  17223. $module
  17224. .css('display', 'none')
  17225. ;
  17226. }
  17227. else if(emptyStyle) {
  17228. $module
  17229. .removeAttr('style')
  17230. ;
  17231. }
  17232. }
  17233. },
  17234. has: {
  17235. direction: function(animation) {
  17236. var
  17237. hasDirection = false
  17238. ;
  17239. animation = animation || settings.animation;
  17240. if(typeof animation === 'string') {
  17241. animation = animation.split(' ');
  17242. $.each(animation, function(index, word){
  17243. if(word === className.inward || word === className.outward) {
  17244. hasDirection = true;
  17245. }
  17246. });
  17247. }
  17248. return hasDirection;
  17249. },
  17250. inlineDisplay: function() {
  17251. var
  17252. style = $module.attr('style') || ''
  17253. ;
  17254. return $.isArray(style.match(/display.*?;/, ''));
  17255. }
  17256. },
  17257. set: {
  17258. animating: function(animation) {
  17259. var
  17260. animationClass,
  17261. direction
  17262. ;
  17263. // remove previous callbacks
  17264. module.remove.completeCallback();
  17265. // determine exact animation
  17266. animation = animation || settings.animation;
  17267. animationClass = module.get.animationClass(animation);
  17268. // save animation class in cache to restore class names
  17269. module.save.animation(animationClass);
  17270. // override display if necessary so animation appears visibly
  17271. module.force.visible();
  17272. module.remove.hidden();
  17273. module.remove.direction();
  17274. module.start.animation(animationClass);
  17275. },
  17276. duration: function(animationName, duration) {
  17277. duration = duration || settings.duration;
  17278. duration = (typeof duration == 'number')
  17279. ? duration + 'ms'
  17280. : duration
  17281. ;
  17282. if(duration || duration === 0) {
  17283. module.verbose('Setting animation duration', duration);
  17284. $module
  17285. .css({
  17286. 'animation-duration': duration
  17287. })
  17288. ;
  17289. }
  17290. },
  17291. direction: function(direction) {
  17292. direction = direction || module.get.direction();
  17293. if(direction == className.inward) {
  17294. module.set.inward();
  17295. }
  17296. else {
  17297. module.set.outward();
  17298. }
  17299. },
  17300. looping: function() {
  17301. module.debug('Transition set to loop');
  17302. $module
  17303. .addClass(className.looping)
  17304. ;
  17305. },
  17306. hidden: function() {
  17307. $module
  17308. .addClass(className.transition)
  17309. .addClass(className.hidden)
  17310. ;
  17311. },
  17312. inward: function() {
  17313. module.debug('Setting direction to inward');
  17314. $module
  17315. .removeClass(className.outward)
  17316. .addClass(className.inward)
  17317. ;
  17318. },
  17319. outward: function() {
  17320. module.debug('Setting direction to outward');
  17321. $module
  17322. .removeClass(className.inward)
  17323. .addClass(className.outward)
  17324. ;
  17325. },
  17326. visible: function() {
  17327. $module
  17328. .addClass(className.transition)
  17329. .addClass(className.visible)
  17330. ;
  17331. }
  17332. },
  17333. start: {
  17334. animation: function(animationClass) {
  17335. animationClass = animationClass || module.get.animationClass();
  17336. module.debug('Starting tween', animationClass);
  17337. $module
  17338. .addClass(animationClass)
  17339. .one(animationEnd + '.complete' + eventNamespace, module.complete)
  17340. ;
  17341. if(settings.useFailSafe) {
  17342. module.add.failSafe();
  17343. }
  17344. module.set.duration(settings.duration);
  17345. settings.onStart.call(element);
  17346. }
  17347. },
  17348. save: {
  17349. animation: function(animation) {
  17350. if(!module.cache) {
  17351. module.cache = {};
  17352. }
  17353. module.cache.animation = animation;
  17354. },
  17355. displayType: function(displayType) {
  17356. if(displayType !== 'none') {
  17357. $module.data(metadata.displayType, displayType);
  17358. }
  17359. },
  17360. transitionExists: function(animation, exists) {
  17361. $.fn.transition.exists[animation] = exists;
  17362. module.verbose('Saving existence of transition', animation, exists);
  17363. }
  17364. },
  17365. restore: {
  17366. conditions: function() {
  17367. var
  17368. animation = module.get.currentAnimation()
  17369. ;
  17370. if(animation) {
  17371. $module
  17372. .removeClass(animation)
  17373. ;
  17374. module.verbose('Removing animation class', module.cache);
  17375. }
  17376. module.remove.duration();
  17377. }
  17378. },
  17379. add: {
  17380. failSafe: function() {
  17381. var
  17382. duration = module.get.duration()
  17383. ;
  17384. module.timer = setTimeout(function() {
  17385. $module.triggerHandler(animationEnd);
  17386. }, duration + settings.failSafeDelay);
  17387. module.verbose('Adding fail safe timer', module.timer);
  17388. }
  17389. },
  17390. remove: {
  17391. animating: function() {
  17392. $module.removeClass(className.animating);
  17393. },
  17394. animationCallbacks: function() {
  17395. module.remove.queueCallback();
  17396. module.remove.completeCallback();
  17397. },
  17398. queueCallback: function() {
  17399. $module.off('.queue' + eventNamespace);
  17400. },
  17401. completeCallback: function() {
  17402. $module.off('.complete' + eventNamespace);
  17403. },
  17404. display: function() {
  17405. $module.css('display', '');
  17406. },
  17407. direction: function() {
  17408. $module
  17409. .removeClass(className.inward)
  17410. .removeClass(className.outward)
  17411. ;
  17412. },
  17413. duration: function() {
  17414. $module
  17415. .css('animation-duration', '')
  17416. ;
  17417. },
  17418. failSafe: function() {
  17419. module.verbose('Removing fail safe timer', module.timer);
  17420. if(module.timer) {
  17421. clearTimeout(module.timer);
  17422. }
  17423. },
  17424. hidden: function() {
  17425. $module.removeClass(className.hidden);
  17426. },
  17427. visible: function() {
  17428. $module.removeClass(className.visible);
  17429. },
  17430. looping: function() {
  17431. module.debug('Transitions are no longer looping');
  17432. if( module.is.looping() ) {
  17433. module.reset();
  17434. $module
  17435. .removeClass(className.looping)
  17436. ;
  17437. }
  17438. },
  17439. transition: function() {
  17440. $module
  17441. .removeClass(className.visible)
  17442. .removeClass(className.hidden)
  17443. ;
  17444. }
  17445. },
  17446. get: {
  17447. settings: function(animation, duration, onComplete) {
  17448. // single settings object
  17449. if(typeof animation == 'object') {
  17450. return $.extend(true, {}, $.fn.transition.settings, animation);
  17451. }
  17452. // all arguments provided
  17453. else if(typeof onComplete == 'function') {
  17454. return $.extend({}, $.fn.transition.settings, {
  17455. animation : animation,
  17456. onComplete : onComplete,
  17457. duration : duration
  17458. });
  17459. }
  17460. // only duration provided
  17461. else if(typeof duration == 'string' || typeof duration == 'number') {
  17462. return $.extend({}, $.fn.transition.settings, {
  17463. animation : animation,
  17464. duration : duration
  17465. });
  17466. }
  17467. // duration is actually settings object
  17468. else if(typeof duration == 'object') {
  17469. return $.extend({}, $.fn.transition.settings, duration, {
  17470. animation : animation
  17471. });
  17472. }
  17473. // duration is actually callback
  17474. else if(typeof duration == 'function') {
  17475. return $.extend({}, $.fn.transition.settings, {
  17476. animation : animation,
  17477. onComplete : duration
  17478. });
  17479. }
  17480. // only animation provided
  17481. else {
  17482. return $.extend({}, $.fn.transition.settings, {
  17483. animation : animation
  17484. });
  17485. }
  17486. },
  17487. animationClass: function(animation) {
  17488. var
  17489. animationClass = animation || settings.animation,
  17490. directionClass = (module.can.transition() && !module.has.direction())
  17491. ? module.get.direction() + ' '
  17492. : ''
  17493. ;
  17494. return className.animating + ' '
  17495. + className.transition + ' '
  17496. + directionClass
  17497. + animationClass
  17498. ;
  17499. },
  17500. currentAnimation: function() {
  17501. return (module.cache && module.cache.animation !== undefined)
  17502. ? module.cache.animation
  17503. : false
  17504. ;
  17505. },
  17506. currentDirection: function() {
  17507. return module.is.inward()
  17508. ? className.inward
  17509. : className.outward
  17510. ;
  17511. },
  17512. direction: function() {
  17513. return module.is.hidden() || !module.is.visible()
  17514. ? className.inward
  17515. : className.outward
  17516. ;
  17517. },
  17518. animationDirection: function(animation) {
  17519. var
  17520. direction
  17521. ;
  17522. animation = animation || settings.animation;
  17523. if(typeof animation === 'string') {
  17524. animation = animation.split(' ');
  17525. // search animation name for out/in class
  17526. $.each(animation, function(index, word){
  17527. if(word === className.inward) {
  17528. direction = className.inward;
  17529. }
  17530. else if(word === className.outward) {
  17531. direction = className.outward;
  17532. }
  17533. });
  17534. }
  17535. // return found direction
  17536. if(direction) {
  17537. return direction;
  17538. }
  17539. return false;
  17540. },
  17541. duration: function(duration) {
  17542. duration = duration || settings.duration;
  17543. if(duration === false) {
  17544. duration = $module.css('animation-duration') || 0;
  17545. }
  17546. return (typeof duration === 'string')
  17547. ? (duration.indexOf('ms') > -1)
  17548. ? parseFloat(duration)
  17549. : parseFloat(duration) * 1000
  17550. : duration
  17551. ;
  17552. },
  17553. displayType: function(shouldDetermine) {
  17554. shouldDetermine = (shouldDetermine !== undefined)
  17555. ? shouldDetermine
  17556. : true
  17557. ;
  17558. if(settings.displayType) {
  17559. return settings.displayType;
  17560. }
  17561. if(shouldDetermine && $module.data(metadata.displayType) === undefined) {
  17562. // create fake element to determine display state
  17563. module.can.transition(true);
  17564. }
  17565. return $module.data(metadata.displayType);
  17566. },
  17567. userStyle: function(style) {
  17568. style = style || $module.attr('style') || '';
  17569. return style.replace(/display.*?;/, '');
  17570. },
  17571. transitionExists: function(animation) {
  17572. return $.fn.transition.exists[animation];
  17573. },
  17574. animationStartEvent: function() {
  17575. var
  17576. element = document.createElement('div'),
  17577. animations = {
  17578. 'animation' :'animationstart',
  17579. 'OAnimation' :'oAnimationStart',
  17580. 'MozAnimation' :'mozAnimationStart',
  17581. 'WebkitAnimation' :'webkitAnimationStart'
  17582. },
  17583. animation
  17584. ;
  17585. for(animation in animations){
  17586. if( element.style[animation] !== undefined ){
  17587. return animations[animation];
  17588. }
  17589. }
  17590. return false;
  17591. },
  17592. animationEndEvent: function() {
  17593. var
  17594. element = document.createElement('div'),
  17595. animations = {
  17596. 'animation' :'animationend',
  17597. 'OAnimation' :'oAnimationEnd',
  17598. 'MozAnimation' :'mozAnimationEnd',
  17599. 'WebkitAnimation' :'webkitAnimationEnd'
  17600. },
  17601. animation
  17602. ;
  17603. for(animation in animations){
  17604. if( element.style[animation] !== undefined ){
  17605. return animations[animation];
  17606. }
  17607. }
  17608. return false;
  17609. }
  17610. },
  17611. can: {
  17612. transition: function(forced) {
  17613. var
  17614. animation = settings.animation,
  17615. transitionExists = module.get.transitionExists(animation),
  17616. displayType = module.get.displayType(false),
  17617. elementClass,
  17618. tagName,
  17619. $clone,
  17620. currentAnimation,
  17621. inAnimation,
  17622. directionExists
  17623. ;
  17624. if( transitionExists === undefined || forced) {
  17625. module.verbose('Determining whether animation exists');
  17626. elementClass = $module.attr('class');
  17627. tagName = $module.prop('tagName');
  17628. $clone = $('<' + tagName + ' />').addClass( elementClass ).insertAfter($module);
  17629. currentAnimation = $clone
  17630. .addClass(animation)
  17631. .removeClass(className.inward)
  17632. .removeClass(className.outward)
  17633. .addClass(className.animating)
  17634. .addClass(className.transition)
  17635. .css('animationName')
  17636. ;
  17637. inAnimation = $clone
  17638. .addClass(className.inward)
  17639. .css('animationName')
  17640. ;
  17641. if(!displayType) {
  17642. displayType = $clone
  17643. .attr('class', elementClass)
  17644. .removeAttr('style')
  17645. .removeClass(className.hidden)
  17646. .removeClass(className.visible)
  17647. .show()
  17648. .css('display')
  17649. ;
  17650. module.verbose('Determining final display state', displayType);
  17651. module.save.displayType(displayType);
  17652. }
  17653. $clone.remove();
  17654. if(currentAnimation != inAnimation) {
  17655. module.debug('Direction exists for animation', animation);
  17656. directionExists = true;
  17657. }
  17658. else if(currentAnimation == 'none' || !currentAnimation) {
  17659. module.debug('No animation defined in css', animation);
  17660. return;
  17661. }
  17662. else {
  17663. module.debug('Static animation found', animation, displayType);
  17664. directionExists = false;
  17665. }
  17666. module.save.transitionExists(animation, directionExists);
  17667. }
  17668. return (transitionExists !== undefined)
  17669. ? transitionExists
  17670. : directionExists
  17671. ;
  17672. },
  17673. animate: function() {
  17674. // can transition does not return a value if animation does not exist
  17675. return (module.can.transition() !== undefined);
  17676. }
  17677. },
  17678. is: {
  17679. animating: function() {
  17680. return $module.hasClass(className.animating);
  17681. },
  17682. inward: function() {
  17683. return $module.hasClass(className.inward);
  17684. },
  17685. outward: function() {
  17686. return $module.hasClass(className.outward);
  17687. },
  17688. looping: function() {
  17689. return $module.hasClass(className.looping);
  17690. },
  17691. occurring: function(animation) {
  17692. animation = animation || settings.animation;
  17693. animation = '.' + animation.replace(' ', '.');
  17694. return ( $module.filter(animation).length > 0 );
  17695. },
  17696. visible: function() {
  17697. return $module.is(':visible');
  17698. },
  17699. hidden: function() {
  17700. return $module.css('visibility') === 'hidden';
  17701. },
  17702. supported: function() {
  17703. return(animationEnd !== false);
  17704. }
  17705. },
  17706. hide: function() {
  17707. module.verbose('Hiding element');
  17708. if( module.is.animating() ) {
  17709. module.reset();
  17710. }
  17711. element.blur(); // IE will trigger focus change if element is not blurred before hiding
  17712. module.remove.display();
  17713. module.remove.visible();
  17714. module.set.hidden();
  17715. module.force.hidden();
  17716. settings.onHide.call(element);
  17717. settings.onComplete.call(element);
  17718. // module.repaint();
  17719. },
  17720. show: function(display) {
  17721. module.verbose('Showing element', display);
  17722. module.remove.hidden();
  17723. module.set.visible();
  17724. module.force.visible();
  17725. settings.onShow.call(element);
  17726. settings.onComplete.call(element);
  17727. // module.repaint();
  17728. },
  17729. toggle: function() {
  17730. if( module.is.visible() ) {
  17731. module.hide();
  17732. }
  17733. else {
  17734. module.show();
  17735. }
  17736. },
  17737. stop: function() {
  17738. module.debug('Stopping current animation');
  17739. $module.triggerHandler(animationEnd);
  17740. },
  17741. stopAll: function() {
  17742. module.debug('Stopping all animation');
  17743. module.remove.queueCallback();
  17744. $module.triggerHandler(animationEnd);
  17745. },
  17746. clear: {
  17747. queue: function() {
  17748. module.debug('Clearing animation queue');
  17749. module.remove.queueCallback();
  17750. }
  17751. },
  17752. enable: function() {
  17753. module.verbose('Starting animation');
  17754. $module.removeClass(className.disabled);
  17755. },
  17756. disable: function() {
  17757. module.debug('Stopping animation');
  17758. $module.addClass(className.disabled);
  17759. },
  17760. setting: function(name, value) {
  17761. module.debug('Changing setting', name, value);
  17762. if( $.isPlainObject(name) ) {
  17763. $.extend(true, settings, name);
  17764. }
  17765. else if(value !== undefined) {
  17766. if($.isPlainObject(settings[name])) {
  17767. $.extend(true, settings[name], value);
  17768. }
  17769. else {
  17770. settings[name] = value;
  17771. }
  17772. }
  17773. else {
  17774. return settings[name];
  17775. }
  17776. },
  17777. internal: function(name, value) {
  17778. if( $.isPlainObject(name) ) {
  17779. $.extend(true, module, name);
  17780. }
  17781. else if(value !== undefined) {
  17782. module[name] = value;
  17783. }
  17784. else {
  17785. return module[name];
  17786. }
  17787. },
  17788. debug: function() {
  17789. if(!settings.silent && settings.debug) {
  17790. if(settings.performance) {
  17791. module.performance.log(arguments);
  17792. }
  17793. else {
  17794. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  17795. module.debug.apply(console, arguments);
  17796. }
  17797. }
  17798. },
  17799. verbose: function() {
  17800. if(!settings.silent && settings.verbose && settings.debug) {
  17801. if(settings.performance) {
  17802. module.performance.log(arguments);
  17803. }
  17804. else {
  17805. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  17806. module.verbose.apply(console, arguments);
  17807. }
  17808. }
  17809. },
  17810. error: function() {
  17811. if(!settings.silent) {
  17812. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  17813. module.error.apply(console, arguments);
  17814. }
  17815. },
  17816. performance: {
  17817. log: function(message) {
  17818. var
  17819. currentTime,
  17820. executionTime,
  17821. previousTime
  17822. ;
  17823. if(settings.performance) {
  17824. currentTime = new Date().getTime();
  17825. previousTime = time || currentTime;
  17826. executionTime = currentTime - previousTime;
  17827. time = currentTime;
  17828. performance.push({
  17829. 'Name' : message[0],
  17830. 'Arguments' : [].slice.call(message, 1) || '',
  17831. 'Element' : element,
  17832. 'Execution Time' : executionTime
  17833. });
  17834. }
  17835. clearTimeout(module.performance.timer);
  17836. module.performance.timer = setTimeout(module.performance.display, 500);
  17837. },
  17838. display: function() {
  17839. var
  17840. title = settings.name + ':',
  17841. totalTime = 0
  17842. ;
  17843. time = false;
  17844. clearTimeout(module.performance.timer);
  17845. $.each(performance, function(index, data) {
  17846. totalTime += data['Execution Time'];
  17847. });
  17848. title += ' ' + totalTime + 'ms';
  17849. if(moduleSelector) {
  17850. title += ' \'' + moduleSelector + '\'';
  17851. }
  17852. if($allModules.length > 1) {
  17853. title += ' ' + '(' + $allModules.length + ')';
  17854. }
  17855. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  17856. console.groupCollapsed(title);
  17857. if(console.table) {
  17858. console.table(performance);
  17859. }
  17860. else {
  17861. $.each(performance, function(index, data) {
  17862. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  17863. });
  17864. }
  17865. console.groupEnd();
  17866. }
  17867. performance = [];
  17868. }
  17869. },
  17870. // modified for transition to return invoke success
  17871. invoke: function(query, passedArguments, context) {
  17872. var
  17873. object = instance,
  17874. maxDepth,
  17875. found,
  17876. response
  17877. ;
  17878. passedArguments = passedArguments || queryArguments;
  17879. context = element || context;
  17880. if(typeof query == 'string' && object !== undefined) {
  17881. query = query.split(/[\. ]/);
  17882. maxDepth = query.length - 1;
  17883. $.each(query, function(depth, value) {
  17884. var camelCaseValue = (depth != maxDepth)
  17885. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  17886. : query
  17887. ;
  17888. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  17889. object = object[camelCaseValue];
  17890. }
  17891. else if( object[camelCaseValue] !== undefined ) {
  17892. found = object[camelCaseValue];
  17893. return false;
  17894. }
  17895. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  17896. object = object[value];
  17897. }
  17898. else if( object[value] !== undefined ) {
  17899. found = object[value];
  17900. return false;
  17901. }
  17902. else {
  17903. return false;
  17904. }
  17905. });
  17906. }
  17907. if ( $.isFunction( found ) ) {
  17908. response = found.apply(context, passedArguments);
  17909. }
  17910. else if(found !== undefined) {
  17911. response = found;
  17912. }
  17913. if($.isArray(returnedValue)) {
  17914. returnedValue.push(response);
  17915. }
  17916. else if(returnedValue !== undefined) {
  17917. returnedValue = [returnedValue, response];
  17918. }
  17919. else if(response !== undefined) {
  17920. returnedValue = response;
  17921. }
  17922. return (found !== undefined)
  17923. ? found
  17924. : false
  17925. ;
  17926. }
  17927. };
  17928. module.initialize();
  17929. })
  17930. ;
  17931. return (returnedValue !== undefined)
  17932. ? returnedValue
  17933. : this
  17934. ;
  17935. };
  17936. // Records if CSS transition is available
  17937. $.fn.transition.exists = {};
  17938. $.fn.transition.settings = {
  17939. // module info
  17940. name : 'Transition',
  17941. // hide all output from this component regardless of other settings
  17942. silent : false,
  17943. // debug content outputted to console
  17944. debug : false,
  17945. // verbose debug output
  17946. verbose : false,
  17947. // performance data output
  17948. performance : true,
  17949. // event namespace
  17950. namespace : 'transition',
  17951. // delay between animations in group
  17952. interval : 0,
  17953. // whether group animations should be reversed
  17954. reverse : 'auto',
  17955. // animation callback event
  17956. onStart : function() {},
  17957. onComplete : function() {},
  17958. onShow : function() {},
  17959. onHide : function() {},
  17960. // whether timeout should be used to ensure callback fires in cases animationend does not
  17961. useFailSafe : true,
  17962. // delay in ms for fail safe
  17963. failSafeDelay : 100,
  17964. // whether EXACT animation can occur twice in a row
  17965. allowRepeats : false,
  17966. // Override final display type on visible
  17967. displayType : false,
  17968. // animation duration
  17969. animation : 'fade',
  17970. duration : false,
  17971. // new animations will occur after previous ones
  17972. queue : true,
  17973. metadata : {
  17974. displayType: 'display'
  17975. },
  17976. className : {
  17977. animating : 'animating',
  17978. disabled : 'disabled',
  17979. hidden : 'hidden',
  17980. inward : 'in',
  17981. loading : 'loading',
  17982. looping : 'looping',
  17983. outward : 'out',
  17984. transition : 'transition',
  17985. visible : 'visible'
  17986. },
  17987. // possible errors
  17988. error: {
  17989. noAnimation : 'Element is no longer attached to DOM. Unable to animate. Use silent setting to surpress this warning in production.',
  17990. repeated : 'That animation is already occurring, cancelling repeated animation',
  17991. method : 'The method you called is not defined',
  17992. support : 'This browser does not support CSS animations'
  17993. }
  17994. };
  17995. })( jQuery, window, document );
  17996. /*!
  17997. * # Semantic UI 2.2.6 - API
  17998. * http://github.com/semantic-org/semantic-ui/
  17999. *
  18000. *
  18001. * Released under the MIT license
  18002. * http://opensource.org/licenses/MIT
  18003. *
  18004. */
  18005. ;(function ($, window, document, undefined) {
  18006. "use strict";
  18007. var
  18008. window = (typeof window != 'undefined' && window.Math == Math)
  18009. ? window
  18010. : (typeof self != 'undefined' && self.Math == Math)
  18011. ? self
  18012. : Function('return this')()
  18013. ;
  18014. $.api = $.fn.api = function(parameters) {
  18015. var
  18016. // use window context if none specified
  18017. $allModules = $.isFunction(this)
  18018. ? $(window)
  18019. : $(this),
  18020. moduleSelector = $allModules.selector || '',
  18021. time = new Date().getTime(),
  18022. performance = [],
  18023. query = arguments[0],
  18024. methodInvoked = (typeof query == 'string'),
  18025. queryArguments = [].slice.call(arguments, 1),
  18026. returnedValue
  18027. ;
  18028. $allModules
  18029. .each(function() {
  18030. var
  18031. settings = ( $.isPlainObject(parameters) )
  18032. ? $.extend(true, {}, $.fn.api.settings, parameters)
  18033. : $.extend({}, $.fn.api.settings),
  18034. // internal aliases
  18035. namespace = settings.namespace,
  18036. metadata = settings.metadata,
  18037. selector = settings.selector,
  18038. error = settings.error,
  18039. className = settings.className,
  18040. // define namespaces for modules
  18041. eventNamespace = '.' + namespace,
  18042. moduleNamespace = 'module-' + namespace,
  18043. // element that creates request
  18044. $module = $(this),
  18045. $form = $module.closest(selector.form),
  18046. // context used for state
  18047. $context = (settings.stateContext)
  18048. ? $(settings.stateContext)
  18049. : $module,
  18050. // request details
  18051. ajaxSettings,
  18052. requestSettings,
  18053. url,
  18054. data,
  18055. requestStartTime,
  18056. // standard module
  18057. element = this,
  18058. context = $context[0],
  18059. instance = $module.data(moduleNamespace),
  18060. module
  18061. ;
  18062. module = {
  18063. initialize: function() {
  18064. if(!methodInvoked) {
  18065. module.bind.events();
  18066. }
  18067. module.instantiate();
  18068. },
  18069. instantiate: function() {
  18070. module.verbose('Storing instance of module', module);
  18071. instance = module;
  18072. $module
  18073. .data(moduleNamespace, instance)
  18074. ;
  18075. },
  18076. destroy: function() {
  18077. module.verbose('Destroying previous module for', element);
  18078. $module
  18079. .removeData(moduleNamespace)
  18080. .off(eventNamespace)
  18081. ;
  18082. },
  18083. bind: {
  18084. events: function() {
  18085. var
  18086. triggerEvent = module.get.event()
  18087. ;
  18088. if( triggerEvent ) {
  18089. module.verbose('Attaching API events to element', triggerEvent);
  18090. $module
  18091. .on(triggerEvent + eventNamespace, module.event.trigger)
  18092. ;
  18093. }
  18094. else if(settings.on == 'now') {
  18095. module.debug('Querying API endpoint immediately');
  18096. module.query();
  18097. }
  18098. }
  18099. },
  18100. decode: {
  18101. json: function(response) {
  18102. if(response !== undefined && typeof response == 'string') {
  18103. try {
  18104. response = JSON.parse(response);
  18105. }
  18106. catch(e) {
  18107. // isnt json string
  18108. }
  18109. }
  18110. return response;
  18111. }
  18112. },
  18113. read: {
  18114. cachedResponse: function(url) {
  18115. var
  18116. response
  18117. ;
  18118. if(window.Storage === undefined) {
  18119. module.error(error.noStorage);
  18120. return;
  18121. }
  18122. response = sessionStorage.getItem(url);
  18123. module.debug('Using cached response', url, response);
  18124. response = module.decode.json(response);
  18125. return response;
  18126. }
  18127. },
  18128. write: {
  18129. cachedResponse: function(url, response) {
  18130. if(response && response === '') {
  18131. module.debug('Response empty, not caching', response);
  18132. return;
  18133. }
  18134. if(window.Storage === undefined) {
  18135. module.error(error.noStorage);
  18136. return;
  18137. }
  18138. if( $.isPlainObject(response) ) {
  18139. response = JSON.stringify(response);
  18140. }
  18141. sessionStorage.setItem(url, response);
  18142. module.verbose('Storing cached response for url', url, response);
  18143. }
  18144. },
  18145. query: function() {
  18146. if(module.is.disabled()) {
  18147. module.debug('Element is disabled API request aborted');
  18148. return;
  18149. }
  18150. if(module.is.loading()) {
  18151. if(settings.interruptRequests) {
  18152. module.debug('Interrupting previous request');
  18153. module.abort();
  18154. }
  18155. else {
  18156. module.debug('Cancelling request, previous request is still pending');
  18157. return;
  18158. }
  18159. }
  18160. // pass element metadata to url (value, text)
  18161. if(settings.defaultData) {
  18162. $.extend(true, settings.urlData, module.get.defaultData());
  18163. }
  18164. // Add form content
  18165. if(settings.serializeForm) {
  18166. settings.data = module.add.formData(settings.data);
  18167. }
  18168. // call beforesend and get any settings changes
  18169. requestSettings = module.get.settings();
  18170. // check if before send cancelled request
  18171. if(requestSettings === false) {
  18172. module.cancelled = true;
  18173. module.error(error.beforeSend);
  18174. return;
  18175. }
  18176. else {
  18177. module.cancelled = false;
  18178. }
  18179. // get url
  18180. url = module.get.templatedURL();
  18181. if(!url && !module.is.mocked()) {
  18182. module.error(error.missingURL);
  18183. return;
  18184. }
  18185. // replace variables
  18186. url = module.add.urlData( url );
  18187. // missing url parameters
  18188. if( !url && !module.is.mocked()) {
  18189. return;
  18190. }
  18191. requestSettings.url = settings.base + url;
  18192. // look for jQuery ajax parameters in settings
  18193. ajaxSettings = $.extend(true, {}, settings, {
  18194. type : settings.method || settings.type,
  18195. data : data,
  18196. url : settings.base + url,
  18197. beforeSend : settings.beforeXHR,
  18198. success : function() {},
  18199. failure : function() {},
  18200. complete : function() {}
  18201. });
  18202. module.debug('Querying URL', ajaxSettings.url);
  18203. module.verbose('Using AJAX settings', ajaxSettings);
  18204. if(settings.cache === 'local' && module.read.cachedResponse(url)) {
  18205. module.debug('Response returned from local cache');
  18206. module.request = module.create.request();
  18207. module.request.resolveWith(context, [ module.read.cachedResponse(url) ]);
  18208. return;
  18209. }
  18210. if( !settings.throttle ) {
  18211. module.debug('Sending request', data, ajaxSettings.method);
  18212. module.send.request();
  18213. }
  18214. else {
  18215. if(!settings.throttleFirstRequest && !module.timer) {
  18216. module.debug('Sending request', data, ajaxSettings.method);
  18217. module.send.request();
  18218. module.timer = setTimeout(function(){}, settings.throttle);
  18219. }
  18220. else {
  18221. module.debug('Throttling request', settings.throttle);
  18222. clearTimeout(module.timer);
  18223. module.timer = setTimeout(function() {
  18224. if(module.timer) {
  18225. delete module.timer;
  18226. }
  18227. module.debug('Sending throttled request', data, ajaxSettings.method);
  18228. module.send.request();
  18229. }, settings.throttle);
  18230. }
  18231. }
  18232. },
  18233. should: {
  18234. removeError: function() {
  18235. return ( settings.hideError === true || (settings.hideError === 'auto' && !module.is.form()) );
  18236. }
  18237. },
  18238. is: {
  18239. disabled: function() {
  18240. return ($module.filter(selector.disabled).length > 0);
  18241. },
  18242. expectingJSON: function() {
  18243. return settings.dataType === 'json' || settings.dataType === 'jsonp';
  18244. },
  18245. form: function() {
  18246. return $module.is('form') || $context.is('form');
  18247. },
  18248. mocked: function() {
  18249. return (settings.mockResponse || settings.mockResponseAsync || settings.response || settings.responseAsync);
  18250. },
  18251. input: function() {
  18252. return $module.is('input');
  18253. },
  18254. loading: function() {
  18255. return (module.request)
  18256. ? (module.request.state() == 'pending')
  18257. : false
  18258. ;
  18259. },
  18260. abortedRequest: function(xhr) {
  18261. if(xhr && xhr.readyState !== undefined && xhr.readyState === 0) {
  18262. module.verbose('XHR request determined to be aborted');
  18263. return true;
  18264. }
  18265. else {
  18266. module.verbose('XHR request was not aborted');
  18267. return false;
  18268. }
  18269. },
  18270. validResponse: function(response) {
  18271. if( (!module.is.expectingJSON()) || !$.isFunction(settings.successTest) ) {
  18272. module.verbose('Response is not JSON, skipping validation', settings.successTest, response);
  18273. return true;
  18274. }
  18275. module.debug('Checking JSON returned success', settings.successTest, response);
  18276. if( settings.successTest(response) ) {
  18277. module.debug('Response passed success test', response);
  18278. return true;
  18279. }
  18280. else {
  18281. module.debug('Response failed success test', response);
  18282. return false;
  18283. }
  18284. }
  18285. },
  18286. was: {
  18287. cancelled: function() {
  18288. return (module.cancelled || false);
  18289. },
  18290. succesful: function() {
  18291. return (module.request && module.request.state() == 'resolved');
  18292. },
  18293. failure: function() {
  18294. return (module.request && module.request.state() == 'rejected');
  18295. },
  18296. complete: function() {
  18297. return (module.request && (module.request.state() == 'resolved' || module.request.state() == 'rejected') );
  18298. }
  18299. },
  18300. add: {
  18301. urlData: function(url, urlData) {
  18302. var
  18303. requiredVariables,
  18304. optionalVariables
  18305. ;
  18306. if(url) {
  18307. requiredVariables = url.match(settings.regExp.required);
  18308. optionalVariables = url.match(settings.regExp.optional);
  18309. urlData = urlData || settings.urlData;
  18310. if(requiredVariables) {
  18311. module.debug('Looking for required URL variables', requiredVariables);
  18312. $.each(requiredVariables, function(index, templatedString) {
  18313. var
  18314. // allow legacy {$var} style
  18315. variable = (templatedString.indexOf('$') !== -1)
  18316. ? templatedString.substr(2, templatedString.length - 3)
  18317. : templatedString.substr(1, templatedString.length - 2),
  18318. value = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
  18319. ? urlData[variable]
  18320. : ($module.data(variable) !== undefined)
  18321. ? $module.data(variable)
  18322. : ($context.data(variable) !== undefined)
  18323. ? $context.data(variable)
  18324. : urlData[variable]
  18325. ;
  18326. // remove value
  18327. if(value === undefined) {
  18328. module.error(error.requiredParameter, variable, url);
  18329. url = false;
  18330. return false;
  18331. }
  18332. else {
  18333. module.verbose('Found required variable', variable, value);
  18334. value = (settings.encodeParameters)
  18335. ? module.get.urlEncodedValue(value)
  18336. : value
  18337. ;
  18338. url = url.replace(templatedString, value);
  18339. }
  18340. });
  18341. }
  18342. if(optionalVariables) {
  18343. module.debug('Looking for optional URL variables', requiredVariables);
  18344. $.each(optionalVariables, function(index, templatedString) {
  18345. var
  18346. // allow legacy {/$var} style
  18347. variable = (templatedString.indexOf('$') !== -1)
  18348. ? templatedString.substr(3, templatedString.length - 4)
  18349. : templatedString.substr(2, templatedString.length - 3),
  18350. value = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
  18351. ? urlData[variable]
  18352. : ($module.data(variable) !== undefined)
  18353. ? $module.data(variable)
  18354. : ($context.data(variable) !== undefined)
  18355. ? $context.data(variable)
  18356. : urlData[variable]
  18357. ;
  18358. // optional replacement
  18359. if(value !== undefined) {
  18360. module.verbose('Optional variable Found', variable, value);
  18361. url = url.replace(templatedString, value);
  18362. }
  18363. else {
  18364. module.verbose('Optional variable not found', variable);
  18365. // remove preceding slash if set
  18366. if(url.indexOf('/' + templatedString) !== -1) {
  18367. url = url.replace('/' + templatedString, '');
  18368. }
  18369. else {
  18370. url = url.replace(templatedString, '');
  18371. }
  18372. }
  18373. });
  18374. }
  18375. }
  18376. return url;
  18377. },
  18378. formData: function(data) {
  18379. var
  18380. canSerialize = ($.fn.serializeObject !== undefined),
  18381. formData = (canSerialize)
  18382. ? $form.serializeObject()
  18383. : $form.serialize(),
  18384. hasOtherData
  18385. ;
  18386. data = data || settings.data;
  18387. hasOtherData = $.isPlainObject(data);
  18388. if(hasOtherData) {
  18389. if(canSerialize) {
  18390. module.debug('Extending existing data with form data', data, formData);
  18391. data = $.extend(true, {}, data, formData);
  18392. }
  18393. else {
  18394. module.error(error.missingSerialize);
  18395. module.debug('Cant extend data. Replacing data with form data', data, formData);
  18396. data = formData;
  18397. }
  18398. }
  18399. else {
  18400. module.debug('Adding form data', formData);
  18401. data = formData;
  18402. }
  18403. return data;
  18404. }
  18405. },
  18406. send: {
  18407. request: function() {
  18408. module.set.loading();
  18409. module.request = module.create.request();
  18410. if( module.is.mocked() ) {
  18411. module.mockedXHR = module.create.mockedXHR();
  18412. }
  18413. else {
  18414. module.xhr = module.create.xhr();
  18415. }
  18416. settings.onRequest.call(context, module.request, module.xhr);
  18417. }
  18418. },
  18419. event: {
  18420. trigger: function(event) {
  18421. module.query();
  18422. if(event.type == 'submit' || event.type == 'click') {
  18423. event.preventDefault();
  18424. }
  18425. },
  18426. xhr: {
  18427. always: function() {
  18428. // nothing special
  18429. },
  18430. done: function(response, textStatus, xhr) {
  18431. var
  18432. context = this,
  18433. elapsedTime = (new Date().getTime() - requestStartTime),
  18434. timeLeft = (settings.loadingDuration - elapsedTime),
  18435. translatedResponse = ( $.isFunction(settings.onResponse) )
  18436. ? module.is.expectingJSON()
  18437. ? settings.onResponse.call(context, $.extend(true, {}, response))
  18438. : settings.onResponse.call(context, response)
  18439. : false
  18440. ;
  18441. timeLeft = (timeLeft > 0)
  18442. ? timeLeft
  18443. : 0
  18444. ;
  18445. if(translatedResponse) {
  18446. module.debug('Modified API response in onResponse callback', settings.onResponse, translatedResponse, response);
  18447. response = translatedResponse;
  18448. }
  18449. if(timeLeft > 0) {
  18450. module.debug('Response completed early delaying state change by', timeLeft);
  18451. }
  18452. setTimeout(function() {
  18453. if( module.is.validResponse(response) ) {
  18454. module.request.resolveWith(context, [response, xhr]);
  18455. }
  18456. else {
  18457. module.request.rejectWith(context, [xhr, 'invalid']);
  18458. }
  18459. }, timeLeft);
  18460. },
  18461. fail: function(xhr, status, httpMessage) {
  18462. var
  18463. context = this,
  18464. elapsedTime = (new Date().getTime() - requestStartTime),
  18465. timeLeft = (settings.loadingDuration - elapsedTime)
  18466. ;
  18467. timeLeft = (timeLeft > 0)
  18468. ? timeLeft
  18469. : 0
  18470. ;
  18471. if(timeLeft > 0) {
  18472. module.debug('Response completed early delaying state change by', timeLeft);
  18473. }
  18474. setTimeout(function() {
  18475. if( module.is.abortedRequest(xhr) ) {
  18476. module.request.rejectWith(context, [xhr, 'aborted', httpMessage]);
  18477. }
  18478. else {
  18479. module.request.rejectWith(context, [xhr, 'error', status, httpMessage]);
  18480. }
  18481. }, timeLeft);
  18482. }
  18483. },
  18484. request: {
  18485. done: function(response, xhr) {
  18486. module.debug('Successful API Response', response);
  18487. if(settings.cache === 'local' && url) {
  18488. module.write.cachedResponse(url, response);
  18489. module.debug('Saving server response locally', module.cache);
  18490. }
  18491. settings.onSuccess.call(context, response, $module, xhr);
  18492. },
  18493. complete: function(firstParameter, secondParameter) {
  18494. var
  18495. xhr,
  18496. response
  18497. ;
  18498. // have to guess callback parameters based on request success
  18499. if( module.was.succesful() ) {
  18500. response = firstParameter;
  18501. xhr = secondParameter;
  18502. }
  18503. else {
  18504. xhr = firstParameter;
  18505. response = module.get.responseFromXHR(xhr);
  18506. }
  18507. module.remove.loading();
  18508. settings.onComplete.call(context, response, $module, xhr);
  18509. },
  18510. fail: function(xhr, status, httpMessage) {
  18511. var
  18512. // pull response from xhr if available
  18513. response = module.get.responseFromXHR(xhr),
  18514. errorMessage = module.get.errorFromRequest(response, status, httpMessage)
  18515. ;
  18516. if(status == 'aborted') {
  18517. module.debug('XHR Aborted (Most likely caused by page navigation or CORS Policy)', status, httpMessage);
  18518. settings.onAbort.call(context, status, $module, xhr);
  18519. return true;
  18520. }
  18521. else if(status == 'invalid') {
  18522. module.debug('JSON did not pass success test. A server-side error has most likely occurred', response);
  18523. }
  18524. else if(status == 'error') {
  18525. if(xhr !== undefined) {
  18526. module.debug('XHR produced a server error', status, httpMessage);
  18527. // make sure we have an error to display to console
  18528. if( xhr.status != 200 && httpMessage !== undefined && httpMessage !== '') {
  18529. module.error(error.statusMessage + httpMessage, ajaxSettings.url);
  18530. }
  18531. settings.onError.call(context, errorMessage, $module, xhr);
  18532. }
  18533. }
  18534. if(settings.errorDuration && status !== 'aborted') {
  18535. module.debug('Adding error state');
  18536. module.set.error();
  18537. if( module.should.removeError() ) {
  18538. setTimeout(module.remove.error, settings.errorDuration);
  18539. }
  18540. }
  18541. module.debug('API Request failed', errorMessage, xhr);
  18542. settings.onFailure.call(context, response, $module, xhr);
  18543. }
  18544. }
  18545. },
  18546. create: {
  18547. request: function() {
  18548. // api request promise
  18549. return $.Deferred()
  18550. .always(module.event.request.complete)
  18551. .done(module.event.request.done)
  18552. .fail(module.event.request.fail)
  18553. ;
  18554. },
  18555. mockedXHR: function () {
  18556. var
  18557. // xhr does not simulate these properties of xhr but must return them
  18558. textStatus = false,
  18559. status = false,
  18560. httpMessage = false,
  18561. responder = settings.mockResponse || settings.response,
  18562. asyncResponder = settings.mockResponseAsync || settings.responseAsync,
  18563. asyncCallback,
  18564. response,
  18565. mockedXHR
  18566. ;
  18567. mockedXHR = $.Deferred()
  18568. .always(module.event.xhr.complete)
  18569. .done(module.event.xhr.done)
  18570. .fail(module.event.xhr.fail)
  18571. ;
  18572. if(responder) {
  18573. if( $.isFunction(responder) ) {
  18574. module.debug('Using specified synchronous callback', responder);
  18575. response = responder.call(context, requestSettings);
  18576. }
  18577. else {
  18578. module.debug('Using settings specified response', responder);
  18579. response = responder;
  18580. }
  18581. // simulating response
  18582. mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]);
  18583. }
  18584. else if( $.isFunction(asyncResponder) ) {
  18585. asyncCallback = function(response) {
  18586. module.debug('Async callback returned response', response);
  18587. if(response) {
  18588. mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]);
  18589. }
  18590. else {
  18591. mockedXHR.rejectWith(context, [{ responseText: response }, status, httpMessage]);
  18592. }
  18593. };
  18594. module.debug('Using specified async response callback', asyncResponder);
  18595. asyncResponder.call(context, requestSettings, asyncCallback);
  18596. }
  18597. return mockedXHR;
  18598. },
  18599. xhr: function() {
  18600. var
  18601. xhr
  18602. ;
  18603. // ajax request promise
  18604. xhr = $.ajax(ajaxSettings)
  18605. .always(module.event.xhr.always)
  18606. .done(module.event.xhr.done)
  18607. .fail(module.event.xhr.fail)
  18608. ;
  18609. module.verbose('Created server request', xhr, ajaxSettings);
  18610. return xhr;
  18611. }
  18612. },
  18613. set: {
  18614. error: function() {
  18615. module.verbose('Adding error state to element', $context);
  18616. $context.addClass(className.error);
  18617. },
  18618. loading: function() {
  18619. module.verbose('Adding loading state to element', $context);
  18620. $context.addClass(className.loading);
  18621. requestStartTime = new Date().getTime();
  18622. }
  18623. },
  18624. remove: {
  18625. error: function() {
  18626. module.verbose('Removing error state from element', $context);
  18627. $context.removeClass(className.error);
  18628. },
  18629. loading: function() {
  18630. module.verbose('Removing loading state from element', $context);
  18631. $context.removeClass(className.loading);
  18632. }
  18633. },
  18634. get: {
  18635. responseFromXHR: function(xhr) {
  18636. return $.isPlainObject(xhr)
  18637. ? (module.is.expectingJSON())
  18638. ? module.decode.json(xhr.responseText)
  18639. : xhr.responseText
  18640. : false
  18641. ;
  18642. },
  18643. errorFromRequest: function(response, status, httpMessage) {
  18644. return ($.isPlainObject(response) && response.error !== undefined)
  18645. ? response.error // use json error message
  18646. : (settings.error[status] !== undefined) // use server error message
  18647. ? settings.error[status]
  18648. : httpMessage
  18649. ;
  18650. },
  18651. request: function() {
  18652. return module.request || false;
  18653. },
  18654. xhr: function() {
  18655. return module.xhr || false;
  18656. },
  18657. settings: function() {
  18658. var
  18659. runSettings
  18660. ;
  18661. runSettings = settings.beforeSend.call(context, settings);
  18662. if(runSettings) {
  18663. if(runSettings.success !== undefined) {
  18664. module.debug('Legacy success callback detected', runSettings);
  18665. module.error(error.legacyParameters, runSettings.success);
  18666. runSettings.onSuccess = runSettings.success;
  18667. }
  18668. if(runSettings.failure !== undefined) {
  18669. module.debug('Legacy failure callback detected', runSettings);
  18670. module.error(error.legacyParameters, runSettings.failure);
  18671. runSettings.onFailure = runSettings.failure;
  18672. }
  18673. if(runSettings.complete !== undefined) {
  18674. module.debug('Legacy complete callback detected', runSettings);
  18675. module.error(error.legacyParameters, runSettings.complete);
  18676. runSettings.onComplete = runSettings.complete;
  18677. }
  18678. }
  18679. if(runSettings === undefined) {
  18680. module.error(error.noReturnedValue);
  18681. }
  18682. if(runSettings === false) {
  18683. return runSettings;
  18684. }
  18685. return (runSettings !== undefined)
  18686. ? $.extend(true, {}, runSettings)
  18687. : $.extend(true, {}, settings)
  18688. ;
  18689. },
  18690. urlEncodedValue: function(value) {
  18691. var
  18692. decodedValue = window.decodeURIComponent(value),
  18693. encodedValue = window.encodeURIComponent(value),
  18694. alreadyEncoded = (decodedValue !== value)
  18695. ;
  18696. if(alreadyEncoded) {
  18697. module.debug('URL value is already encoded, avoiding double encoding', value);
  18698. return value;
  18699. }
  18700. module.verbose('Encoding value using encodeURIComponent', value, encodedValue);
  18701. return encodedValue;
  18702. },
  18703. defaultData: function() {
  18704. var
  18705. data = {}
  18706. ;
  18707. if( !$.isWindow(element) ) {
  18708. if( module.is.input() ) {
  18709. data.value = $module.val();
  18710. }
  18711. else if( module.is.form() ) {
  18712. }
  18713. else {
  18714. data.text = $module.text();
  18715. }
  18716. }
  18717. return data;
  18718. },
  18719. event: function() {
  18720. if( $.isWindow(element) || settings.on == 'now' ) {
  18721. module.debug('API called without element, no events attached');
  18722. return false;
  18723. }
  18724. else if(settings.on == 'auto') {
  18725. if( $module.is('input') ) {
  18726. return (element.oninput !== undefined)
  18727. ? 'input'
  18728. : (element.onpropertychange !== undefined)
  18729. ? 'propertychange'
  18730. : 'keyup'
  18731. ;
  18732. }
  18733. else if( $module.is('form') ) {
  18734. return 'submit';
  18735. }
  18736. else {
  18737. return 'click';
  18738. }
  18739. }
  18740. else {
  18741. return settings.on;
  18742. }
  18743. },
  18744. templatedURL: function(action) {
  18745. action = action || $module.data(metadata.action) || settings.action || false;
  18746. url = $module.data(metadata.url) || settings.url || false;
  18747. if(url) {
  18748. module.debug('Using specified url', url);
  18749. return url;
  18750. }
  18751. if(action) {
  18752. module.debug('Looking up url for action', action, settings.api);
  18753. if(settings.api[action] === undefined && !module.is.mocked()) {
  18754. module.error(error.missingAction, settings.action, settings.api);
  18755. return;
  18756. }
  18757. url = settings.api[action];
  18758. }
  18759. else if( module.is.form() ) {
  18760. url = $module.attr('action') || $context.attr('action') || false;
  18761. module.debug('No url or action specified, defaulting to form action', url);
  18762. }
  18763. return url;
  18764. }
  18765. },
  18766. abort: function() {
  18767. var
  18768. xhr = module.get.xhr()
  18769. ;
  18770. if( xhr && xhr.state() !== 'resolved') {
  18771. module.debug('Cancelling API request');
  18772. xhr.abort();
  18773. }
  18774. },
  18775. // reset state
  18776. reset: function() {
  18777. module.remove.error();
  18778. module.remove.loading();
  18779. },
  18780. setting: function(name, value) {
  18781. module.debug('Changing setting', name, value);
  18782. if( $.isPlainObject(name) ) {
  18783. $.extend(true, settings, name);
  18784. }
  18785. else if(value !== undefined) {
  18786. if($.isPlainObject(settings[name])) {
  18787. $.extend(true, settings[name], value);
  18788. }
  18789. else {
  18790. settings[name] = value;
  18791. }
  18792. }
  18793. else {
  18794. return settings[name];
  18795. }
  18796. },
  18797. internal: function(name, value) {
  18798. if( $.isPlainObject(name) ) {
  18799. $.extend(true, module, name);
  18800. }
  18801. else if(value !== undefined) {
  18802. module[name] = value;
  18803. }
  18804. else {
  18805. return module[name];
  18806. }
  18807. },
  18808. debug: function() {
  18809. if(!settings.silent && settings.debug) {
  18810. if(settings.performance) {
  18811. module.performance.log(arguments);
  18812. }
  18813. else {
  18814. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  18815. module.debug.apply(console, arguments);
  18816. }
  18817. }
  18818. },
  18819. verbose: function() {
  18820. if(!settings.silent && settings.verbose && settings.debug) {
  18821. if(settings.performance) {
  18822. module.performance.log(arguments);
  18823. }
  18824. else {
  18825. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  18826. module.verbose.apply(console, arguments);
  18827. }
  18828. }
  18829. },
  18830. error: function() {
  18831. if(!settings.silent) {
  18832. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  18833. module.error.apply(console, arguments);
  18834. }
  18835. },
  18836. performance: {
  18837. log: function(message) {
  18838. var
  18839. currentTime,
  18840. executionTime,
  18841. previousTime
  18842. ;
  18843. if(settings.performance) {
  18844. currentTime = new Date().getTime();
  18845. previousTime = time || currentTime;
  18846. executionTime = currentTime - previousTime;
  18847. time = currentTime;
  18848. performance.push({
  18849. 'Name' : message[0],
  18850. 'Arguments' : [].slice.call(message, 1) || '',
  18851. //'Element' : element,
  18852. 'Execution Time' : executionTime
  18853. });
  18854. }
  18855. clearTimeout(module.performance.timer);
  18856. module.performance.timer = setTimeout(module.performance.display, 500);
  18857. },
  18858. display: function() {
  18859. var
  18860. title = settings.name + ':',
  18861. totalTime = 0
  18862. ;
  18863. time = false;
  18864. clearTimeout(module.performance.timer);
  18865. $.each(performance, function(index, data) {
  18866. totalTime += data['Execution Time'];
  18867. });
  18868. title += ' ' + totalTime + 'ms';
  18869. if(moduleSelector) {
  18870. title += ' \'' + moduleSelector + '\'';
  18871. }
  18872. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  18873. console.groupCollapsed(title);
  18874. if(console.table) {
  18875. console.table(performance);
  18876. }
  18877. else {
  18878. $.each(performance, function(index, data) {
  18879. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  18880. });
  18881. }
  18882. console.groupEnd();
  18883. }
  18884. performance = [];
  18885. }
  18886. },
  18887. invoke: function(query, passedArguments, context) {
  18888. var
  18889. object = instance,
  18890. maxDepth,
  18891. found,
  18892. response
  18893. ;
  18894. passedArguments = passedArguments || queryArguments;
  18895. context = element || context;
  18896. if(typeof query == 'string' && object !== undefined) {
  18897. query = query.split(/[\. ]/);
  18898. maxDepth = query.length - 1;
  18899. $.each(query, function(depth, value) {
  18900. var camelCaseValue = (depth != maxDepth)
  18901. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  18902. : query
  18903. ;
  18904. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  18905. object = object[camelCaseValue];
  18906. }
  18907. else if( object[camelCaseValue] !== undefined ) {
  18908. found = object[camelCaseValue];
  18909. return false;
  18910. }
  18911. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  18912. object = object[value];
  18913. }
  18914. else if( object[value] !== undefined ) {
  18915. found = object[value];
  18916. return false;
  18917. }
  18918. else {
  18919. module.error(error.method, query);
  18920. return false;
  18921. }
  18922. });
  18923. }
  18924. if ( $.isFunction( found ) ) {
  18925. response = found.apply(context, passedArguments);
  18926. }
  18927. else if(found !== undefined) {
  18928. response = found;
  18929. }
  18930. if($.isArray(returnedValue)) {
  18931. returnedValue.push(response);
  18932. }
  18933. else if(returnedValue !== undefined) {
  18934. returnedValue = [returnedValue, response];
  18935. }
  18936. else if(response !== undefined) {
  18937. returnedValue = response;
  18938. }
  18939. return found;
  18940. }
  18941. };
  18942. if(methodInvoked) {
  18943. if(instance === undefined) {
  18944. module.initialize();
  18945. }
  18946. module.invoke(query);
  18947. }
  18948. else {
  18949. if(instance !== undefined) {
  18950. instance.invoke('destroy');
  18951. }
  18952. module.initialize();
  18953. }
  18954. })
  18955. ;
  18956. return (returnedValue !== undefined)
  18957. ? returnedValue
  18958. : this
  18959. ;
  18960. };
  18961. $.api.settings = {
  18962. name : 'API',
  18963. namespace : 'api',
  18964. debug : false,
  18965. verbose : false,
  18966. performance : true,
  18967. // object containing all templates endpoints
  18968. api : {},
  18969. // whether to cache responses
  18970. cache : true,
  18971. // whether new requests should abort previous requests
  18972. interruptRequests : true,
  18973. // event binding
  18974. on : 'auto',
  18975. // context for applying state classes
  18976. stateContext : false,
  18977. // duration for loading state
  18978. loadingDuration : 0,
  18979. // whether to hide errors after a period of time
  18980. hideError : 'auto',
  18981. // duration for error state
  18982. errorDuration : 2000,
  18983. // whether parameters should be encoded with encodeURIComponent
  18984. encodeParameters : true,
  18985. // API action to use
  18986. action : false,
  18987. // templated URL to use
  18988. url : false,
  18989. // base URL to apply to all endpoints
  18990. base : '',
  18991. // data that will
  18992. urlData : {},
  18993. // whether to add default data to url data
  18994. defaultData : true,
  18995. // whether to serialize closest form
  18996. serializeForm : false,
  18997. // how long to wait before request should occur
  18998. throttle : 0,
  18999. // whether to throttle first request or only repeated
  19000. throttleFirstRequest : true,
  19001. // standard ajax settings
  19002. method : 'get',
  19003. data : {},
  19004. dataType : 'json',
  19005. // mock response
  19006. mockResponse : false,
  19007. mockResponseAsync : false,
  19008. // aliases for mock
  19009. response : false,
  19010. responseAsync : false,
  19011. // callbacks before request
  19012. beforeSend : function(settings) { return settings; },
  19013. beforeXHR : function(xhr) {},
  19014. onRequest : function(promise, xhr) {},
  19015. // after request
  19016. onResponse : false, // function(response) { },
  19017. // response was successful, if JSON passed validation
  19018. onSuccess : function(response, $module) {},
  19019. // request finished without aborting
  19020. onComplete : function(response, $module) {},
  19021. // failed JSON success test
  19022. onFailure : function(response, $module) {},
  19023. // server error
  19024. onError : function(errorMessage, $module) {},
  19025. // request aborted
  19026. onAbort : function(errorMessage, $module) {},
  19027. successTest : false,
  19028. // errors
  19029. error : {
  19030. beforeSend : 'The before send function has aborted the request',
  19031. error : 'There was an error with your request',
  19032. exitConditions : 'API Request Aborted. Exit conditions met',
  19033. JSONParse : 'JSON could not be parsed during error handling',
  19034. legacyParameters : 'You are using legacy API success callback names',
  19035. method : 'The method you called is not defined',
  19036. missingAction : 'API action used but no url was defined',
  19037. missingSerialize : 'jquery-serialize-object is required to add form data to an existing data object',
  19038. missingURL : 'No URL specified for api event',
  19039. noReturnedValue : 'The beforeSend callback must return a settings object, beforeSend ignored.',
  19040. noStorage : 'Caching responses locally requires session storage',
  19041. parseError : 'There was an error parsing your request',
  19042. requiredParameter : 'Missing a required URL parameter: ',
  19043. statusMessage : 'Server gave an error: ',
  19044. timeout : 'Your request timed out'
  19045. },
  19046. regExp : {
  19047. required : /\{\$*[A-z0-9]+\}/g,
  19048. optional : /\{\/\$*[A-z0-9]+\}/g,
  19049. },
  19050. className: {
  19051. loading : 'loading',
  19052. error : 'error'
  19053. },
  19054. selector: {
  19055. disabled : '.disabled',
  19056. form : 'form'
  19057. },
  19058. metadata: {
  19059. action : 'action',
  19060. url : 'url'
  19061. }
  19062. };
  19063. })( jQuery, window, document );
  19064. /*!
  19065. * # Semantic UI 2.2.6 - State
  19066. * http://github.com/semantic-org/semantic-ui/
  19067. *
  19068. *
  19069. * Released under the MIT license
  19070. * http://opensource.org/licenses/MIT
  19071. *
  19072. */
  19073. ;(function ($, window, document, undefined) {
  19074. "use strict";
  19075. window = (typeof window != 'undefined' && window.Math == Math)
  19076. ? window
  19077. : (typeof self != 'undefined' && self.Math == Math)
  19078. ? self
  19079. : Function('return this')()
  19080. ;
  19081. $.fn.state = function(parameters) {
  19082. var
  19083. $allModules = $(this),
  19084. moduleSelector = $allModules.selector || '',
  19085. hasTouch = ('ontouchstart' in document.documentElement),
  19086. time = new Date().getTime(),
  19087. performance = [],
  19088. query = arguments[0],
  19089. methodInvoked = (typeof query == 'string'),
  19090. queryArguments = [].slice.call(arguments, 1),
  19091. returnedValue
  19092. ;
  19093. $allModules
  19094. .each(function() {
  19095. var
  19096. settings = ( $.isPlainObject(parameters) )
  19097. ? $.extend(true, {}, $.fn.state.settings, parameters)
  19098. : $.extend({}, $.fn.state.settings),
  19099. error = settings.error,
  19100. metadata = settings.metadata,
  19101. className = settings.className,
  19102. namespace = settings.namespace,
  19103. states = settings.states,
  19104. text = settings.text,
  19105. eventNamespace = '.' + namespace,
  19106. moduleNamespace = namespace + '-module',
  19107. $module = $(this),
  19108. element = this,
  19109. instance = $module.data(moduleNamespace),
  19110. module
  19111. ;
  19112. module = {
  19113. initialize: function() {
  19114. module.verbose('Initializing module');
  19115. // allow module to guess desired state based on element
  19116. if(settings.automatic) {
  19117. module.add.defaults();
  19118. }
  19119. // bind events with delegated events
  19120. if(settings.context && moduleSelector !== '') {
  19121. $(settings.context)
  19122. .on(moduleSelector, 'mouseenter' + eventNamespace, module.change.text)
  19123. .on(moduleSelector, 'mouseleave' + eventNamespace, module.reset.text)
  19124. .on(moduleSelector, 'click' + eventNamespace, module.toggle.state)
  19125. ;
  19126. }
  19127. else {
  19128. $module
  19129. .on('mouseenter' + eventNamespace, module.change.text)
  19130. .on('mouseleave' + eventNamespace, module.reset.text)
  19131. .on('click' + eventNamespace, module.toggle.state)
  19132. ;
  19133. }
  19134. module.instantiate();
  19135. },
  19136. instantiate: function() {
  19137. module.verbose('Storing instance of module', module);
  19138. instance = module;
  19139. $module
  19140. .data(moduleNamespace, module)
  19141. ;
  19142. },
  19143. destroy: function() {
  19144. module.verbose('Destroying previous module', instance);
  19145. $module
  19146. .off(eventNamespace)
  19147. .removeData(moduleNamespace)
  19148. ;
  19149. },
  19150. refresh: function() {
  19151. module.verbose('Refreshing selector cache');
  19152. $module = $(element);
  19153. },
  19154. add: {
  19155. defaults: function() {
  19156. var
  19157. userStates = parameters && $.isPlainObject(parameters.states)
  19158. ? parameters.states
  19159. : {}
  19160. ;
  19161. $.each(settings.defaults, function(type, typeStates) {
  19162. if( module.is[type] !== undefined && module.is[type]() ) {
  19163. module.verbose('Adding default states', type, element);
  19164. $.extend(settings.states, typeStates, userStates);
  19165. }
  19166. });
  19167. }
  19168. },
  19169. is: {
  19170. active: function() {
  19171. return $module.hasClass(className.active);
  19172. },
  19173. loading: function() {
  19174. return $module.hasClass(className.loading);
  19175. },
  19176. inactive: function() {
  19177. return !( $module.hasClass(className.active) );
  19178. },
  19179. state: function(state) {
  19180. if(className[state] === undefined) {
  19181. return false;
  19182. }
  19183. return $module.hasClass( className[state] );
  19184. },
  19185. enabled: function() {
  19186. return !( $module.is(settings.filter.active) );
  19187. },
  19188. disabled: function() {
  19189. return ( $module.is(settings.filter.active) );
  19190. },
  19191. textEnabled: function() {
  19192. return !( $module.is(settings.filter.text) );
  19193. },
  19194. // definitions for automatic type detection
  19195. button: function() {
  19196. return $module.is('.button:not(a, .submit)');
  19197. },
  19198. input: function() {
  19199. return $module.is('input');
  19200. },
  19201. progress: function() {
  19202. return $module.is('.ui.progress');
  19203. }
  19204. },
  19205. allow: function(state) {
  19206. module.debug('Now allowing state', state);
  19207. states[state] = true;
  19208. },
  19209. disallow: function(state) {
  19210. module.debug('No longer allowing', state);
  19211. states[state] = false;
  19212. },
  19213. allows: function(state) {
  19214. return states[state] || false;
  19215. },
  19216. enable: function() {
  19217. $module.removeClass(className.disabled);
  19218. },
  19219. disable: function() {
  19220. $module.addClass(className.disabled);
  19221. },
  19222. setState: function(state) {
  19223. if(module.allows(state)) {
  19224. $module.addClass( className[state] );
  19225. }
  19226. },
  19227. removeState: function(state) {
  19228. if(module.allows(state)) {
  19229. $module.removeClass( className[state] );
  19230. }
  19231. },
  19232. toggle: {
  19233. state: function() {
  19234. var
  19235. apiRequest,
  19236. requestCancelled
  19237. ;
  19238. if( module.allows('active') && module.is.enabled() ) {
  19239. module.refresh();
  19240. if($.fn.api !== undefined) {
  19241. apiRequest = $module.api('get request');
  19242. requestCancelled = $module.api('was cancelled');
  19243. if( requestCancelled ) {
  19244. module.debug('API Request cancelled by beforesend');
  19245. settings.activateTest = function(){ return false; };
  19246. settings.deactivateTest = function(){ return false; };
  19247. }
  19248. else if(apiRequest) {
  19249. module.listenTo(apiRequest);
  19250. return;
  19251. }
  19252. }
  19253. module.change.state();
  19254. }
  19255. }
  19256. },
  19257. listenTo: function(apiRequest) {
  19258. module.debug('API request detected, waiting for state signal', apiRequest);
  19259. if(apiRequest) {
  19260. if(text.loading) {
  19261. module.update.text(text.loading);
  19262. }
  19263. $.when(apiRequest)
  19264. .then(function() {
  19265. if(apiRequest.state() == 'resolved') {
  19266. module.debug('API request succeeded');
  19267. settings.activateTest = function(){ return true; };
  19268. settings.deactivateTest = function(){ return true; };
  19269. }
  19270. else {
  19271. module.debug('API request failed');
  19272. settings.activateTest = function(){ return false; };
  19273. settings.deactivateTest = function(){ return false; };
  19274. }
  19275. module.change.state();
  19276. })
  19277. ;
  19278. }
  19279. },
  19280. // checks whether active/inactive state can be given
  19281. change: {
  19282. state: function() {
  19283. module.debug('Determining state change direction');
  19284. // inactive to active change
  19285. if( module.is.inactive() ) {
  19286. module.activate();
  19287. }
  19288. else {
  19289. module.deactivate();
  19290. }
  19291. if(settings.sync) {
  19292. module.sync();
  19293. }
  19294. settings.onChange.call(element);
  19295. },
  19296. text: function() {
  19297. if( module.is.textEnabled() ) {
  19298. if(module.is.disabled() ) {
  19299. module.verbose('Changing text to disabled text', text.hover);
  19300. module.update.text(text.disabled);
  19301. }
  19302. else if( module.is.active() ) {
  19303. if(text.hover) {
  19304. module.verbose('Changing text to hover text', text.hover);
  19305. module.update.text(text.hover);
  19306. }
  19307. else if(text.deactivate) {
  19308. module.verbose('Changing text to deactivating text', text.deactivate);
  19309. module.update.text(text.deactivate);
  19310. }
  19311. }
  19312. else {
  19313. if(text.hover) {
  19314. module.verbose('Changing text to hover text', text.hover);
  19315. module.update.text(text.hover);
  19316. }
  19317. else if(text.activate){
  19318. module.verbose('Changing text to activating text', text.activate);
  19319. module.update.text(text.activate);
  19320. }
  19321. }
  19322. }
  19323. }
  19324. },
  19325. activate: function() {
  19326. if( settings.activateTest.call(element) ) {
  19327. module.debug('Setting state to active');
  19328. $module
  19329. .addClass(className.active)
  19330. ;
  19331. module.update.text(text.active);
  19332. settings.onActivate.call(element);
  19333. }
  19334. },
  19335. deactivate: function() {
  19336. if( settings.deactivateTest.call(element) ) {
  19337. module.debug('Setting state to inactive');
  19338. $module
  19339. .removeClass(className.active)
  19340. ;
  19341. module.update.text(text.inactive);
  19342. settings.onDeactivate.call(element);
  19343. }
  19344. },
  19345. sync: function() {
  19346. module.verbose('Syncing other buttons to current state');
  19347. if( module.is.active() ) {
  19348. $allModules
  19349. .not($module)
  19350. .state('activate');
  19351. }
  19352. else {
  19353. $allModules
  19354. .not($module)
  19355. .state('deactivate')
  19356. ;
  19357. }
  19358. },
  19359. get: {
  19360. text: function() {
  19361. return (settings.selector.text)
  19362. ? $module.find(settings.selector.text).text()
  19363. : $module.html()
  19364. ;
  19365. },
  19366. textFor: function(state) {
  19367. return text[state] || false;
  19368. }
  19369. },
  19370. flash: {
  19371. text: function(text, duration, callback) {
  19372. var
  19373. previousText = module.get.text()
  19374. ;
  19375. module.debug('Flashing text message', text, duration);
  19376. text = text || settings.text.flash;
  19377. duration = duration || settings.flashDuration;
  19378. callback = callback || function() {};
  19379. module.update.text(text);
  19380. setTimeout(function(){
  19381. module.update.text(previousText);
  19382. callback.call(element);
  19383. }, duration);
  19384. }
  19385. },
  19386. reset: {
  19387. // on mouseout sets text to previous value
  19388. text: function() {
  19389. var
  19390. activeText = text.active || $module.data(metadata.storedText),
  19391. inactiveText = text.inactive || $module.data(metadata.storedText)
  19392. ;
  19393. if( module.is.textEnabled() ) {
  19394. if( module.is.active() && activeText) {
  19395. module.verbose('Resetting active text', activeText);
  19396. module.update.text(activeText);
  19397. }
  19398. else if(inactiveText) {
  19399. module.verbose('Resetting inactive text', activeText);
  19400. module.update.text(inactiveText);
  19401. }
  19402. }
  19403. }
  19404. },
  19405. update: {
  19406. text: function(text) {
  19407. var
  19408. currentText = module.get.text()
  19409. ;
  19410. if(text && text !== currentText) {
  19411. module.debug('Updating text', text);
  19412. if(settings.selector.text) {
  19413. $module
  19414. .data(metadata.storedText, text)
  19415. .find(settings.selector.text)
  19416. .text(text)
  19417. ;
  19418. }
  19419. else {
  19420. $module
  19421. .data(metadata.storedText, text)
  19422. .html(text)
  19423. ;
  19424. }
  19425. }
  19426. else {
  19427. module.debug('Text is already set, ignoring update', text);
  19428. }
  19429. }
  19430. },
  19431. setting: function(name, value) {
  19432. module.debug('Changing setting', name, value);
  19433. if( $.isPlainObject(name) ) {
  19434. $.extend(true, settings, name);
  19435. }
  19436. else if(value !== undefined) {
  19437. if($.isPlainObject(settings[name])) {
  19438. $.extend(true, settings[name], value);
  19439. }
  19440. else {
  19441. settings[name] = value;
  19442. }
  19443. }
  19444. else {
  19445. return settings[name];
  19446. }
  19447. },
  19448. internal: function(name, value) {
  19449. if( $.isPlainObject(name) ) {
  19450. $.extend(true, module, name);
  19451. }
  19452. else if(value !== undefined) {
  19453. module[name] = value;
  19454. }
  19455. else {
  19456. return module[name];
  19457. }
  19458. },
  19459. debug: function() {
  19460. if(!settings.silent && settings.debug) {
  19461. if(settings.performance) {
  19462. module.performance.log(arguments);
  19463. }
  19464. else {
  19465. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  19466. module.debug.apply(console, arguments);
  19467. }
  19468. }
  19469. },
  19470. verbose: function() {
  19471. if(!settings.silent && settings.verbose && settings.debug) {
  19472. if(settings.performance) {
  19473. module.performance.log(arguments);
  19474. }
  19475. else {
  19476. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  19477. module.verbose.apply(console, arguments);
  19478. }
  19479. }
  19480. },
  19481. error: function() {
  19482. if(!settings.silent) {
  19483. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  19484. module.error.apply(console, arguments);
  19485. }
  19486. },
  19487. performance: {
  19488. log: function(message) {
  19489. var
  19490. currentTime,
  19491. executionTime,
  19492. previousTime
  19493. ;
  19494. if(settings.performance) {
  19495. currentTime = new Date().getTime();
  19496. previousTime = time || currentTime;
  19497. executionTime = currentTime - previousTime;
  19498. time = currentTime;
  19499. performance.push({
  19500. 'Name' : message[0],
  19501. 'Arguments' : [].slice.call(message, 1) || '',
  19502. 'Element' : element,
  19503. 'Execution Time' : executionTime
  19504. });
  19505. }
  19506. clearTimeout(module.performance.timer);
  19507. module.performance.timer = setTimeout(module.performance.display, 500);
  19508. },
  19509. display: function() {
  19510. var
  19511. title = settings.name + ':',
  19512. totalTime = 0
  19513. ;
  19514. time = false;
  19515. clearTimeout(module.performance.timer);
  19516. $.each(performance, function(index, data) {
  19517. totalTime += data['Execution Time'];
  19518. });
  19519. title += ' ' + totalTime + 'ms';
  19520. if(moduleSelector) {
  19521. title += ' \'' + moduleSelector + '\'';
  19522. }
  19523. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  19524. console.groupCollapsed(title);
  19525. if(console.table) {
  19526. console.table(performance);
  19527. }
  19528. else {
  19529. $.each(performance, function(index, data) {
  19530. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  19531. });
  19532. }
  19533. console.groupEnd();
  19534. }
  19535. performance = [];
  19536. }
  19537. },
  19538. invoke: function(query, passedArguments, context) {
  19539. var
  19540. object = instance,
  19541. maxDepth,
  19542. found,
  19543. response
  19544. ;
  19545. passedArguments = passedArguments || queryArguments;
  19546. context = element || context;
  19547. if(typeof query == 'string' && object !== undefined) {
  19548. query = query.split(/[\. ]/);
  19549. maxDepth = query.length - 1;
  19550. $.each(query, function(depth, value) {
  19551. var camelCaseValue = (depth != maxDepth)
  19552. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  19553. : query
  19554. ;
  19555. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  19556. object = object[camelCaseValue];
  19557. }
  19558. else if( object[camelCaseValue] !== undefined ) {
  19559. found = object[camelCaseValue];
  19560. return false;
  19561. }
  19562. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  19563. object = object[value];
  19564. }
  19565. else if( object[value] !== undefined ) {
  19566. found = object[value];
  19567. return false;
  19568. }
  19569. else {
  19570. module.error(error.method, query);
  19571. return false;
  19572. }
  19573. });
  19574. }
  19575. if ( $.isFunction( found ) ) {
  19576. response = found.apply(context, passedArguments);
  19577. }
  19578. else if(found !== undefined) {
  19579. response = found;
  19580. }
  19581. if($.isArray(returnedValue)) {
  19582. returnedValue.push(response);
  19583. }
  19584. else if(returnedValue !== undefined) {
  19585. returnedValue = [returnedValue, response];
  19586. }
  19587. else if(response !== undefined) {
  19588. returnedValue = response;
  19589. }
  19590. return found;
  19591. }
  19592. };
  19593. if(methodInvoked) {
  19594. if(instance === undefined) {
  19595. module.initialize();
  19596. }
  19597. module.invoke(query);
  19598. }
  19599. else {
  19600. if(instance !== undefined) {
  19601. instance.invoke('destroy');
  19602. }
  19603. module.initialize();
  19604. }
  19605. })
  19606. ;
  19607. return (returnedValue !== undefined)
  19608. ? returnedValue
  19609. : this
  19610. ;
  19611. };
  19612. $.fn.state.settings = {
  19613. // module info
  19614. name : 'State',
  19615. // debug output
  19616. debug : false,
  19617. // verbose debug output
  19618. verbose : false,
  19619. // namespace for events
  19620. namespace : 'state',
  19621. // debug data includes performance
  19622. performance : true,
  19623. // callback occurs on state change
  19624. onActivate : function() {},
  19625. onDeactivate : function() {},
  19626. onChange : function() {},
  19627. // state test functions
  19628. activateTest : function() { return true; },
  19629. deactivateTest : function() { return true; },
  19630. // whether to automatically map default states
  19631. automatic : true,
  19632. // activate / deactivate changes all elements instantiated at same time
  19633. sync : false,
  19634. // default flash text duration, used for temporarily changing text of an element
  19635. flashDuration : 1000,
  19636. // selector filter
  19637. filter : {
  19638. text : '.loading, .disabled',
  19639. active : '.disabled'
  19640. },
  19641. context : false,
  19642. // error
  19643. error: {
  19644. beforeSend : 'The before send function has cancelled state change',
  19645. method : 'The method you called is not defined.'
  19646. },
  19647. // metadata
  19648. metadata: {
  19649. promise : 'promise',
  19650. storedText : 'stored-text'
  19651. },
  19652. // change class on state
  19653. className: {
  19654. active : 'active',
  19655. disabled : 'disabled',
  19656. error : 'error',
  19657. loading : 'loading',
  19658. success : 'success',
  19659. warning : 'warning'
  19660. },
  19661. selector: {
  19662. // selector for text node
  19663. text: false
  19664. },
  19665. defaults : {
  19666. input: {
  19667. disabled : true,
  19668. loading : true,
  19669. active : true
  19670. },
  19671. button: {
  19672. disabled : true,
  19673. loading : true,
  19674. active : true,
  19675. },
  19676. progress: {
  19677. active : true,
  19678. success : true,
  19679. warning : true,
  19680. error : true
  19681. }
  19682. },
  19683. states : {
  19684. active : true,
  19685. disabled : true,
  19686. error : true,
  19687. loading : true,
  19688. success : true,
  19689. warning : true
  19690. },
  19691. text : {
  19692. disabled : false,
  19693. flash : false,
  19694. hover : false,
  19695. active : false,
  19696. inactive : false,
  19697. activate : false,
  19698. deactivate : false
  19699. }
  19700. };
  19701. })( jQuery, window, document );
  19702. /*!
  19703. * # Semantic UI 2.2.6 - Visibility
  19704. * http://github.com/semantic-org/semantic-ui/
  19705. *
  19706. *
  19707. * Released under the MIT license
  19708. * http://opensource.org/licenses/MIT
  19709. *
  19710. */
  19711. ;(function ($, window, document, undefined) {
  19712. "use strict";
  19713. window = (typeof window != 'undefined' && window.Math == Math)
  19714. ? window
  19715. : (typeof self != 'undefined' && self.Math == Math)
  19716. ? self
  19717. : Function('return this')()
  19718. ;
  19719. $.fn.visibility = function(parameters) {
  19720. var
  19721. $allModules = $(this),
  19722. moduleSelector = $allModules.selector || '',
  19723. time = new Date().getTime(),
  19724. performance = [],
  19725. query = arguments[0],
  19726. methodInvoked = (typeof query == 'string'),
  19727. queryArguments = [].slice.call(arguments, 1),
  19728. returnedValue,
  19729. moduleCount = $allModules.length,
  19730. loadedCount = 0
  19731. ;
  19732. $allModules
  19733. .each(function() {
  19734. var
  19735. settings = ( $.isPlainObject(parameters) )
  19736. ? $.extend(true, {}, $.fn.visibility.settings, parameters)
  19737. : $.extend({}, $.fn.visibility.settings),
  19738. className = settings.className,
  19739. namespace = settings.namespace,
  19740. error = settings.error,
  19741. metadata = settings.metadata,
  19742. eventNamespace = '.' + namespace,
  19743. moduleNamespace = 'module-' + namespace,
  19744. $window = $(window),
  19745. $module = $(this),
  19746. $context = $(settings.context),
  19747. $placeholder,
  19748. selector = $module.selector || '',
  19749. instance = $module.data(moduleNamespace),
  19750. requestAnimationFrame = window.requestAnimationFrame
  19751. || window.mozRequestAnimationFrame
  19752. || window.webkitRequestAnimationFrame
  19753. || window.msRequestAnimationFrame
  19754. || function(callback) { setTimeout(callback, 0); },
  19755. element = this,
  19756. disabled = false,
  19757. contextObserver,
  19758. observer,
  19759. module
  19760. ;
  19761. module = {
  19762. initialize: function() {
  19763. module.debug('Initializing', settings);
  19764. module.setup.cache();
  19765. if( module.should.trackChanges() ) {
  19766. if(settings.type == 'image') {
  19767. module.setup.image();
  19768. }
  19769. if(settings.type == 'fixed') {
  19770. module.setup.fixed();
  19771. }
  19772. if(settings.observeChanges) {
  19773. module.observeChanges();
  19774. }
  19775. module.bind.events();
  19776. }
  19777. module.save.position();
  19778. if( !module.is.visible() ) {
  19779. module.error(error.visible, $module);
  19780. }
  19781. if(settings.initialCheck) {
  19782. module.checkVisibility();
  19783. }
  19784. module.instantiate();
  19785. },
  19786. instantiate: function() {
  19787. module.debug('Storing instance', module);
  19788. $module
  19789. .data(moduleNamespace, module)
  19790. ;
  19791. instance = module;
  19792. },
  19793. destroy: function() {
  19794. module.verbose('Destroying previous module');
  19795. if(observer) {
  19796. observer.disconnect();
  19797. }
  19798. if(contextObserver) {
  19799. contextObserver.disconnect();
  19800. }
  19801. $window
  19802. .off('load' + eventNamespace, module.event.load)
  19803. .off('resize' + eventNamespace, module.event.resize)
  19804. ;
  19805. $context
  19806. .off('scroll' + eventNamespace, module.event.scroll)
  19807. .off('scrollchange' + eventNamespace, module.event.scrollchange)
  19808. ;
  19809. if(settings.type == 'fixed') {
  19810. module.resetFixed();
  19811. module.remove.placeholder();
  19812. }
  19813. $module
  19814. .off(eventNamespace)
  19815. .removeData(moduleNamespace)
  19816. ;
  19817. },
  19818. observeChanges: function() {
  19819. if('MutationObserver' in window) {
  19820. contextObserver = new MutationObserver(module.event.contextChanged);
  19821. observer = new MutationObserver(module.event.changed);
  19822. contextObserver.observe(document, {
  19823. childList : true,
  19824. subtree : true
  19825. });
  19826. observer.observe(element, {
  19827. childList : true,
  19828. subtree : true
  19829. });
  19830. module.debug('Setting up mutation observer', observer);
  19831. }
  19832. },
  19833. bind: {
  19834. events: function() {
  19835. module.verbose('Binding visibility events to scroll and resize');
  19836. if(settings.refreshOnLoad) {
  19837. $window
  19838. .on('load' + eventNamespace, module.event.load)
  19839. ;
  19840. }
  19841. $window
  19842. .on('resize' + eventNamespace, module.event.resize)
  19843. ;
  19844. // pub/sub pattern
  19845. $context
  19846. .off('scroll' + eventNamespace)
  19847. .on('scroll' + eventNamespace, module.event.scroll)
  19848. .on('scrollchange' + eventNamespace, module.event.scrollchange)
  19849. ;
  19850. }
  19851. },
  19852. event: {
  19853. changed: function(mutations) {
  19854. module.verbose('DOM tree modified, updating visibility calculations');
  19855. module.timer = setTimeout(function() {
  19856. module.verbose('DOM tree modified, updating sticky menu');
  19857. module.refresh();
  19858. }, 100);
  19859. },
  19860. contextChanged: function(mutations) {
  19861. [].forEach.call(mutations, function(mutation) {
  19862. if(mutation.removedNodes) {
  19863. [].forEach.call(mutation.removedNodes, function(node) {
  19864. if(node == element || $(node).find(element).length > 0) {
  19865. module.debug('Element removed from DOM, tearing down events');
  19866. module.destroy();
  19867. }
  19868. });
  19869. }
  19870. });
  19871. },
  19872. resize: function() {
  19873. module.debug('Window resized');
  19874. if(settings.refreshOnResize) {
  19875. requestAnimationFrame(module.refresh);
  19876. }
  19877. },
  19878. load: function() {
  19879. module.debug('Page finished loading');
  19880. requestAnimationFrame(module.refresh);
  19881. },
  19882. // publishes scrollchange event on one scroll
  19883. scroll: function() {
  19884. if(settings.throttle) {
  19885. clearTimeout(module.timer);
  19886. module.timer = setTimeout(function() {
  19887. $context.triggerHandler('scrollchange' + eventNamespace, [ $context.scrollTop() ]);
  19888. }, settings.throttle);
  19889. }
  19890. else {
  19891. requestAnimationFrame(function() {
  19892. $context.triggerHandler('scrollchange' + eventNamespace, [ $context.scrollTop() ]);
  19893. });
  19894. }
  19895. },
  19896. // subscribes to scrollchange
  19897. scrollchange: function(event, scrollPosition) {
  19898. module.checkVisibility(scrollPosition);
  19899. },
  19900. },
  19901. precache: function(images, callback) {
  19902. if (!(images instanceof Array)) {
  19903. images = [images];
  19904. }
  19905. var
  19906. imagesLength = images.length,
  19907. loadedCounter = 0,
  19908. cache = [],
  19909. cacheImage = document.createElement('img'),
  19910. handleLoad = function() {
  19911. loadedCounter++;
  19912. if (loadedCounter >= images.length) {
  19913. if ($.isFunction(callback)) {
  19914. callback();
  19915. }
  19916. }
  19917. }
  19918. ;
  19919. while (imagesLength--) {
  19920. cacheImage = document.createElement('img');
  19921. cacheImage.onload = handleLoad;
  19922. cacheImage.onerror = handleLoad;
  19923. cacheImage.src = images[imagesLength];
  19924. cache.push(cacheImage);
  19925. }
  19926. },
  19927. enableCallbacks: function() {
  19928. module.debug('Allowing callbacks to occur');
  19929. disabled = false;
  19930. },
  19931. disableCallbacks: function() {
  19932. module.debug('Disabling all callbacks temporarily');
  19933. disabled = true;
  19934. },
  19935. should: {
  19936. trackChanges: function() {
  19937. if(methodInvoked) {
  19938. module.debug('One time query, no need to bind events');
  19939. return false;
  19940. }
  19941. module.debug('Callbacks being attached');
  19942. return true;
  19943. }
  19944. },
  19945. setup: {
  19946. cache: function() {
  19947. module.cache = {
  19948. occurred : {},
  19949. screen : {},
  19950. element : {},
  19951. };
  19952. },
  19953. image: function() {
  19954. var
  19955. src = $module.data(metadata.src)
  19956. ;
  19957. if(src) {
  19958. module.verbose('Lazy loading image', src);
  19959. settings.once = true;
  19960. settings.observeChanges = false;
  19961. // show when top visible
  19962. settings.onOnScreen = function() {
  19963. module.debug('Image on screen', element);
  19964. module.precache(src, function() {
  19965. module.set.image(src, function() {
  19966. loadedCount++;
  19967. if(loadedCount == moduleCount) {
  19968. settings.onAllLoaded.call(this);
  19969. }
  19970. settings.onLoad.call(this);
  19971. });
  19972. });
  19973. };
  19974. }
  19975. },
  19976. fixed: function() {
  19977. module.debug('Setting up fixed');
  19978. settings.once = false;
  19979. settings.observeChanges = false;
  19980. settings.initialCheck = true;
  19981. settings.refreshOnLoad = true;
  19982. if(!parameters.transition) {
  19983. settings.transition = false;
  19984. }
  19985. module.create.placeholder();
  19986. module.debug('Added placeholder', $placeholder);
  19987. settings.onTopPassed = function() {
  19988. module.debug('Element passed, adding fixed position', $module);
  19989. module.show.placeholder();
  19990. module.set.fixed();
  19991. if(settings.transition) {
  19992. if($.fn.transition !== undefined) {
  19993. $module.transition(settings.transition, settings.duration);
  19994. }
  19995. }
  19996. };
  19997. settings.onTopPassedReverse = function() {
  19998. module.debug('Element returned to position, removing fixed', $module);
  19999. module.hide.placeholder();
  20000. module.remove.fixed();
  20001. };
  20002. }
  20003. },
  20004. create: {
  20005. placeholder: function() {
  20006. module.verbose('Creating fixed position placeholder');
  20007. $placeholder = $module
  20008. .clone(false)
  20009. .css('display', 'none')
  20010. .addClass(className.placeholder)
  20011. .insertAfter($module)
  20012. ;
  20013. }
  20014. },
  20015. show: {
  20016. placeholder: function() {
  20017. module.verbose('Showing placeholder');
  20018. $placeholder
  20019. .css('display', 'block')
  20020. .css('visibility', 'hidden')
  20021. ;
  20022. }
  20023. },
  20024. hide: {
  20025. placeholder: function() {
  20026. module.verbose('Hiding placeholder');
  20027. $placeholder
  20028. .css('display', 'none')
  20029. .css('visibility', '')
  20030. ;
  20031. }
  20032. },
  20033. set: {
  20034. fixed: function() {
  20035. module.verbose('Setting element to fixed position');
  20036. $module
  20037. .addClass(className.fixed)
  20038. .css({
  20039. position : 'fixed',
  20040. top : settings.offset + 'px',
  20041. left : 'auto',
  20042. zIndex : settings.zIndex
  20043. })
  20044. ;
  20045. settings.onFixed.call(element);
  20046. },
  20047. image: function(src, callback) {
  20048. $module
  20049. .attr('src', src)
  20050. ;
  20051. if(settings.transition) {
  20052. if( $.fn.transition !== undefined ) {
  20053. $module.transition(settings.transition, settings.duration, callback);
  20054. }
  20055. else {
  20056. $module.fadeIn(settings.duration, callback);
  20057. }
  20058. }
  20059. else {
  20060. $module.show();
  20061. }
  20062. }
  20063. },
  20064. is: {
  20065. onScreen: function() {
  20066. var
  20067. calculations = module.get.elementCalculations()
  20068. ;
  20069. return calculations.onScreen;
  20070. },
  20071. offScreen: function() {
  20072. var
  20073. calculations = module.get.elementCalculations()
  20074. ;
  20075. return calculations.offScreen;
  20076. },
  20077. visible: function() {
  20078. if(module.cache && module.cache.element) {
  20079. return !(module.cache.element.width === 0 && module.cache.element.offset.top === 0);
  20080. }
  20081. return false;
  20082. }
  20083. },
  20084. refresh: function() {
  20085. module.debug('Refreshing constants (width/height)');
  20086. if(settings.type == 'fixed') {
  20087. module.resetFixed();
  20088. }
  20089. module.reset();
  20090. module.save.position();
  20091. if(settings.checkOnRefresh) {
  20092. module.checkVisibility();
  20093. }
  20094. settings.onRefresh.call(element);
  20095. },
  20096. resetFixed: function () {
  20097. module.remove.fixed();
  20098. module.remove.occurred();
  20099. },
  20100. reset: function() {
  20101. module.verbose('Resetting all cached values');
  20102. if( $.isPlainObject(module.cache) ) {
  20103. module.cache.screen = {};
  20104. module.cache.element = {};
  20105. }
  20106. },
  20107. checkVisibility: function(scroll) {
  20108. module.verbose('Checking visibility of element', module.cache.element);
  20109. if( !disabled && module.is.visible() ) {
  20110. // save scroll position
  20111. module.save.scroll(scroll);
  20112. // update calculations derived from scroll
  20113. module.save.calculations();
  20114. // percentage
  20115. module.passed();
  20116. // reverse (must be first)
  20117. module.passingReverse();
  20118. module.topVisibleReverse();
  20119. module.bottomVisibleReverse();
  20120. module.topPassedReverse();
  20121. module.bottomPassedReverse();
  20122. // one time
  20123. module.onScreen();
  20124. module.offScreen();
  20125. module.passing();
  20126. module.topVisible();
  20127. module.bottomVisible();
  20128. module.topPassed();
  20129. module.bottomPassed();
  20130. // on update callback
  20131. if(settings.onUpdate) {
  20132. settings.onUpdate.call(element, module.get.elementCalculations());
  20133. }
  20134. }
  20135. },
  20136. passed: function(amount, newCallback) {
  20137. var
  20138. calculations = module.get.elementCalculations(),
  20139. amountInPixels
  20140. ;
  20141. // assign callback
  20142. if(amount && newCallback) {
  20143. settings.onPassed[amount] = newCallback;
  20144. }
  20145. else if(amount !== undefined) {
  20146. return (module.get.pixelsPassed(amount) > calculations.pixelsPassed);
  20147. }
  20148. else if(calculations.passing) {
  20149. $.each(settings.onPassed, function(amount, callback) {
  20150. if(calculations.bottomVisible || calculations.pixelsPassed > module.get.pixelsPassed(amount)) {
  20151. module.execute(callback, amount);
  20152. }
  20153. else if(!settings.once) {
  20154. module.remove.occurred(callback);
  20155. }
  20156. });
  20157. }
  20158. },
  20159. onScreen: function(newCallback) {
  20160. var
  20161. calculations = module.get.elementCalculations(),
  20162. callback = newCallback || settings.onOnScreen,
  20163. callbackName = 'onScreen'
  20164. ;
  20165. if(newCallback) {
  20166. module.debug('Adding callback for onScreen', newCallback);
  20167. settings.onOnScreen = newCallback;
  20168. }
  20169. if(calculations.onScreen) {
  20170. module.execute(callback, callbackName);
  20171. }
  20172. else if(!settings.once) {
  20173. module.remove.occurred(callbackName);
  20174. }
  20175. if(newCallback !== undefined) {
  20176. return calculations.onOnScreen;
  20177. }
  20178. },
  20179. offScreen: function(newCallback) {
  20180. var
  20181. calculations = module.get.elementCalculations(),
  20182. callback = newCallback || settings.onOffScreen,
  20183. callbackName = 'offScreen'
  20184. ;
  20185. if(newCallback) {
  20186. module.debug('Adding callback for offScreen', newCallback);
  20187. settings.onOffScreen = newCallback;
  20188. }
  20189. if(calculations.offScreen) {
  20190. module.execute(callback, callbackName);
  20191. }
  20192. else if(!settings.once) {
  20193. module.remove.occurred(callbackName);
  20194. }
  20195. if(newCallback !== undefined) {
  20196. return calculations.onOffScreen;
  20197. }
  20198. },
  20199. passing: function(newCallback) {
  20200. var
  20201. calculations = module.get.elementCalculations(),
  20202. callback = newCallback || settings.onPassing,
  20203. callbackName = 'passing'
  20204. ;
  20205. if(newCallback) {
  20206. module.debug('Adding callback for passing', newCallback);
  20207. settings.onPassing = newCallback;
  20208. }
  20209. if(calculations.passing) {
  20210. module.execute(callback, callbackName);
  20211. }
  20212. else if(!settings.once) {
  20213. module.remove.occurred(callbackName);
  20214. }
  20215. if(newCallback !== undefined) {
  20216. return calculations.passing;
  20217. }
  20218. },
  20219. topVisible: function(newCallback) {
  20220. var
  20221. calculations = module.get.elementCalculations(),
  20222. callback = newCallback || settings.onTopVisible,
  20223. callbackName = 'topVisible'
  20224. ;
  20225. if(newCallback) {
  20226. module.debug('Adding callback for top visible', newCallback);
  20227. settings.onTopVisible = newCallback;
  20228. }
  20229. if(calculations.topVisible) {
  20230. module.execute(callback, callbackName);
  20231. }
  20232. else if(!settings.once) {
  20233. module.remove.occurred(callbackName);
  20234. }
  20235. if(newCallback === undefined) {
  20236. return calculations.topVisible;
  20237. }
  20238. },
  20239. bottomVisible: function(newCallback) {
  20240. var
  20241. calculations = module.get.elementCalculations(),
  20242. callback = newCallback || settings.onBottomVisible,
  20243. callbackName = 'bottomVisible'
  20244. ;
  20245. if(newCallback) {
  20246. module.debug('Adding callback for bottom visible', newCallback);
  20247. settings.onBottomVisible = newCallback;
  20248. }
  20249. if(calculations.bottomVisible) {
  20250. module.execute(callback, callbackName);
  20251. }
  20252. else if(!settings.once) {
  20253. module.remove.occurred(callbackName);
  20254. }
  20255. if(newCallback === undefined) {
  20256. return calculations.bottomVisible;
  20257. }
  20258. },
  20259. topPassed: function(newCallback) {
  20260. var
  20261. calculations = module.get.elementCalculations(),
  20262. callback = newCallback || settings.onTopPassed,
  20263. callbackName = 'topPassed'
  20264. ;
  20265. if(newCallback) {
  20266. module.debug('Adding callback for top passed', newCallback);
  20267. settings.onTopPassed = newCallback;
  20268. }
  20269. if(calculations.topPassed) {
  20270. module.execute(callback, callbackName);
  20271. }
  20272. else if(!settings.once) {
  20273. module.remove.occurred(callbackName);
  20274. }
  20275. if(newCallback === undefined) {
  20276. return calculations.topPassed;
  20277. }
  20278. },
  20279. bottomPassed: function(newCallback) {
  20280. var
  20281. calculations = module.get.elementCalculations(),
  20282. callback = newCallback || settings.onBottomPassed,
  20283. callbackName = 'bottomPassed'
  20284. ;
  20285. if(newCallback) {
  20286. module.debug('Adding callback for bottom passed', newCallback);
  20287. settings.onBottomPassed = newCallback;
  20288. }
  20289. if(calculations.bottomPassed) {
  20290. module.execute(callback, callbackName);
  20291. }
  20292. else if(!settings.once) {
  20293. module.remove.occurred(callbackName);
  20294. }
  20295. if(newCallback === undefined) {
  20296. return calculations.bottomPassed;
  20297. }
  20298. },
  20299. passingReverse: function(newCallback) {
  20300. var
  20301. calculations = module.get.elementCalculations(),
  20302. callback = newCallback || settings.onPassingReverse,
  20303. callbackName = 'passingReverse'
  20304. ;
  20305. if(newCallback) {
  20306. module.debug('Adding callback for passing reverse', newCallback);
  20307. settings.onPassingReverse = newCallback;
  20308. }
  20309. if(!calculations.passing) {
  20310. if(module.get.occurred('passing')) {
  20311. module.execute(callback, callbackName);
  20312. }
  20313. }
  20314. else if(!settings.once) {
  20315. module.remove.occurred(callbackName);
  20316. }
  20317. if(newCallback !== undefined) {
  20318. return !calculations.passing;
  20319. }
  20320. },
  20321. topVisibleReverse: function(newCallback) {
  20322. var
  20323. calculations = module.get.elementCalculations(),
  20324. callback = newCallback || settings.onTopVisibleReverse,
  20325. callbackName = 'topVisibleReverse'
  20326. ;
  20327. if(newCallback) {
  20328. module.debug('Adding callback for top visible reverse', newCallback);
  20329. settings.onTopVisibleReverse = newCallback;
  20330. }
  20331. if(!calculations.topVisible) {
  20332. if(module.get.occurred('topVisible')) {
  20333. module.execute(callback, callbackName);
  20334. }
  20335. }
  20336. else if(!settings.once) {
  20337. module.remove.occurred(callbackName);
  20338. }
  20339. if(newCallback === undefined) {
  20340. return !calculations.topVisible;
  20341. }
  20342. },
  20343. bottomVisibleReverse: function(newCallback) {
  20344. var
  20345. calculations = module.get.elementCalculations(),
  20346. callback = newCallback || settings.onBottomVisibleReverse,
  20347. callbackName = 'bottomVisibleReverse'
  20348. ;
  20349. if(newCallback) {
  20350. module.debug('Adding callback for bottom visible reverse', newCallback);
  20351. settings.onBottomVisibleReverse = newCallback;
  20352. }
  20353. if(!calculations.bottomVisible) {
  20354. if(module.get.occurred('bottomVisible')) {
  20355. module.execute(callback, callbackName);
  20356. }
  20357. }
  20358. else if(!settings.once) {
  20359. module.remove.occurred(callbackName);
  20360. }
  20361. if(newCallback === undefined) {
  20362. return !calculations.bottomVisible;
  20363. }
  20364. },
  20365. topPassedReverse: function(newCallback) {
  20366. var
  20367. calculations = module.get.elementCalculations(),
  20368. callback = newCallback || settings.onTopPassedReverse,
  20369. callbackName = 'topPassedReverse'
  20370. ;
  20371. if(newCallback) {
  20372. module.debug('Adding callback for top passed reverse', newCallback);
  20373. settings.onTopPassedReverse = newCallback;
  20374. }
  20375. if(!calculations.topPassed) {
  20376. if(module.get.occurred('topPassed')) {
  20377. module.execute(callback, callbackName);
  20378. }
  20379. }
  20380. else if(!settings.once) {
  20381. module.remove.occurred(callbackName);
  20382. }
  20383. if(newCallback === undefined) {
  20384. return !calculations.onTopPassed;
  20385. }
  20386. },
  20387. bottomPassedReverse: function(newCallback) {
  20388. var
  20389. calculations = module.get.elementCalculations(),
  20390. callback = newCallback || settings.onBottomPassedReverse,
  20391. callbackName = 'bottomPassedReverse'
  20392. ;
  20393. if(newCallback) {
  20394. module.debug('Adding callback for bottom passed reverse', newCallback);
  20395. settings.onBottomPassedReverse = newCallback;
  20396. }
  20397. if(!calculations.bottomPassed) {
  20398. if(module.get.occurred('bottomPassed')) {
  20399. module.execute(callback, callbackName);
  20400. }
  20401. }
  20402. else if(!settings.once) {
  20403. module.remove.occurred(callbackName);
  20404. }
  20405. if(newCallback === undefined) {
  20406. return !calculations.bottomPassed;
  20407. }
  20408. },
  20409. execute: function(callback, callbackName) {
  20410. var
  20411. calculations = module.get.elementCalculations(),
  20412. screen = module.get.screenCalculations()
  20413. ;
  20414. callback = callback || false;
  20415. if(callback) {
  20416. if(settings.continuous) {
  20417. module.debug('Callback being called continuously', callbackName, calculations);
  20418. callback.call(element, calculations, screen);
  20419. }
  20420. else if(!module.get.occurred(callbackName)) {
  20421. module.debug('Conditions met', callbackName, calculations);
  20422. callback.call(element, calculations, screen);
  20423. }
  20424. }
  20425. module.save.occurred(callbackName);
  20426. },
  20427. remove: {
  20428. fixed: function() {
  20429. module.debug('Removing fixed position');
  20430. $module
  20431. .removeClass(className.fixed)
  20432. .css({
  20433. position : '',
  20434. top : '',
  20435. left : '',
  20436. zIndex : ''
  20437. })
  20438. ;
  20439. settings.onUnfixed.call(element);
  20440. },
  20441. placeholder: function() {
  20442. module.debug('Removing placeholder content');
  20443. if($placeholder) {
  20444. $placeholder.remove();
  20445. }
  20446. },
  20447. occurred: function(callback) {
  20448. if(callback) {
  20449. var
  20450. occurred = module.cache.occurred
  20451. ;
  20452. if(occurred[callback] !== undefined && occurred[callback] === true) {
  20453. module.debug('Callback can now be called again', callback);
  20454. module.cache.occurred[callback] = false;
  20455. }
  20456. }
  20457. else {
  20458. module.cache.occurred = {};
  20459. }
  20460. }
  20461. },
  20462. save: {
  20463. calculations: function() {
  20464. module.verbose('Saving all calculations necessary to determine positioning');
  20465. module.save.direction();
  20466. module.save.screenCalculations();
  20467. module.save.elementCalculations();
  20468. },
  20469. occurred: function(callback) {
  20470. if(callback) {
  20471. if(module.cache.occurred[callback] === undefined || (module.cache.occurred[callback] !== true)) {
  20472. module.verbose('Saving callback occurred', callback);
  20473. module.cache.occurred[callback] = true;
  20474. }
  20475. }
  20476. },
  20477. scroll: function(scrollPosition) {
  20478. scrollPosition = scrollPosition + settings.offset || $context.scrollTop() + settings.offset;
  20479. module.cache.scroll = scrollPosition;
  20480. },
  20481. direction: function() {
  20482. var
  20483. scroll = module.get.scroll(),
  20484. lastScroll = module.get.lastScroll(),
  20485. direction
  20486. ;
  20487. if(scroll > lastScroll && lastScroll) {
  20488. direction = 'down';
  20489. }
  20490. else if(scroll < lastScroll && lastScroll) {
  20491. direction = 'up';
  20492. }
  20493. else {
  20494. direction = 'static';
  20495. }
  20496. module.cache.direction = direction;
  20497. return module.cache.direction;
  20498. },
  20499. elementPosition: function() {
  20500. var
  20501. element = module.cache.element,
  20502. screen = module.get.screenSize()
  20503. ;
  20504. module.verbose('Saving element position');
  20505. // (quicker than $.extend)
  20506. element.fits = (element.height < screen.height);
  20507. element.offset = $module.offset();
  20508. element.width = $module.outerWidth();
  20509. element.height = $module.outerHeight();
  20510. // store
  20511. module.cache.element = element;
  20512. return element;
  20513. },
  20514. elementCalculations: function() {
  20515. var
  20516. screen = module.get.screenCalculations(),
  20517. element = module.get.elementPosition()
  20518. ;
  20519. // offset
  20520. if(settings.includeMargin) {
  20521. element.margin = {};
  20522. element.margin.top = parseInt($module.css('margin-top'), 10);
  20523. element.margin.bottom = parseInt($module.css('margin-bottom'), 10);
  20524. element.top = element.offset.top - element.margin.top;
  20525. element.bottom = element.offset.top + element.height + element.margin.bottom;
  20526. }
  20527. else {
  20528. element.top = element.offset.top;
  20529. element.bottom = element.offset.top + element.height;
  20530. }
  20531. // visibility
  20532. element.topVisible = (screen.bottom >= element.top);
  20533. element.topPassed = (screen.top >= element.top);
  20534. element.bottomVisible = (screen.bottom >= element.bottom);
  20535. element.bottomPassed = (screen.top >= element.bottom);
  20536. element.pixelsPassed = 0;
  20537. element.percentagePassed = 0;
  20538. // meta calculations
  20539. element.onScreen = (element.topVisible && !element.bottomPassed);
  20540. element.passing = (element.topPassed && !element.bottomPassed);
  20541. element.offScreen = (!element.onScreen);
  20542. // passing calculations
  20543. if(element.passing) {
  20544. element.pixelsPassed = (screen.top - element.top);
  20545. element.percentagePassed = (screen.top - element.top) / element.height;
  20546. }
  20547. module.cache.element = element;
  20548. module.verbose('Updated element calculations', element);
  20549. return element;
  20550. },
  20551. screenCalculations: function() {
  20552. var
  20553. scroll = module.get.scroll()
  20554. ;
  20555. module.save.direction();
  20556. module.cache.screen.top = scroll;
  20557. module.cache.screen.bottom = scroll + module.cache.screen.height;
  20558. return module.cache.screen;
  20559. },
  20560. screenSize: function() {
  20561. module.verbose('Saving window position');
  20562. module.cache.screen = {
  20563. height: $context.height()
  20564. };
  20565. },
  20566. position: function() {
  20567. module.save.screenSize();
  20568. module.save.elementPosition();
  20569. }
  20570. },
  20571. get: {
  20572. pixelsPassed: function(amount) {
  20573. var
  20574. element = module.get.elementCalculations()
  20575. ;
  20576. if(amount.search('%') > -1) {
  20577. return ( element.height * (parseInt(amount, 10) / 100) );
  20578. }
  20579. return parseInt(amount, 10);
  20580. },
  20581. occurred: function(callback) {
  20582. return (module.cache.occurred !== undefined)
  20583. ? module.cache.occurred[callback] || false
  20584. : false
  20585. ;
  20586. },
  20587. direction: function() {
  20588. if(module.cache.direction === undefined) {
  20589. module.save.direction();
  20590. }
  20591. return module.cache.direction;
  20592. },
  20593. elementPosition: function() {
  20594. if(module.cache.element === undefined) {
  20595. module.save.elementPosition();
  20596. }
  20597. return module.cache.element;
  20598. },
  20599. elementCalculations: function() {
  20600. if(module.cache.element === undefined) {
  20601. module.save.elementCalculations();
  20602. }
  20603. return module.cache.element;
  20604. },
  20605. screenCalculations: function() {
  20606. if(module.cache.screen === undefined) {
  20607. module.save.screenCalculations();
  20608. }
  20609. return module.cache.screen;
  20610. },
  20611. screenSize: function() {
  20612. if(module.cache.screen === undefined) {
  20613. module.save.screenSize();
  20614. }
  20615. return module.cache.screen;
  20616. },
  20617. scroll: function() {
  20618. if(module.cache.scroll === undefined) {
  20619. module.save.scroll();
  20620. }
  20621. return module.cache.scroll;
  20622. },
  20623. lastScroll: function() {
  20624. if(module.cache.screen === undefined) {
  20625. module.debug('First scroll event, no last scroll could be found');
  20626. return false;
  20627. }
  20628. return module.cache.screen.top;
  20629. }
  20630. },
  20631. setting: function(name, value) {
  20632. if( $.isPlainObject(name) ) {
  20633. $.extend(true, settings, name);
  20634. }
  20635. else if(value !== undefined) {
  20636. settings[name] = value;
  20637. }
  20638. else {
  20639. return settings[name];
  20640. }
  20641. },
  20642. internal: function(name, value) {
  20643. if( $.isPlainObject(name) ) {
  20644. $.extend(true, module, name);
  20645. }
  20646. else if(value !== undefined) {
  20647. module[name] = value;
  20648. }
  20649. else {
  20650. return module[name];
  20651. }
  20652. },
  20653. debug: function() {
  20654. if(!settings.silent && settings.debug) {
  20655. if(settings.performance) {
  20656. module.performance.log(arguments);
  20657. }
  20658. else {
  20659. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  20660. module.debug.apply(console, arguments);
  20661. }
  20662. }
  20663. },
  20664. verbose: function() {
  20665. if(!settings.silent && settings.verbose && settings.debug) {
  20666. if(settings.performance) {
  20667. module.performance.log(arguments);
  20668. }
  20669. else {
  20670. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  20671. module.verbose.apply(console, arguments);
  20672. }
  20673. }
  20674. },
  20675. error: function() {
  20676. if(!settings.silent) {
  20677. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  20678. module.error.apply(console, arguments);
  20679. }
  20680. },
  20681. performance: {
  20682. log: function(message) {
  20683. var
  20684. currentTime,
  20685. executionTime,
  20686. previousTime
  20687. ;
  20688. if(settings.performance) {
  20689. currentTime = new Date().getTime();
  20690. previousTime = time || currentTime;
  20691. executionTime = currentTime - previousTime;
  20692. time = currentTime;
  20693. performance.push({
  20694. 'Name' : message[0],
  20695. 'Arguments' : [].slice.call(message, 1) || '',
  20696. 'Element' : element,
  20697. 'Execution Time' : executionTime
  20698. });
  20699. }
  20700. clearTimeout(module.performance.timer);
  20701. module.performance.timer = setTimeout(module.performance.display, 500);
  20702. },
  20703. display: function() {
  20704. var
  20705. title = settings.name + ':',
  20706. totalTime = 0
  20707. ;
  20708. time = false;
  20709. clearTimeout(module.performance.timer);
  20710. $.each(performance, function(index, data) {
  20711. totalTime += data['Execution Time'];
  20712. });
  20713. title += ' ' + totalTime + 'ms';
  20714. if(moduleSelector) {
  20715. title += ' \'' + moduleSelector + '\'';
  20716. }
  20717. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  20718. console.groupCollapsed(title);
  20719. if(console.table) {
  20720. console.table(performance);
  20721. }
  20722. else {
  20723. $.each(performance, function(index, data) {
  20724. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  20725. });
  20726. }
  20727. console.groupEnd();
  20728. }
  20729. performance = [];
  20730. }
  20731. },
  20732. invoke: function(query, passedArguments, context) {
  20733. var
  20734. object = instance,
  20735. maxDepth,
  20736. found,
  20737. response
  20738. ;
  20739. passedArguments = passedArguments || queryArguments;
  20740. context = element || context;
  20741. if(typeof query == 'string' && object !== undefined) {
  20742. query = query.split(/[\. ]/);
  20743. maxDepth = query.length - 1;
  20744. $.each(query, function(depth, value) {
  20745. var camelCaseValue = (depth != maxDepth)
  20746. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  20747. : query
  20748. ;
  20749. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  20750. object = object[camelCaseValue];
  20751. }
  20752. else if( object[camelCaseValue] !== undefined ) {
  20753. found = object[camelCaseValue];
  20754. return false;
  20755. }
  20756. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  20757. object = object[value];
  20758. }
  20759. else if( object[value] !== undefined ) {
  20760. found = object[value];
  20761. return false;
  20762. }
  20763. else {
  20764. module.error(error.method, query);
  20765. return false;
  20766. }
  20767. });
  20768. }
  20769. if ( $.isFunction( found ) ) {
  20770. response = found.apply(context, passedArguments);
  20771. }
  20772. else if(found !== undefined) {
  20773. response = found;
  20774. }
  20775. if($.isArray(returnedValue)) {
  20776. returnedValue.push(response);
  20777. }
  20778. else if(returnedValue !== undefined) {
  20779. returnedValue = [returnedValue, response];
  20780. }
  20781. else if(response !== undefined) {
  20782. returnedValue = response;
  20783. }
  20784. return found;
  20785. }
  20786. };
  20787. if(methodInvoked) {
  20788. if(instance === undefined) {
  20789. module.initialize();
  20790. }
  20791. instance.save.scroll();
  20792. instance.save.calculations();
  20793. module.invoke(query);
  20794. }
  20795. else {
  20796. if(instance !== undefined) {
  20797. instance.invoke('destroy');
  20798. }
  20799. module.initialize();
  20800. }
  20801. })
  20802. ;
  20803. return (returnedValue !== undefined)
  20804. ? returnedValue
  20805. : this
  20806. ;
  20807. };
  20808. $.fn.visibility.settings = {
  20809. name : 'Visibility',
  20810. namespace : 'visibility',
  20811. debug : false,
  20812. verbose : false,
  20813. performance : true,
  20814. // whether to use mutation observers to follow changes
  20815. observeChanges : true,
  20816. // check position immediately on init
  20817. initialCheck : true,
  20818. // whether to refresh calculations after all page images load
  20819. refreshOnLoad : true,
  20820. // whether to refresh calculations after page resize event
  20821. refreshOnResize : true,
  20822. // should call callbacks on refresh event (resize, etc)
  20823. checkOnRefresh : true,
  20824. // callback should only occur one time
  20825. once : true,
  20826. // callback should fire continuously whe evaluates to true
  20827. continuous : false,
  20828. // offset to use with scroll top
  20829. offset : 0,
  20830. // whether to include margin in elements position
  20831. includeMargin : false,
  20832. // scroll context for visibility checks
  20833. context : window,
  20834. // visibility check delay in ms (defaults to animationFrame)
  20835. throttle : false,
  20836. // special visibility type (image, fixed)
  20837. type : false,
  20838. // z-index to use with visibility 'fixed'
  20839. zIndex : '10',
  20840. // image only animation settings
  20841. transition : 'fade in',
  20842. duration : 1000,
  20843. // array of callbacks for percentage
  20844. onPassed : {},
  20845. // standard callbacks
  20846. onOnScreen : false,
  20847. onOffScreen : false,
  20848. onPassing : false,
  20849. onTopVisible : false,
  20850. onBottomVisible : false,
  20851. onTopPassed : false,
  20852. onBottomPassed : false,
  20853. // reverse callbacks
  20854. onPassingReverse : false,
  20855. onTopVisibleReverse : false,
  20856. onBottomVisibleReverse : false,
  20857. onTopPassedReverse : false,
  20858. onBottomPassedReverse : false,
  20859. // special callbacks for image
  20860. onLoad : function() {},
  20861. onAllLoaded : function() {},
  20862. // special callbacks for fixed position
  20863. onFixed : function() {},
  20864. onUnfixed : function() {},
  20865. // utility callbacks
  20866. onUpdate : false, // disabled by default for performance
  20867. onRefresh : function(){},
  20868. metadata : {
  20869. src: 'src'
  20870. },
  20871. className: {
  20872. fixed : 'fixed',
  20873. placeholder : 'placeholder'
  20874. },
  20875. error : {
  20876. method : 'The method you called is not defined.',
  20877. visible : 'Element is hidden, you must call refresh after element becomes visible'
  20878. }
  20879. };
  20880. })( jQuery, window, document );