kityminder.m-share.js 1.0 MB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197
  1. /*!
  2. * ====================================================
  3. * kityminder - v1.3.5 - 2015-05-15
  4. * https://github.com/fex-team/kityminder
  5. * GitHub: https://github.com/fex-team/kityminder.git
  6. * Copyright (c) 2015 f-cube @ FEX; Licensed MIT
  7. * ====================================================
  8. */
  9. (function(window) {
  10. /*!
  11. * jQuery JavaScript Library v2.1.1
  12. * http://jquery.com/
  13. *
  14. * Includes Sizzle.js
  15. * http://sizzlejs.com/
  16. *
  17. * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
  18. * Released under the MIT license
  19. * http://jquery.org/license
  20. *
  21. * Date: 2014-05-01T17:11Z
  22. */
  23. (function( global, factory ) {
  24. if ( typeof module === "object" && typeof module.exports === "object" ) {
  25. // For CommonJS and CommonJS-like environments where a proper window is present,
  26. // execute the factory and get jQuery
  27. // For environments that do not inherently posses a window with a document
  28. // (such as Node.js), expose a jQuery-making factory as module.exports
  29. // This accentuates the need for the creation of a real window
  30. // e.g. var jQuery = require("jquery")(window);
  31. // See ticket #14549 for more info
  32. module.exports = global.document ?
  33. factory( global, true ) :
  34. function( w ) {
  35. if ( !w.document ) {
  36. throw new Error( "jQuery requires a window with a document" );
  37. }
  38. return factory( w );
  39. };
  40. } else {
  41. factory( global );
  42. }
  43. // Pass this if window is not defined yet
  44. }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
  45. // Can't do this because several apps including ASP.NET trace
  46. // the stack via arguments.caller.callee and Firefox dies if
  47. // you try to trace through "use strict" call chains. (#13335)
  48. // Support: Firefox 18+
  49. //
  50. var arr = [];
  51. var slice = arr.slice;
  52. var concat = arr.concat;
  53. var push = arr.push;
  54. var indexOf = arr.indexOf;
  55. var class2type = {};
  56. var toString = class2type.toString;
  57. var hasOwn = class2type.hasOwnProperty;
  58. var support = {};
  59. var
  60. // Use the correct document accordingly with window argument (sandbox)
  61. document = window.document,
  62. version = "2.1.1",
  63. // Define a local copy of jQuery
  64. jQuery = function( selector, context ) {
  65. // The jQuery object is actually just the init constructor 'enhanced'
  66. // Need init if jQuery is called (just allow error to be thrown if not included)
  67. return new jQuery.fn.init( selector, context );
  68. },
  69. // Support: Android<4.1
  70. // Make sure we trim BOM and NBSP
  71. rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
  72. // Matches dashed string for camelizing
  73. rmsPrefix = /^-ms-/,
  74. rdashAlpha = /-([\da-z])/gi,
  75. // Used by jQuery.camelCase as callback to replace()
  76. fcamelCase = function( all, letter ) {
  77. return letter.toUpperCase();
  78. };
  79. jQuery.fn = jQuery.prototype = {
  80. // The current version of jQuery being used
  81. jquery: version,
  82. constructor: jQuery,
  83. // Start with an empty selector
  84. selector: "",
  85. // The default length of a jQuery object is 0
  86. length: 0,
  87. toArray: function() {
  88. return slice.call( this );
  89. },
  90. // Get the Nth element in the matched element set OR
  91. // Get the whole matched element set as a clean array
  92. get: function( num ) {
  93. return num != null ?
  94. // Return just the one element from the set
  95. ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
  96. // Return all the elements in a clean array
  97. slice.call( this );
  98. },
  99. // Take an array of elements and push it onto the stack
  100. // (returning the new matched element set)
  101. pushStack: function( elems ) {
  102. // Build a new jQuery matched element set
  103. var ret = jQuery.merge( this.constructor(), elems );
  104. // Add the old object onto the stack (as a reference)
  105. ret.prevObject = this;
  106. ret.context = this.context;
  107. // Return the newly-formed element set
  108. return ret;
  109. },
  110. // Execute a callback for every element in the matched set.
  111. // (You can seed the arguments with an array of args, but this is
  112. // only used internally.)
  113. each: function( callback, args ) {
  114. return jQuery.each( this, callback, args );
  115. },
  116. map: function( callback ) {
  117. return this.pushStack( jQuery.map(this, function( elem, i ) {
  118. return callback.call( elem, i, elem );
  119. }));
  120. },
  121. slice: function() {
  122. return this.pushStack( slice.apply( this, arguments ) );
  123. },
  124. first: function() {
  125. return this.eq( 0 );
  126. },
  127. last: function() {
  128. return this.eq( -1 );
  129. },
  130. eq: function( i ) {
  131. var len = this.length,
  132. j = +i + ( i < 0 ? len : 0 );
  133. return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
  134. },
  135. end: function() {
  136. return this.prevObject || this.constructor(null);
  137. },
  138. // For internal use only.
  139. // Behaves like an Array's method, not like a jQuery method.
  140. push: push,
  141. sort: arr.sort,
  142. splice: arr.splice
  143. };
  144. jQuery.extend = jQuery.fn.extend = function() {
  145. var options, name, src, copy, copyIsArray, clone,
  146. target = arguments[0] || {},
  147. i = 1,
  148. length = arguments.length,
  149. deep = false;
  150. // Handle a deep copy situation
  151. if ( typeof target === "boolean" ) {
  152. deep = target;
  153. // skip the boolean and the target
  154. target = arguments[ i ] || {};
  155. i++;
  156. }
  157. // Handle case when target is a string or something (possible in deep copy)
  158. if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
  159. target = {};
  160. }
  161. // extend jQuery itself if only one argument is passed
  162. if ( i === length ) {
  163. target = this;
  164. i--;
  165. }
  166. for ( ; i < length; i++ ) {
  167. // Only deal with non-null/undefined values
  168. if ( (options = arguments[ i ]) != null ) {
  169. // Extend the base object
  170. for ( name in options ) {
  171. src = target[ name ];
  172. copy = options[ name ];
  173. // Prevent never-ending loop
  174. if ( target === copy ) {
  175. continue;
  176. }
  177. // Recurse if we're merging plain objects or arrays
  178. if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
  179. if ( copyIsArray ) {
  180. copyIsArray = false;
  181. clone = src && jQuery.isArray(src) ? src : [];
  182. } else {
  183. clone = src && jQuery.isPlainObject(src) ? src : {};
  184. }
  185. // Never move original objects, clone them
  186. target[ name ] = jQuery.extend( deep, clone, copy );
  187. // Don't bring in undefined values
  188. } else if ( copy !== undefined ) {
  189. target[ name ] = copy;
  190. }
  191. }
  192. }
  193. }
  194. // Return the modified object
  195. return target;
  196. };
  197. jQuery.extend({
  198. // Unique for each copy of jQuery on the page
  199. expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
  200. // Assume jQuery is ready without the ready module
  201. isReady: true,
  202. error: function( msg ) {
  203. throw new Error( msg );
  204. },
  205. noop: function() {},
  206. // See test/unit/core.js for details concerning isFunction.
  207. // Since version 1.3, DOM methods and functions like alert
  208. // aren't supported. They return false on IE (#2968).
  209. isFunction: function( obj ) {
  210. return jQuery.type(obj) === "function";
  211. },
  212. isArray: Array.isArray,
  213. isWindow: function( obj ) {
  214. return obj != null && obj === obj.window;
  215. },
  216. isNumeric: function( obj ) {
  217. // parseFloat NaNs numeric-cast false positives (null|true|false|"")
  218. // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
  219. // subtraction forces infinities to NaN
  220. return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0;
  221. },
  222. isPlainObject: function( obj ) {
  223. // Not plain objects:
  224. // - Any object or value whose internal [[Class]] property is not "[object Object]"
  225. // - DOM nodes
  226. // - window
  227. if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
  228. return false;
  229. }
  230. if ( obj.constructor &&
  231. !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
  232. return false;
  233. }
  234. // If the function hasn't returned already, we're confident that
  235. // |obj| is a plain object, created by {} or constructed with new Object
  236. return true;
  237. },
  238. isEmptyObject: function( obj ) {
  239. var name;
  240. for ( name in obj ) {
  241. return false;
  242. }
  243. return true;
  244. },
  245. type: function( obj ) {
  246. if ( obj == null ) {
  247. return obj + "";
  248. }
  249. // Support: Android < 4.0, iOS < 6 (functionish RegExp)
  250. return typeof obj === "object" || typeof obj === "function" ?
  251. class2type[ toString.call(obj) ] || "object" :
  252. typeof obj;
  253. },
  254. // Evaluates a script in a global context
  255. globalEval: function( code ) {
  256. var script,
  257. indirect = eval;
  258. code = jQuery.trim( code );
  259. if ( code ) {
  260. // If the code includes a valid, prologue position
  261. // strict mode pragma, execute code by injecting a
  262. // script tag into the document.
  263. if ( code.indexOf("use strict") === 1 ) {
  264. script = document.createElement("script");
  265. script.text = code;
  266. document.head.appendChild( script ).parentNode.removeChild( script );
  267. } else {
  268. // Otherwise, avoid the DOM node creation, insertion
  269. // and removal by using an indirect global eval
  270. indirect( code );
  271. }
  272. }
  273. },
  274. // Convert dashed to camelCase; used by the css and data modules
  275. // Microsoft forgot to hump their vendor prefix (#9572)
  276. camelCase: function( string ) {
  277. return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
  278. },
  279. nodeName: function( elem, name ) {
  280. return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
  281. },
  282. // args is for internal usage only
  283. each: function( obj, callback, args ) {
  284. var value,
  285. i = 0,
  286. length = obj.length,
  287. isArray = isArraylike( obj );
  288. if ( args ) {
  289. if ( isArray ) {
  290. for ( ; i < length; i++ ) {
  291. value = callback.apply( obj[ i ], args );
  292. if ( value === false ) {
  293. break;
  294. }
  295. }
  296. } else {
  297. for ( i in obj ) {
  298. value = callback.apply( obj[ i ], args );
  299. if ( value === false ) {
  300. break;
  301. }
  302. }
  303. }
  304. // A special, fast, case for the most common use of each
  305. } else {
  306. if ( isArray ) {
  307. for ( ; i < length; i++ ) {
  308. value = callback.call( obj[ i ], i, obj[ i ] );
  309. if ( value === false ) {
  310. break;
  311. }
  312. }
  313. } else {
  314. for ( i in obj ) {
  315. value = callback.call( obj[ i ], i, obj[ i ] );
  316. if ( value === false ) {
  317. break;
  318. }
  319. }
  320. }
  321. }
  322. return obj;
  323. },
  324. // Support: Android<4.1
  325. trim: function( text ) {
  326. return text == null ?
  327. "" :
  328. ( text + "" ).replace( rtrim, "" );
  329. },
  330. // results is for internal usage only
  331. makeArray: function( arr, results ) {
  332. var ret = results || [];
  333. if ( arr != null ) {
  334. if ( isArraylike( Object(arr) ) ) {
  335. jQuery.merge( ret,
  336. typeof arr === "string" ?
  337. [ arr ] : arr
  338. );
  339. } else {
  340. push.call( ret, arr );
  341. }
  342. }
  343. return ret;
  344. },
  345. inArray: function( elem, arr, i ) {
  346. return arr == null ? -1 : indexOf.call( arr, elem, i );
  347. },
  348. merge: function( first, second ) {
  349. var len = +second.length,
  350. j = 0,
  351. i = first.length;
  352. for ( ; j < len; j++ ) {
  353. first[ i++ ] = second[ j ];
  354. }
  355. first.length = i;
  356. return first;
  357. },
  358. grep: function( elems, callback, invert ) {
  359. var callbackInverse,
  360. matches = [],
  361. i = 0,
  362. length = elems.length,
  363. callbackExpect = !invert;
  364. // Go through the array, only saving the items
  365. // that pass the validator function
  366. for ( ; i < length; i++ ) {
  367. callbackInverse = !callback( elems[ i ], i );
  368. if ( callbackInverse !== callbackExpect ) {
  369. matches.push( elems[ i ] );
  370. }
  371. }
  372. return matches;
  373. },
  374. // arg is for internal usage only
  375. map: function( elems, callback, arg ) {
  376. var value,
  377. i = 0,
  378. length = elems.length,
  379. isArray = isArraylike( elems ),
  380. ret = [];
  381. // Go through the array, translating each of the items to their new values
  382. if ( isArray ) {
  383. for ( ; i < length; i++ ) {
  384. value = callback( elems[ i ], i, arg );
  385. if ( value != null ) {
  386. ret.push( value );
  387. }
  388. }
  389. // Go through every key on the object,
  390. } else {
  391. for ( i in elems ) {
  392. value = callback( elems[ i ], i, arg );
  393. if ( value != null ) {
  394. ret.push( value );
  395. }
  396. }
  397. }
  398. // Flatten any nested arrays
  399. return concat.apply( [], ret );
  400. },
  401. // A global GUID counter for objects
  402. guid: 1,
  403. // Bind a function to a context, optionally partially applying any
  404. // arguments.
  405. proxy: function( fn, context ) {
  406. var tmp, args, proxy;
  407. if ( typeof context === "string" ) {
  408. tmp = fn[ context ];
  409. context = fn;
  410. fn = tmp;
  411. }
  412. // Quick check to determine if target is callable, in the spec
  413. // this throws a TypeError, but we will just return undefined.
  414. if ( !jQuery.isFunction( fn ) ) {
  415. return undefined;
  416. }
  417. // Simulated bind
  418. args = slice.call( arguments, 2 );
  419. proxy = function() {
  420. return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
  421. };
  422. // Set the guid of unique handler to the same of original handler, so it can be removed
  423. proxy.guid = fn.guid = fn.guid || jQuery.guid++;
  424. return proxy;
  425. },
  426. now: Date.now,
  427. // jQuery.support is not used in Core but other projects attach their
  428. // properties to it so it needs to exist.
  429. support: support
  430. });
  431. // Populate the class2type map
  432. jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
  433. class2type[ "[object " + name + "]" ] = name.toLowerCase();
  434. });
  435. function isArraylike( obj ) {
  436. var length = obj.length,
  437. type = jQuery.type( obj );
  438. if ( type === "function" || jQuery.isWindow( obj ) ) {
  439. return false;
  440. }
  441. if ( obj.nodeType === 1 && length ) {
  442. return true;
  443. }
  444. return type === "array" || length === 0 ||
  445. typeof length === "number" && length > 0 && ( length - 1 ) in obj;
  446. }
  447. var Sizzle =
  448. /*!
  449. * Sizzle CSS Selector Engine v1.10.19
  450. * http://sizzlejs.com/
  451. *
  452. * Copyright 2013 jQuery Foundation, Inc. and other contributors
  453. * Released under the MIT license
  454. * http://jquery.org/license
  455. *
  456. * Date: 2014-04-18
  457. */
  458. (function( window ) {
  459. var i,
  460. support,
  461. Expr,
  462. getText,
  463. isXML,
  464. tokenize,
  465. compile,
  466. select,
  467. outermostContext,
  468. sortInput,
  469. hasDuplicate,
  470. // Local document vars
  471. setDocument,
  472. document,
  473. docElem,
  474. documentIsHTML,
  475. rbuggyQSA,
  476. rbuggyMatches,
  477. matches,
  478. contains,
  479. // Instance-specific data
  480. expando = "sizzle" + -(new Date()),
  481. preferredDoc = window.document,
  482. dirruns = 0,
  483. done = 0,
  484. classCache = createCache(),
  485. tokenCache = createCache(),
  486. compilerCache = createCache(),
  487. sortOrder = function( a, b ) {
  488. if ( a === b ) {
  489. hasDuplicate = true;
  490. }
  491. return 0;
  492. },
  493. // General-purpose constants
  494. strundefined = typeof undefined,
  495. MAX_NEGATIVE = 1 << 31,
  496. // Instance methods
  497. hasOwn = ({}).hasOwnProperty,
  498. arr = [],
  499. pop = arr.pop,
  500. push_native = arr.push,
  501. push = arr.push,
  502. slice = arr.slice,
  503. // Use a stripped-down indexOf if we can't use a native one
  504. indexOf = arr.indexOf || function( elem ) {
  505. var i = 0,
  506. len = this.length;
  507. for ( ; i < len; i++ ) {
  508. if ( this[i] === elem ) {
  509. return i;
  510. }
  511. }
  512. return -1;
  513. },
  514. booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
  515. // Regular expressions
  516. // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
  517. whitespace = "[\\x20\\t\\r\\n\\f]",
  518. // http://www.w3.org/TR/css3-syntax/#characters
  519. characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
  520. // Loosely modeled on CSS identifier characters
  521. // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
  522. // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
  523. identifier = characterEncoding.replace( "w", "w#" ),
  524. // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
  525. attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
  526. // Operator (capture 2)
  527. "*([*^$|!~]?=)" + whitespace +
  528. // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
  529. "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
  530. "*\\]",
  531. pseudos = ":(" + characterEncoding + ")(?:\\((" +
  532. // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
  533. // 1. quoted (capture 3; capture 4 or capture 5)
  534. "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
  535. // 2. simple (capture 6)
  536. "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
  537. // 3. anything else (capture 2)
  538. ".*" +
  539. ")\\)|)",
  540. // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
  541. rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
  542. rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
  543. rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
  544. rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
  545. rpseudo = new RegExp( pseudos ),
  546. ridentifier = new RegExp( "^" + identifier + "$" ),
  547. matchExpr = {
  548. "ID": new RegExp( "^#(" + characterEncoding + ")" ),
  549. "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
  550. "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
  551. "ATTR": new RegExp( "^" + attributes ),
  552. "PSEUDO": new RegExp( "^" + pseudos ),
  553. "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
  554. "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
  555. "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
  556. "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
  557. // For use in libraries implementing .is()
  558. // We use this for POS matching in `select`
  559. "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
  560. whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
  561. },
  562. rinputs = /^(?:input|select|textarea|button)$/i,
  563. rheader = /^h\d$/i,
  564. rnative = /^[^{]+\{\s*\[native \w/,
  565. // Easily-parseable/retrievable ID or TAG or CLASS selectors
  566. rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
  567. rsibling = /[+~]/,
  568. rescape = /'|\\/g,
  569. // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
  570. runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
  571. funescape = function( _, escaped, escapedWhitespace ) {
  572. var high = "0x" + escaped - 0x10000;
  573. // NaN means non-codepoint
  574. // Support: Firefox<24
  575. // Workaround erroneous numeric interpretation of +"0x"
  576. return high !== high || escapedWhitespace ?
  577. escaped :
  578. high < 0 ?
  579. // BMP codepoint
  580. String.fromCharCode( high + 0x10000 ) :
  581. // Supplemental Plane codepoint (surrogate pair)
  582. String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
  583. };
  584. // Optimize for push.apply( _, NodeList )
  585. try {
  586. push.apply(
  587. (arr = slice.call( preferredDoc.childNodes )),
  588. preferredDoc.childNodes
  589. );
  590. // Support: Android<4.0
  591. // Detect silently failing push.apply
  592. arr[ preferredDoc.childNodes.length ].nodeType;
  593. } catch ( e ) {
  594. push = { apply: arr.length ?
  595. // Leverage slice if possible
  596. function( target, els ) {
  597. push_native.apply( target, slice.call(els) );
  598. } :
  599. // Support: IE<9
  600. // Otherwise append directly
  601. function( target, els ) {
  602. var j = target.length,
  603. i = 0;
  604. // Can't trust NodeList.length
  605. while ( (target[j++] = els[i++]) ) {}
  606. target.length = j - 1;
  607. }
  608. };
  609. }
  610. function Sizzle( selector, context, results, seed ) {
  611. var match, elem, m, nodeType,
  612. // QSA vars
  613. i, groups, old, nid, newContext, newSelector;
  614. if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
  615. setDocument( context );
  616. }
  617. context = context || document;
  618. results = results || [];
  619. if ( !selector || typeof selector !== "string" ) {
  620. return results;
  621. }
  622. if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
  623. return [];
  624. }
  625. if ( documentIsHTML && !seed ) {
  626. // Shortcuts
  627. if ( (match = rquickExpr.exec( selector )) ) {
  628. // Speed-up: Sizzle("#ID")
  629. if ( (m = match[1]) ) {
  630. if ( nodeType === 9 ) {
  631. elem = context.getElementById( m );
  632. // Check parentNode to catch when Blackberry 4.6 returns
  633. // nodes that are no longer in the document (jQuery #6963)
  634. if ( elem && elem.parentNode ) {
  635. // Handle the case where IE, Opera, and Webkit return items
  636. // by name instead of ID
  637. if ( elem.id === m ) {
  638. results.push( elem );
  639. return results;
  640. }
  641. } else {
  642. return results;
  643. }
  644. } else {
  645. // Context is not a document
  646. if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
  647. contains( context, elem ) && elem.id === m ) {
  648. results.push( elem );
  649. return results;
  650. }
  651. }
  652. // Speed-up: Sizzle("TAG")
  653. } else if ( match[2] ) {
  654. push.apply( results, context.getElementsByTagName( selector ) );
  655. return results;
  656. // Speed-up: Sizzle(".CLASS")
  657. } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
  658. push.apply( results, context.getElementsByClassName( m ) );
  659. return results;
  660. }
  661. }
  662. // QSA path
  663. if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
  664. nid = old = expando;
  665. newContext = context;
  666. newSelector = nodeType === 9 && selector;
  667. // qSA works strangely on Element-rooted queries
  668. // We can work around this by specifying an extra ID on the root
  669. // and working up from there (Thanks to Andrew Dupont for the technique)
  670. // IE 8 doesn't work on object elements
  671. if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
  672. groups = tokenize( selector );
  673. if ( (old = context.getAttribute("id")) ) {
  674. nid = old.replace( rescape, "\\$&" );
  675. } else {
  676. context.setAttribute( "id", nid );
  677. }
  678. nid = "[id='" + nid + "'] ";
  679. i = groups.length;
  680. while ( i-- ) {
  681. groups[i] = nid + toSelector( groups[i] );
  682. }
  683. newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
  684. newSelector = groups.join(",");
  685. }
  686. if ( newSelector ) {
  687. try {
  688. push.apply( results,
  689. newContext.querySelectorAll( newSelector )
  690. );
  691. return results;
  692. } catch(qsaError) {
  693. } finally {
  694. if ( !old ) {
  695. context.removeAttribute("id");
  696. }
  697. }
  698. }
  699. }
  700. }
  701. // All others
  702. return select( selector.replace( rtrim, "$1" ), context, results, seed );
  703. }
  704. /**
  705. * Create key-value caches of limited size
  706. * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
  707. * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
  708. * deleting the oldest entry
  709. */
  710. function createCache() {
  711. var keys = [];
  712. function cache( key, value ) {
  713. // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
  714. if ( keys.push( key + " " ) > Expr.cacheLength ) {
  715. // Only keep the most recent entries
  716. delete cache[ keys.shift() ];
  717. }
  718. return (cache[ key + " " ] = value);
  719. }
  720. return cache;
  721. }
  722. /**
  723. * Mark a function for special use by Sizzle
  724. * @param {Function} fn The function to mark
  725. */
  726. function markFunction( fn ) {
  727. fn[ expando ] = true;
  728. return fn;
  729. }
  730. /**
  731. * Support testing using an element
  732. * @param {Function} fn Passed the created div and expects a boolean result
  733. */
  734. function assert( fn ) {
  735. var div = document.createElement("div");
  736. try {
  737. return !!fn( div );
  738. } catch (e) {
  739. return false;
  740. } finally {
  741. // Remove from its parent by default
  742. if ( div.parentNode ) {
  743. div.parentNode.removeChild( div );
  744. }
  745. // release memory in IE
  746. div = null;
  747. }
  748. }
  749. /**
  750. * Adds the same handler for all of the specified attrs
  751. * @param {String} attrs Pipe-separated list of attributes
  752. * @param {Function} handler The method that will be applied
  753. */
  754. function addHandle( attrs, handler ) {
  755. var arr = attrs.split("|"),
  756. i = attrs.length;
  757. while ( i-- ) {
  758. Expr.attrHandle[ arr[i] ] = handler;
  759. }
  760. }
  761. /**
  762. * Checks document order of two siblings
  763. * @param {Element} a
  764. * @param {Element} b
  765. * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
  766. */
  767. function siblingCheck( a, b ) {
  768. var cur = b && a,
  769. diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
  770. ( ~b.sourceIndex || MAX_NEGATIVE ) -
  771. ( ~a.sourceIndex || MAX_NEGATIVE );
  772. // Use IE sourceIndex if available on both nodes
  773. if ( diff ) {
  774. return diff;
  775. }
  776. // Check if b follows a
  777. if ( cur ) {
  778. while ( (cur = cur.nextSibling) ) {
  779. if ( cur === b ) {
  780. return -1;
  781. }
  782. }
  783. }
  784. return a ? 1 : -1;
  785. }
  786. /**
  787. * Returns a function to use in pseudos for input types
  788. * @param {String} type
  789. */
  790. function createInputPseudo( type ) {
  791. return function( elem ) {
  792. var name = elem.nodeName.toLowerCase();
  793. return name === "input" && elem.type === type;
  794. };
  795. }
  796. /**
  797. * Returns a function to use in pseudos for buttons
  798. * @param {String} type
  799. */
  800. function createButtonPseudo( type ) {
  801. return function( elem ) {
  802. var name = elem.nodeName.toLowerCase();
  803. return (name === "input" || name === "button") && elem.type === type;
  804. };
  805. }
  806. /**
  807. * Returns a function to use in pseudos for positionals
  808. * @param {Function} fn
  809. */
  810. function createPositionalPseudo( fn ) {
  811. return markFunction(function( argument ) {
  812. argument = +argument;
  813. return markFunction(function( seed, matches ) {
  814. var j,
  815. matchIndexes = fn( [], seed.length, argument ),
  816. i = matchIndexes.length;
  817. // Match elements found at the specified indexes
  818. while ( i-- ) {
  819. if ( seed[ (j = matchIndexes[i]) ] ) {
  820. seed[j] = !(matches[j] = seed[j]);
  821. }
  822. }
  823. });
  824. });
  825. }
  826. /**
  827. * Checks a node for validity as a Sizzle context
  828. * @param {Element|Object=} context
  829. * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
  830. */
  831. function testContext( context ) {
  832. return context && typeof context.getElementsByTagName !== strundefined && context;
  833. }
  834. // Expose support vars for convenience
  835. support = Sizzle.support = {};
  836. /**
  837. * Detects XML nodes
  838. * @param {Element|Object} elem An element or a document
  839. * @returns {Boolean} True iff elem is a non-HTML XML node
  840. */
  841. isXML = Sizzle.isXML = function( elem ) {
  842. // documentElement is verified for cases where it doesn't yet exist
  843. // (such as loading iframes in IE - #4833)
  844. var documentElement = elem && (elem.ownerDocument || elem).documentElement;
  845. return documentElement ? documentElement.nodeName !== "HTML" : false;
  846. };
  847. /**
  848. * Sets document-related variables once based on the current document
  849. * @param {Element|Object} [doc] An element or document object to use to set the document
  850. * @returns {Object} Returns the current document
  851. */
  852. setDocument = Sizzle.setDocument = function( node ) {
  853. var hasCompare,
  854. doc = node ? node.ownerDocument || node : preferredDoc,
  855. parent = doc.defaultView;
  856. // If no document and documentElement is available, return
  857. if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
  858. return document;
  859. }
  860. // Set our document
  861. document = doc;
  862. docElem = doc.documentElement;
  863. // Support tests
  864. documentIsHTML = !isXML( doc );
  865. // Support: IE>8
  866. // If iframe document is assigned to "document" variable and if iframe has been reloaded,
  867. // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
  868. // IE6-8 do not support the defaultView property so parent will be undefined
  869. if ( parent && parent !== parent.top ) {
  870. // IE11 does not have attachEvent, so all must suffer
  871. if ( parent.addEventListener ) {
  872. parent.addEventListener( "unload", function() {
  873. setDocument();
  874. }, false );
  875. } else if ( parent.attachEvent ) {
  876. parent.attachEvent( "onunload", function() {
  877. setDocument();
  878. });
  879. }
  880. }
  881. /* Attributes
  882. ---------------------------------------------------------------------- */
  883. // Support: IE<8
  884. // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
  885. support.attributes = assert(function( div ) {
  886. div.className = "i";
  887. return !div.getAttribute("className");
  888. });
  889. /* getElement(s)By*
  890. ---------------------------------------------------------------------- */
  891. // Check if getElementsByTagName("*") returns only elements
  892. support.getElementsByTagName = assert(function( div ) {
  893. div.appendChild( doc.createComment("") );
  894. return !div.getElementsByTagName("*").length;
  895. });
  896. // Check if getElementsByClassName can be trusted
  897. support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
  898. div.innerHTML = "<div class='a'></div><div class='a i'></div>";
  899. // Support: Safari<4
  900. // Catch class over-caching
  901. div.firstChild.className = "i";
  902. // Support: Opera<10
  903. // Catch gEBCN failure to find non-leading classes
  904. return div.getElementsByClassName("i").length === 2;
  905. });
  906. // Support: IE<10
  907. // Check if getElementById returns elements by name
  908. // The broken getElementById methods don't pick up programatically-set names,
  909. // so use a roundabout getElementsByName test
  910. support.getById = assert(function( div ) {
  911. docElem.appendChild( div ).id = expando;
  912. return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
  913. });
  914. // ID find and filter
  915. if ( support.getById ) {
  916. Expr.find["ID"] = function( id, context ) {
  917. if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
  918. var m = context.getElementById( id );
  919. // Check parentNode to catch when Blackberry 4.6 returns
  920. // nodes that are no longer in the document #6963
  921. return m && m.parentNode ? [ m ] : [];
  922. }
  923. };
  924. Expr.filter["ID"] = function( id ) {
  925. var attrId = id.replace( runescape, funescape );
  926. return function( elem ) {
  927. return elem.getAttribute("id") === attrId;
  928. };
  929. };
  930. } else {
  931. // Support: IE6/7
  932. // getElementById is not reliable as a find shortcut
  933. delete Expr.find["ID"];
  934. Expr.filter["ID"] = function( id ) {
  935. var attrId = id.replace( runescape, funescape );
  936. return function( elem ) {
  937. var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
  938. return node && node.value === attrId;
  939. };
  940. };
  941. }
  942. // Tag
  943. Expr.find["TAG"] = support.getElementsByTagName ?
  944. function( tag, context ) {
  945. if ( typeof context.getElementsByTagName !== strundefined ) {
  946. return context.getElementsByTagName( tag );
  947. }
  948. } :
  949. function( tag, context ) {
  950. var elem,
  951. tmp = [],
  952. i = 0,
  953. results = context.getElementsByTagName( tag );
  954. // Filter out possible comments
  955. if ( tag === "*" ) {
  956. while ( (elem = results[i++]) ) {
  957. if ( elem.nodeType === 1 ) {
  958. tmp.push( elem );
  959. }
  960. }
  961. return tmp;
  962. }
  963. return results;
  964. };
  965. // Class
  966. Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
  967. if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
  968. return context.getElementsByClassName( className );
  969. }
  970. };
  971. /* QSA/matchesSelector
  972. ---------------------------------------------------------------------- */
  973. // QSA and matchesSelector support
  974. // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
  975. rbuggyMatches = [];
  976. // qSa(:focus) reports false when true (Chrome 21)
  977. // We allow this because of a bug in IE8/9 that throws an error
  978. // whenever `document.activeElement` is accessed on an iframe
  979. // So, we allow :focus to pass through QSA all the time to avoid the IE error
  980. // See http://bugs.jquery.com/ticket/13378
  981. rbuggyQSA = [];
  982. if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
  983. // Build QSA regex
  984. // Regex strategy adopted from Diego Perini
  985. assert(function( div ) {
  986. // Select is set to empty string on purpose
  987. // This is to test IE's treatment of not explicitly
  988. // setting a boolean content attribute,
  989. // since its presence should be enough
  990. // http://bugs.jquery.com/ticket/12359
  991. div.innerHTML = "<select msallowclip=''><option selected=''></option></select>";
  992. // Support: IE8, Opera 11-12.16
  993. // Nothing should be selected when empty strings follow ^= or $= or *=
  994. // The test attribute must be unknown in Opera but "safe" for WinRT
  995. // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
  996. if ( div.querySelectorAll("[msallowclip^='']").length ) {
  997. rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
  998. }
  999. // Support: IE8
  1000. // Boolean attributes and "value" are not treated correctly
  1001. if ( !div.querySelectorAll("[selected]").length ) {
  1002. rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
  1003. }
  1004. // Webkit/Opera - :checked should return selected option elements
  1005. // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
  1006. // IE8 throws error here and will not see later tests
  1007. if ( !div.querySelectorAll(":checked").length ) {
  1008. rbuggyQSA.push(":checked");
  1009. }
  1010. });
  1011. assert(function( div ) {
  1012. // Support: Windows 8 Native Apps
  1013. // The type and name attributes are restricted during .innerHTML assignment
  1014. var input = doc.createElement("input");
  1015. input.setAttribute( "type", "hidden" );
  1016. div.appendChild( input ).setAttribute( "name", "D" );
  1017. // Support: IE8
  1018. // Enforce case-sensitivity of name attribute
  1019. if ( div.querySelectorAll("[name=d]").length ) {
  1020. rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
  1021. }
  1022. // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
  1023. // IE8 throws error here and will not see later tests
  1024. if ( !div.querySelectorAll(":enabled").length ) {
  1025. rbuggyQSA.push( ":enabled", ":disabled" );
  1026. }
  1027. // Opera 10-11 does not throw on post-comma invalid pseudos
  1028. div.querySelectorAll("*,:x");
  1029. rbuggyQSA.push(",.*:");
  1030. });
  1031. }
  1032. if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
  1033. docElem.webkitMatchesSelector ||
  1034. docElem.mozMatchesSelector ||
  1035. docElem.oMatchesSelector ||
  1036. docElem.msMatchesSelector) )) ) {
  1037. assert(function( div ) {
  1038. // Check to see if it's possible to do matchesSelector
  1039. // on a disconnected node (IE 9)
  1040. support.disconnectedMatch = matches.call( div, "div" );
  1041. // This should fail with an exception
  1042. // Gecko does not error, returns false instead
  1043. matches.call( div, "[s!='']:x" );
  1044. rbuggyMatches.push( "!=", pseudos );
  1045. });
  1046. }
  1047. rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
  1048. rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
  1049. /* Contains
  1050. ---------------------------------------------------------------------- */
  1051. hasCompare = rnative.test( docElem.compareDocumentPosition );
  1052. // Element contains another
  1053. // Purposefully does not implement inclusive descendent
  1054. // As in, an element does not contain itself
  1055. contains = hasCompare || rnative.test( docElem.contains ) ?
  1056. function( a, b ) {
  1057. var adown = a.nodeType === 9 ? a.documentElement : a,
  1058. bup = b && b.parentNode;
  1059. return a === bup || !!( bup && bup.nodeType === 1 && (
  1060. adown.contains ?
  1061. adown.contains( bup ) :
  1062. a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
  1063. ));
  1064. } :
  1065. function( a, b ) {
  1066. if ( b ) {
  1067. while ( (b = b.parentNode) ) {
  1068. if ( b === a ) {
  1069. return true;
  1070. }
  1071. }
  1072. }
  1073. return false;
  1074. };
  1075. /* Sorting
  1076. ---------------------------------------------------------------------- */
  1077. // Document order sorting
  1078. sortOrder = hasCompare ?
  1079. function( a, b ) {
  1080. // Flag for duplicate removal
  1081. if ( a === b ) {
  1082. hasDuplicate = true;
  1083. return 0;
  1084. }
  1085. // Sort on method existence if only one input has compareDocumentPosition
  1086. var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
  1087. if ( compare ) {
  1088. return compare;
  1089. }
  1090. // Calculate position if both inputs belong to the same document
  1091. compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
  1092. a.compareDocumentPosition( b ) :
  1093. // Otherwise we know they are disconnected
  1094. 1;
  1095. // Disconnected nodes
  1096. if ( compare & 1 ||
  1097. (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
  1098. // Choose the first element that is related to our preferred document
  1099. if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
  1100. return -1;
  1101. }
  1102. if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
  1103. return 1;
  1104. }
  1105. // Maintain original order
  1106. return sortInput ?
  1107. ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
  1108. 0;
  1109. }
  1110. return compare & 4 ? -1 : 1;
  1111. } :
  1112. function( a, b ) {
  1113. // Exit early if the nodes are identical
  1114. if ( a === b ) {
  1115. hasDuplicate = true;
  1116. return 0;
  1117. }
  1118. var cur,
  1119. i = 0,
  1120. aup = a.parentNode,
  1121. bup = b.parentNode,
  1122. ap = [ a ],
  1123. bp = [ b ];
  1124. // Parentless nodes are either documents or disconnected
  1125. if ( !aup || !bup ) {
  1126. return a === doc ? -1 :
  1127. b === doc ? 1 :
  1128. aup ? -1 :
  1129. bup ? 1 :
  1130. sortInput ?
  1131. ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
  1132. 0;
  1133. // If the nodes are siblings, we can do a quick check
  1134. } else if ( aup === bup ) {
  1135. return siblingCheck( a, b );
  1136. }
  1137. // Otherwise we need full lists of their ancestors for comparison
  1138. cur = a;
  1139. while ( (cur = cur.parentNode) ) {
  1140. ap.unshift( cur );
  1141. }
  1142. cur = b;
  1143. while ( (cur = cur.parentNode) ) {
  1144. bp.unshift( cur );
  1145. }
  1146. // Walk down the tree looking for a discrepancy
  1147. while ( ap[i] === bp[i] ) {
  1148. i++;
  1149. }
  1150. return i ?
  1151. // Do a sibling check if the nodes have a common ancestor
  1152. siblingCheck( ap[i], bp[i] ) :
  1153. // Otherwise nodes in our document sort first
  1154. ap[i] === preferredDoc ? -1 :
  1155. bp[i] === preferredDoc ? 1 :
  1156. 0;
  1157. };
  1158. return doc;
  1159. };
  1160. Sizzle.matches = function( expr, elements ) {
  1161. return Sizzle( expr, null, null, elements );
  1162. };
  1163. Sizzle.matchesSelector = function( elem, expr ) {
  1164. // Set document vars if needed
  1165. if ( ( elem.ownerDocument || elem ) !== document ) {
  1166. setDocument( elem );
  1167. }
  1168. // Make sure that attribute selectors are quoted
  1169. expr = expr.replace( rattributeQuotes, "='$1']" );
  1170. if ( support.matchesSelector && documentIsHTML &&
  1171. ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
  1172. ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
  1173. try {
  1174. var ret = matches.call( elem, expr );
  1175. // IE 9's matchesSelector returns false on disconnected nodes
  1176. if ( ret || support.disconnectedMatch ||
  1177. // As well, disconnected nodes are said to be in a document
  1178. // fragment in IE 9
  1179. elem.document && elem.document.nodeType !== 11 ) {
  1180. return ret;
  1181. }
  1182. } catch(e) {}
  1183. }
  1184. return Sizzle( expr, document, null, [ elem ] ).length > 0;
  1185. };
  1186. Sizzle.contains = function( context, elem ) {
  1187. // Set document vars if needed
  1188. if ( ( context.ownerDocument || context ) !== document ) {
  1189. setDocument( context );
  1190. }
  1191. return contains( context, elem );
  1192. };
  1193. Sizzle.attr = function( elem, name ) {
  1194. // Set document vars if needed
  1195. if ( ( elem.ownerDocument || elem ) !== document ) {
  1196. setDocument( elem );
  1197. }
  1198. var fn = Expr.attrHandle[ name.toLowerCase() ],
  1199. // Don't get fooled by Object.prototype properties (jQuery #13807)
  1200. val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
  1201. fn( elem, name, !documentIsHTML ) :
  1202. undefined;
  1203. return val !== undefined ?
  1204. val :
  1205. support.attributes || !documentIsHTML ?
  1206. elem.getAttribute( name ) :
  1207. (val = elem.getAttributeNode(name)) && val.specified ?
  1208. val.value :
  1209. null;
  1210. };
  1211. Sizzle.error = function( msg ) {
  1212. throw new Error( "Syntax error, unrecognized expression: " + msg );
  1213. };
  1214. /**
  1215. * Document sorting and removing duplicates
  1216. * @param {ArrayLike} results
  1217. */
  1218. Sizzle.uniqueSort = function( results ) {
  1219. var elem,
  1220. duplicates = [],
  1221. j = 0,
  1222. i = 0;
  1223. // Unless we *know* we can detect duplicates, assume their presence
  1224. hasDuplicate = !support.detectDuplicates;
  1225. sortInput = !support.sortStable && results.slice( 0 );
  1226. results.sort( sortOrder );
  1227. if ( hasDuplicate ) {
  1228. while ( (elem = results[i++]) ) {
  1229. if ( elem === results[ i ] ) {
  1230. j = duplicates.push( i );
  1231. }
  1232. }
  1233. while ( j-- ) {
  1234. results.splice( duplicates[ j ], 1 );
  1235. }
  1236. }
  1237. // Clear input after sorting to release objects
  1238. // See https://github.com/jquery/sizzle/pull/225
  1239. sortInput = null;
  1240. return results;
  1241. };
  1242. /**
  1243. * Utility function for retrieving the text value of an array of DOM nodes
  1244. * @param {Array|Element} elem
  1245. */
  1246. getText = Sizzle.getText = function( elem ) {
  1247. var node,
  1248. ret = "",
  1249. i = 0,
  1250. nodeType = elem.nodeType;
  1251. if ( !nodeType ) {
  1252. // If no nodeType, this is expected to be an array
  1253. while ( (node = elem[i++]) ) {
  1254. // Do not traverse comment nodes
  1255. ret += getText( node );
  1256. }
  1257. } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
  1258. // Use textContent for elements
  1259. // innerText usage removed for consistency of new lines (jQuery #11153)
  1260. if ( typeof elem.textContent === "string" ) {
  1261. return elem.textContent;
  1262. } else {
  1263. // Traverse its children
  1264. for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
  1265. ret += getText( elem );
  1266. }
  1267. }
  1268. } else if ( nodeType === 3 || nodeType === 4 ) {
  1269. return elem.nodeValue;
  1270. }
  1271. // Do not include comment or processing instruction nodes
  1272. return ret;
  1273. };
  1274. Expr = Sizzle.selectors = {
  1275. // Can be adjusted by the user
  1276. cacheLength: 50,
  1277. createPseudo: markFunction,
  1278. match: matchExpr,
  1279. attrHandle: {},
  1280. find: {},
  1281. relative: {
  1282. ">": { dir: "parentNode", first: true },
  1283. " ": { dir: "parentNode" },
  1284. "+": { dir: "previousSibling", first: true },
  1285. "~": { dir: "previousSibling" }
  1286. },
  1287. preFilter: {
  1288. "ATTR": function( match ) {
  1289. match[1] = match[1].replace( runescape, funescape );
  1290. // Move the given value to match[3] whether quoted or unquoted
  1291. match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
  1292. if ( match[2] === "~=" ) {
  1293. match[3] = " " + match[3] + " ";
  1294. }
  1295. return match.slice( 0, 4 );
  1296. },
  1297. "CHILD": function( match ) {
  1298. /* matches from matchExpr["CHILD"]
  1299. 1 type (only|nth|...)
  1300. 2 what (child|of-type)
  1301. 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
  1302. 4 xn-component of xn+y argument ([+-]?\d*n|)
  1303. 5 sign of xn-component
  1304. 6 x of xn-component
  1305. 7 sign of y-component
  1306. 8 y of y-component
  1307. */
  1308. match[1] = match[1].toLowerCase();
  1309. if ( match[1].slice( 0, 3 ) === "nth" ) {
  1310. // nth-* requires argument
  1311. if ( !match[3] ) {
  1312. Sizzle.error( match[0] );
  1313. }
  1314. // numeric x and y parameters for Expr.filter.CHILD
  1315. // remember that false/true cast respectively to 0/1
  1316. match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
  1317. match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
  1318. // other types prohibit arguments
  1319. } else if ( match[3] ) {
  1320. Sizzle.error( match[0] );
  1321. }
  1322. return match;
  1323. },
  1324. "PSEUDO": function( match ) {
  1325. var excess,
  1326. unquoted = !match[6] && match[2];
  1327. if ( matchExpr["CHILD"].test( match[0] ) ) {
  1328. return null;
  1329. }
  1330. // Accept quoted arguments as-is
  1331. if ( match[3] ) {
  1332. match[2] = match[4] || match[5] || "";
  1333. // Strip excess characters from unquoted arguments
  1334. } else if ( unquoted && rpseudo.test( unquoted ) &&
  1335. // Get excess from tokenize (recursively)
  1336. (excess = tokenize( unquoted, true )) &&
  1337. // advance to the next closing parenthesis
  1338. (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
  1339. // excess is a negative index
  1340. match[0] = match[0].slice( 0, excess );
  1341. match[2] = unquoted.slice( 0, excess );
  1342. }
  1343. // Return only captures needed by the pseudo filter method (type and argument)
  1344. return match.slice( 0, 3 );
  1345. }
  1346. },
  1347. filter: {
  1348. "TAG": function( nodeNameSelector ) {
  1349. var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
  1350. return nodeNameSelector === "*" ?
  1351. function() { return true; } :
  1352. function( elem ) {
  1353. return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
  1354. };
  1355. },
  1356. "CLASS": function( className ) {
  1357. var pattern = classCache[ className + " " ];
  1358. return pattern ||
  1359. (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
  1360. classCache( className, function( elem ) {
  1361. return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
  1362. });
  1363. },
  1364. "ATTR": function( name, operator, check ) {
  1365. return function( elem ) {
  1366. var result = Sizzle.attr( elem, name );
  1367. if ( result == null ) {
  1368. return operator === "!=";
  1369. }
  1370. if ( !operator ) {
  1371. return true;
  1372. }
  1373. result += "";
  1374. return operator === "=" ? result === check :
  1375. operator === "!=" ? result !== check :
  1376. operator === "^=" ? check && result.indexOf( check ) === 0 :
  1377. operator === "*=" ? check && result.indexOf( check ) > -1 :
  1378. operator === "$=" ? check && result.slice( -check.length ) === check :
  1379. operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
  1380. operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
  1381. false;
  1382. };
  1383. },
  1384. "CHILD": function( type, what, argument, first, last ) {
  1385. var simple = type.slice( 0, 3 ) !== "nth",
  1386. forward = type.slice( -4 ) !== "last",
  1387. ofType = what === "of-type";
  1388. return first === 1 && last === 0 ?
  1389. // Shortcut for :nth-*(n)
  1390. function( elem ) {
  1391. return !!elem.parentNode;
  1392. } :
  1393. function( elem, context, xml ) {
  1394. var cache, outerCache, node, diff, nodeIndex, start,
  1395. dir = simple !== forward ? "nextSibling" : "previousSibling",
  1396. parent = elem.parentNode,
  1397. name = ofType && elem.nodeName.toLowerCase(),
  1398. useCache = !xml && !ofType;
  1399. if ( parent ) {
  1400. // :(first|last|only)-(child|of-type)
  1401. if ( simple ) {
  1402. while ( dir ) {
  1403. node = elem;
  1404. while ( (node = node[ dir ]) ) {
  1405. if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
  1406. return false;
  1407. }
  1408. }
  1409. // Reverse direction for :only-* (if we haven't yet done so)
  1410. start = dir = type === "only" && !start && "nextSibling";
  1411. }
  1412. return true;
  1413. }
  1414. start = [ forward ? parent.firstChild : parent.lastChild ];
  1415. // non-xml :nth-child(...) stores cache data on `parent`
  1416. if ( forward && useCache ) {
  1417. // Seek `elem` from a previously-cached index
  1418. outerCache = parent[ expando ] || (parent[ expando ] = {});
  1419. cache = outerCache[ type ] || [];
  1420. nodeIndex = cache[0] === dirruns && cache[1];
  1421. diff = cache[0] === dirruns && cache[2];
  1422. node = nodeIndex && parent.childNodes[ nodeIndex ];
  1423. while ( (node = ++nodeIndex && node && node[ dir ] ||
  1424. // Fallback to seeking `elem` from the start
  1425. (diff = nodeIndex = 0) || start.pop()) ) {
  1426. // When found, cache indexes on `parent` and break
  1427. if ( node.nodeType === 1 && ++diff && node === elem ) {
  1428. outerCache[ type ] = [ dirruns, nodeIndex, diff ];
  1429. break;
  1430. }
  1431. }
  1432. // Use previously-cached element index if available
  1433. } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
  1434. diff = cache[1];
  1435. // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
  1436. } else {
  1437. // Use the same loop as above to seek `elem` from the start
  1438. while ( (node = ++nodeIndex && node && node[ dir ] ||
  1439. (diff = nodeIndex = 0) || start.pop()) ) {
  1440. if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
  1441. // Cache the index of each encountered element
  1442. if ( useCache ) {
  1443. (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
  1444. }
  1445. if ( node === elem ) {
  1446. break;
  1447. }
  1448. }
  1449. }
  1450. }
  1451. // Incorporate the offset, then check against cycle size
  1452. diff -= last;
  1453. return diff === first || ( diff % first === 0 && diff / first >= 0 );
  1454. }
  1455. };
  1456. },
  1457. "PSEUDO": function( pseudo, argument ) {
  1458. // pseudo-class names are case-insensitive
  1459. // http://www.w3.org/TR/selectors/#pseudo-classes
  1460. // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
  1461. // Remember that setFilters inherits from pseudos
  1462. var args,
  1463. fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
  1464. Sizzle.error( "unsupported pseudo: " + pseudo );
  1465. // The user may use createPseudo to indicate that
  1466. // arguments are needed to create the filter function
  1467. // just as Sizzle does
  1468. if ( fn[ expando ] ) {
  1469. return fn( argument );
  1470. }
  1471. // But maintain support for old signatures
  1472. if ( fn.length > 1 ) {
  1473. args = [ pseudo, pseudo, "", argument ];
  1474. return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
  1475. markFunction(function( seed, matches ) {
  1476. var idx,
  1477. matched = fn( seed, argument ),
  1478. i = matched.length;
  1479. while ( i-- ) {
  1480. idx = indexOf.call( seed, matched[i] );
  1481. seed[ idx ] = !( matches[ idx ] = matched[i] );
  1482. }
  1483. }) :
  1484. function( elem ) {
  1485. return fn( elem, 0, args );
  1486. };
  1487. }
  1488. return fn;
  1489. }
  1490. },
  1491. pseudos: {
  1492. // Potentially complex pseudos
  1493. "not": markFunction(function( selector ) {
  1494. // Trim the selector passed to compile
  1495. // to avoid treating leading and trailing
  1496. // spaces as combinators
  1497. var input = [],
  1498. results = [],
  1499. matcher = compile( selector.replace( rtrim, "$1" ) );
  1500. return matcher[ expando ] ?
  1501. markFunction(function( seed, matches, context, xml ) {
  1502. var elem,
  1503. unmatched = matcher( seed, null, xml, [] ),
  1504. i = seed.length;
  1505. // Match elements unmatched by `matcher`
  1506. while ( i-- ) {
  1507. if ( (elem = unmatched[i]) ) {
  1508. seed[i] = !(matches[i] = elem);
  1509. }
  1510. }
  1511. }) :
  1512. function( elem, context, xml ) {
  1513. input[0] = elem;
  1514. matcher( input, null, xml, results );
  1515. return !results.pop();
  1516. };
  1517. }),
  1518. "has": markFunction(function( selector ) {
  1519. return function( elem ) {
  1520. return Sizzle( selector, elem ).length > 0;
  1521. };
  1522. }),
  1523. "contains": markFunction(function( text ) {
  1524. return function( elem ) {
  1525. return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
  1526. };
  1527. }),
  1528. // "Whether an element is represented by a :lang() selector
  1529. // is based solely on the element's language value
  1530. // being equal to the identifier C,
  1531. // or beginning with the identifier C immediately followed by "-".
  1532. // The matching of C against the element's language value is performed case-insensitively.
  1533. // The identifier C does not have to be a valid language name."
  1534. // http://www.w3.org/TR/selectors/#lang-pseudo
  1535. "lang": markFunction( function( lang ) {
  1536. // lang value must be a valid identifier
  1537. if ( !ridentifier.test(lang || "") ) {
  1538. Sizzle.error( "unsupported lang: " + lang );
  1539. }
  1540. lang = lang.replace( runescape, funescape ).toLowerCase();
  1541. return function( elem ) {
  1542. var elemLang;
  1543. do {
  1544. if ( (elemLang = documentIsHTML ?
  1545. elem.lang :
  1546. elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
  1547. elemLang = elemLang.toLowerCase();
  1548. return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
  1549. }
  1550. } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
  1551. return false;
  1552. };
  1553. }),
  1554. // Miscellaneous
  1555. "target": function( elem ) {
  1556. var hash = window.location && window.location.hash;
  1557. return hash && hash.slice( 1 ) === elem.id;
  1558. },
  1559. "root": function( elem ) {
  1560. return elem === docElem;
  1561. },
  1562. "focus": function( elem ) {
  1563. return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
  1564. },
  1565. // Boolean properties
  1566. "enabled": function( elem ) {
  1567. return elem.disabled === false;
  1568. },
  1569. "disabled": function( elem ) {
  1570. return elem.disabled === true;
  1571. },
  1572. "checked": function( elem ) {
  1573. // In CSS3, :checked should return both checked and selected elements
  1574. // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
  1575. var nodeName = elem.nodeName.toLowerCase();
  1576. return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
  1577. },
  1578. "selected": function( elem ) {
  1579. // Accessing this property makes selected-by-default
  1580. // options in Safari work properly
  1581. if ( elem.parentNode ) {
  1582. elem.parentNode.selectedIndex;
  1583. }
  1584. return elem.selected === true;
  1585. },
  1586. // Contents
  1587. "empty": function( elem ) {
  1588. // http://www.w3.org/TR/selectors/#empty-pseudo
  1589. // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
  1590. // but not by others (comment: 8; processing instruction: 7; etc.)
  1591. // nodeType < 6 works because attributes (2) do not appear as children
  1592. for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
  1593. if ( elem.nodeType < 6 ) {
  1594. return false;
  1595. }
  1596. }
  1597. return true;
  1598. },
  1599. "parent": function( elem ) {
  1600. return !Expr.pseudos["empty"]( elem );
  1601. },
  1602. // Element/input types
  1603. "header": function( elem ) {
  1604. return rheader.test( elem.nodeName );
  1605. },
  1606. "input": function( elem ) {
  1607. return rinputs.test( elem.nodeName );
  1608. },
  1609. "button": function( elem ) {
  1610. var name = elem.nodeName.toLowerCase();
  1611. return name === "input" && elem.type === "button" || name === "button";
  1612. },
  1613. "text": function( elem ) {
  1614. var attr;
  1615. return elem.nodeName.toLowerCase() === "input" &&
  1616. elem.type === "text" &&
  1617. // Support: IE<8
  1618. // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
  1619. ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
  1620. },
  1621. // Position-in-collection
  1622. "first": createPositionalPseudo(function() {
  1623. return [ 0 ];
  1624. }),
  1625. "last": createPositionalPseudo(function( matchIndexes, length ) {
  1626. return [ length - 1 ];
  1627. }),
  1628. "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
  1629. return [ argument < 0 ? argument + length : argument ];
  1630. }),
  1631. "even": createPositionalPseudo(function( matchIndexes, length ) {
  1632. var i = 0;
  1633. for ( ; i < length; i += 2 ) {
  1634. matchIndexes.push( i );
  1635. }
  1636. return matchIndexes;
  1637. }),
  1638. "odd": createPositionalPseudo(function( matchIndexes, length ) {
  1639. var i = 1;
  1640. for ( ; i < length; i += 2 ) {
  1641. matchIndexes.push( i );
  1642. }
  1643. return matchIndexes;
  1644. }),
  1645. "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
  1646. var i = argument < 0 ? argument + length : argument;
  1647. for ( ; --i >= 0; ) {
  1648. matchIndexes.push( i );
  1649. }
  1650. return matchIndexes;
  1651. }),
  1652. "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
  1653. var i = argument < 0 ? argument + length : argument;
  1654. for ( ; ++i < length; ) {
  1655. matchIndexes.push( i );
  1656. }
  1657. return matchIndexes;
  1658. })
  1659. }
  1660. };
  1661. Expr.pseudos["nth"] = Expr.pseudos["eq"];
  1662. // Add button/input type pseudos
  1663. for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
  1664. Expr.pseudos[ i ] = createInputPseudo( i );
  1665. }
  1666. for ( i in { submit: true, reset: true } ) {
  1667. Expr.pseudos[ i ] = createButtonPseudo( i );
  1668. }
  1669. // Easy API for creating new setFilters
  1670. function setFilters() {}
  1671. setFilters.prototype = Expr.filters = Expr.pseudos;
  1672. Expr.setFilters = new setFilters();
  1673. tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
  1674. var matched, match, tokens, type,
  1675. soFar, groups, preFilters,
  1676. cached = tokenCache[ selector + " " ];
  1677. if ( cached ) {
  1678. return parseOnly ? 0 : cached.slice( 0 );
  1679. }
  1680. soFar = selector;
  1681. groups = [];
  1682. preFilters = Expr.preFilter;
  1683. while ( soFar ) {
  1684. // Comma and first run
  1685. if ( !matched || (match = rcomma.exec( soFar )) ) {
  1686. if ( match ) {
  1687. // Don't consume trailing commas as valid
  1688. soFar = soFar.slice( match[0].length ) || soFar;
  1689. }
  1690. groups.push( (tokens = []) );
  1691. }
  1692. matched = false;
  1693. // Combinators
  1694. if ( (match = rcombinators.exec( soFar )) ) {
  1695. matched = match.shift();
  1696. tokens.push({
  1697. value: matched,
  1698. // Cast descendant combinators to space
  1699. type: match[0].replace( rtrim, " " )
  1700. });
  1701. soFar = soFar.slice( matched.length );
  1702. }
  1703. // Filters
  1704. for ( type in Expr.filter ) {
  1705. if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
  1706. (match = preFilters[ type ]( match ))) ) {
  1707. matched = match.shift();
  1708. tokens.push({
  1709. value: matched,
  1710. type: type,
  1711. matches: match
  1712. });
  1713. soFar = soFar.slice( matched.length );
  1714. }
  1715. }
  1716. if ( !matched ) {
  1717. break;
  1718. }
  1719. }
  1720. // Return the length of the invalid excess
  1721. // if we're just parsing
  1722. // Otherwise, throw an error or return tokens
  1723. return parseOnly ?
  1724. soFar.length :
  1725. soFar ?
  1726. Sizzle.error( selector ) :
  1727. // Cache the tokens
  1728. tokenCache( selector, groups ).slice( 0 );
  1729. };
  1730. function toSelector( tokens ) {
  1731. var i = 0,
  1732. len = tokens.length,
  1733. selector = "";
  1734. for ( ; i < len; i++ ) {
  1735. selector += tokens[i].value;
  1736. }
  1737. return selector;
  1738. }
  1739. function addCombinator( matcher, combinator, base ) {
  1740. var dir = combinator.dir,
  1741. checkNonElements = base && dir === "parentNode",
  1742. doneName = done++;
  1743. return combinator.first ?
  1744. // Check against closest ancestor/preceding element
  1745. function( elem, context, xml ) {
  1746. while ( (elem = elem[ dir ]) ) {
  1747. if ( elem.nodeType === 1 || checkNonElements ) {
  1748. return matcher( elem, context, xml );
  1749. }
  1750. }
  1751. } :
  1752. // Check against all ancestor/preceding elements
  1753. function( elem, context, xml ) {
  1754. var oldCache, outerCache,
  1755. newCache = [ dirruns, doneName ];
  1756. // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
  1757. if ( xml ) {
  1758. while ( (elem = elem[ dir ]) ) {
  1759. if ( elem.nodeType === 1 || checkNonElements ) {
  1760. if ( matcher( elem, context, xml ) ) {
  1761. return true;
  1762. }
  1763. }
  1764. }
  1765. } else {
  1766. while ( (elem = elem[ dir ]) ) {
  1767. if ( elem.nodeType === 1 || checkNonElements ) {
  1768. outerCache = elem[ expando ] || (elem[ expando ] = {});
  1769. if ( (oldCache = outerCache[ dir ]) &&
  1770. oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
  1771. // Assign to newCache so results back-propagate to previous elements
  1772. return (newCache[ 2 ] = oldCache[ 2 ]);
  1773. } else {
  1774. // Reuse newcache so results back-propagate to previous elements
  1775. outerCache[ dir ] = newCache;
  1776. // A match means we're done; a fail means we have to keep checking
  1777. if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
  1778. return true;
  1779. }
  1780. }
  1781. }
  1782. }
  1783. }
  1784. };
  1785. }
  1786. function elementMatcher( matchers ) {
  1787. return matchers.length > 1 ?
  1788. function( elem, context, xml ) {
  1789. var i = matchers.length;
  1790. while ( i-- ) {
  1791. if ( !matchers[i]( elem, context, xml ) ) {
  1792. return false;
  1793. }
  1794. }
  1795. return true;
  1796. } :
  1797. matchers[0];
  1798. }
  1799. function multipleContexts( selector, contexts, results ) {
  1800. var i = 0,
  1801. len = contexts.length;
  1802. for ( ; i < len; i++ ) {
  1803. Sizzle( selector, contexts[i], results );
  1804. }
  1805. return results;
  1806. }
  1807. function condense( unmatched, map, filter, context, xml ) {
  1808. var elem,
  1809. newUnmatched = [],
  1810. i = 0,
  1811. len = unmatched.length,
  1812. mapped = map != null;
  1813. for ( ; i < len; i++ ) {
  1814. if ( (elem = unmatched[i]) ) {
  1815. if ( !filter || filter( elem, context, xml ) ) {
  1816. newUnmatched.push( elem );
  1817. if ( mapped ) {
  1818. map.push( i );
  1819. }
  1820. }
  1821. }
  1822. }
  1823. return newUnmatched;
  1824. }
  1825. function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
  1826. if ( postFilter && !postFilter[ expando ] ) {
  1827. postFilter = setMatcher( postFilter );
  1828. }
  1829. if ( postFinder && !postFinder[ expando ] ) {
  1830. postFinder = setMatcher( postFinder, postSelector );
  1831. }
  1832. return markFunction(function( seed, results, context, xml ) {
  1833. var temp, i, elem,
  1834. preMap = [],
  1835. postMap = [],
  1836. preexisting = results.length,
  1837. // Get initial elements from seed or context
  1838. elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
  1839. // Prefilter to get matcher input, preserving a map for seed-results synchronization
  1840. matcherIn = preFilter && ( seed || !selector ) ?
  1841. condense( elems, preMap, preFilter, context, xml ) :
  1842. elems,
  1843. matcherOut = matcher ?
  1844. // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
  1845. postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
  1846. // ...intermediate processing is necessary
  1847. [] :
  1848. // ...otherwise use results directly
  1849. results :
  1850. matcherIn;
  1851. // Find primary matches
  1852. if ( matcher ) {
  1853. matcher( matcherIn, matcherOut, context, xml );
  1854. }
  1855. // Apply postFilter
  1856. if ( postFilter ) {
  1857. temp = condense( matcherOut, postMap );
  1858. postFilter( temp, [], context, xml );
  1859. // Un-match failing elements by moving them back to matcherIn
  1860. i = temp.length;
  1861. while ( i-- ) {
  1862. if ( (elem = temp[i]) ) {
  1863. matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
  1864. }
  1865. }
  1866. }
  1867. if ( seed ) {
  1868. if ( postFinder || preFilter ) {
  1869. if ( postFinder ) {
  1870. // Get the final matcherOut by condensing this intermediate into postFinder contexts
  1871. temp = [];
  1872. i = matcherOut.length;
  1873. while ( i-- ) {
  1874. if ( (elem = matcherOut[i]) ) {
  1875. // Restore matcherIn since elem is not yet a final match
  1876. temp.push( (matcherIn[i] = elem) );
  1877. }
  1878. }
  1879. postFinder( null, (matcherOut = []), temp, xml );
  1880. }
  1881. // Move matched elements from seed to results to keep them synchronized
  1882. i = matcherOut.length;
  1883. while ( i-- ) {
  1884. if ( (elem = matcherOut[i]) &&
  1885. (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
  1886. seed[temp] = !(results[temp] = elem);
  1887. }
  1888. }
  1889. }
  1890. // Add elements to results, through postFinder if defined
  1891. } else {
  1892. matcherOut = condense(
  1893. matcherOut === results ?
  1894. matcherOut.splice( preexisting, matcherOut.length ) :
  1895. matcherOut
  1896. );
  1897. if ( postFinder ) {
  1898. postFinder( null, results, matcherOut, xml );
  1899. } else {
  1900. push.apply( results, matcherOut );
  1901. }
  1902. }
  1903. });
  1904. }
  1905. function matcherFromTokens( tokens ) {
  1906. var checkContext, matcher, j,
  1907. len = tokens.length,
  1908. leadingRelative = Expr.relative[ tokens[0].type ],
  1909. implicitRelative = leadingRelative || Expr.relative[" "],
  1910. i = leadingRelative ? 1 : 0,
  1911. // The foundational matcher ensures that elements are reachable from top-level context(s)
  1912. matchContext = addCombinator( function( elem ) {
  1913. return elem === checkContext;
  1914. }, implicitRelative, true ),
  1915. matchAnyContext = addCombinator( function( elem ) {
  1916. return indexOf.call( checkContext, elem ) > -1;
  1917. }, implicitRelative, true ),
  1918. matchers = [ function( elem, context, xml ) {
  1919. return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
  1920. (checkContext = context).nodeType ?
  1921. matchContext( elem, context, xml ) :
  1922. matchAnyContext( elem, context, xml ) );
  1923. } ];
  1924. for ( ; i < len; i++ ) {
  1925. if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
  1926. matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
  1927. } else {
  1928. matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
  1929. // Return special upon seeing a positional matcher
  1930. if ( matcher[ expando ] ) {
  1931. // Find the next relative operator (if any) for proper handling
  1932. j = ++i;
  1933. for ( ; j < len; j++ ) {
  1934. if ( Expr.relative[ tokens[j].type ] ) {
  1935. break;
  1936. }
  1937. }
  1938. return setMatcher(
  1939. i > 1 && elementMatcher( matchers ),
  1940. i > 1 && toSelector(
  1941. // If the preceding token was a descendant combinator, insert an implicit any-element `*`
  1942. tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
  1943. ).replace( rtrim, "$1" ),
  1944. matcher,
  1945. i < j && matcherFromTokens( tokens.slice( i, j ) ),
  1946. j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
  1947. j < len && toSelector( tokens )
  1948. );
  1949. }
  1950. matchers.push( matcher );
  1951. }
  1952. }
  1953. return elementMatcher( matchers );
  1954. }
  1955. function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
  1956. var bySet = setMatchers.length > 0,
  1957. byElement = elementMatchers.length > 0,
  1958. superMatcher = function( seed, context, xml, results, outermost ) {
  1959. var elem, j, matcher,
  1960. matchedCount = 0,
  1961. i = "0",
  1962. unmatched = seed && [],
  1963. setMatched = [],
  1964. contextBackup = outermostContext,
  1965. // We must always have either seed elements or outermost context
  1966. elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
  1967. // Use integer dirruns iff this is the outermost matcher
  1968. dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
  1969. len = elems.length;
  1970. if ( outermost ) {
  1971. outermostContext = context !== document && context;
  1972. }
  1973. // Add elements passing elementMatchers directly to results
  1974. // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
  1975. // Support: IE<9, Safari
  1976. // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
  1977. for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
  1978. if ( byElement && elem ) {
  1979. j = 0;
  1980. while ( (matcher = elementMatchers[j++]) ) {
  1981. if ( matcher( elem, context, xml ) ) {
  1982. results.push( elem );
  1983. break;
  1984. }
  1985. }
  1986. if ( outermost ) {
  1987. dirruns = dirrunsUnique;
  1988. }
  1989. }
  1990. // Track unmatched elements for set filters
  1991. if ( bySet ) {
  1992. // They will have gone through all possible matchers
  1993. if ( (elem = !matcher && elem) ) {
  1994. matchedCount--;
  1995. }
  1996. // Lengthen the array for every element, matched or not
  1997. if ( seed ) {
  1998. unmatched.push( elem );
  1999. }
  2000. }
  2001. }
  2002. // Apply set filters to unmatched elements
  2003. matchedCount += i;
  2004. if ( bySet && i !== matchedCount ) {
  2005. j = 0;
  2006. while ( (matcher = setMatchers[j++]) ) {
  2007. matcher( unmatched, setMatched, context, xml );
  2008. }
  2009. if ( seed ) {
  2010. // Reintegrate element matches to eliminate the need for sorting
  2011. if ( matchedCount > 0 ) {
  2012. while ( i-- ) {
  2013. if ( !(unmatched[i] || setMatched[i]) ) {
  2014. setMatched[i] = pop.call( results );
  2015. }
  2016. }
  2017. }
  2018. // Discard index placeholder values to get only actual matches
  2019. setMatched = condense( setMatched );
  2020. }
  2021. // Add matches to results
  2022. push.apply( results, setMatched );
  2023. // Seedless set matches succeeding multiple successful matchers stipulate sorting
  2024. if ( outermost && !seed && setMatched.length > 0 &&
  2025. ( matchedCount + setMatchers.length ) > 1 ) {
  2026. Sizzle.uniqueSort( results );
  2027. }
  2028. }
  2029. // Override manipulation of globals by nested matchers
  2030. if ( outermost ) {
  2031. dirruns = dirrunsUnique;
  2032. outermostContext = contextBackup;
  2033. }
  2034. return unmatched;
  2035. };
  2036. return bySet ?
  2037. markFunction( superMatcher ) :
  2038. superMatcher;
  2039. }
  2040. compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
  2041. var i,
  2042. setMatchers = [],
  2043. elementMatchers = [],
  2044. cached = compilerCache[ selector + " " ];
  2045. if ( !cached ) {
  2046. // Generate a function of recursive functions that can be used to check each element
  2047. if ( !match ) {
  2048. match = tokenize( selector );
  2049. }
  2050. i = match.length;
  2051. while ( i-- ) {
  2052. cached = matcherFromTokens( match[i] );
  2053. if ( cached[ expando ] ) {
  2054. setMatchers.push( cached );
  2055. } else {
  2056. elementMatchers.push( cached );
  2057. }
  2058. }
  2059. // Cache the compiled function
  2060. cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
  2061. // Save selector and tokenization
  2062. cached.selector = selector;
  2063. }
  2064. return cached;
  2065. };
  2066. /**
  2067. * A low-level selection function that works with Sizzle's compiled
  2068. * selector functions
  2069. * @param {String|Function} selector A selector or a pre-compiled
  2070. * selector function built with Sizzle.compile
  2071. * @param {Element} context
  2072. * @param {Array} [results]
  2073. * @param {Array} [seed] A set of elements to match against
  2074. */
  2075. select = Sizzle.select = function( selector, context, results, seed ) {
  2076. var i, tokens, token, type, find,
  2077. compiled = typeof selector === "function" && selector,
  2078. match = !seed && tokenize( (selector = compiled.selector || selector) );
  2079. results = results || [];
  2080. // Try to minimize operations if there is no seed and only one group
  2081. if ( match.length === 1 ) {
  2082. // Take a shortcut and set the context if the root selector is an ID
  2083. tokens = match[0] = match[0].slice( 0 );
  2084. if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
  2085. support.getById && context.nodeType === 9 && documentIsHTML &&
  2086. Expr.relative[ tokens[1].type ] ) {
  2087. context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
  2088. if ( !context ) {
  2089. return results;
  2090. // Precompiled matchers will still verify ancestry, so step up a level
  2091. } else if ( compiled ) {
  2092. context = context.parentNode;
  2093. }
  2094. selector = selector.slice( tokens.shift().value.length );
  2095. }
  2096. // Fetch a seed set for right-to-left matching
  2097. i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
  2098. while ( i-- ) {
  2099. token = tokens[i];
  2100. // Abort if we hit a combinator
  2101. if ( Expr.relative[ (type = token.type) ] ) {
  2102. break;
  2103. }
  2104. if ( (find = Expr.find[ type ]) ) {
  2105. // Search, expanding context for leading sibling combinators
  2106. if ( (seed = find(
  2107. token.matches[0].replace( runescape, funescape ),
  2108. rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
  2109. )) ) {
  2110. // If seed is empty or no tokens remain, we can return early
  2111. tokens.splice( i, 1 );
  2112. selector = seed.length && toSelector( tokens );
  2113. if ( !selector ) {
  2114. push.apply( results, seed );
  2115. return results;
  2116. }
  2117. break;
  2118. }
  2119. }
  2120. }
  2121. }
  2122. // Compile and execute a filtering function if one is not provided
  2123. // Provide `match` to avoid retokenization if we modified the selector above
  2124. ( compiled || compile( selector, match ) )(
  2125. seed,
  2126. context,
  2127. !documentIsHTML,
  2128. results,
  2129. rsibling.test( selector ) && testContext( context.parentNode ) || context
  2130. );
  2131. return results;
  2132. };
  2133. // One-time assignments
  2134. // Sort stability
  2135. support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
  2136. // Support: Chrome<14
  2137. // Always assume duplicates if they aren't passed to the comparison function
  2138. support.detectDuplicates = !!hasDuplicate;
  2139. // Initialize against the default document
  2140. setDocument();
  2141. // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
  2142. // Detached nodes confoundingly follow *each other*
  2143. support.sortDetached = assert(function( div1 ) {
  2144. // Should return 1, but returns 4 (following)
  2145. return div1.compareDocumentPosition( document.createElement("div") ) & 1;
  2146. });
  2147. // Support: IE<8
  2148. // Prevent attribute/property "interpolation"
  2149. // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
  2150. if ( !assert(function( div ) {
  2151. div.innerHTML = "<a href='#'></a>";
  2152. return div.firstChild.getAttribute("href") === "#" ;
  2153. }) ) {
  2154. addHandle( "type|href|height|width", function( elem, name, isXML ) {
  2155. if ( !isXML ) {
  2156. return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
  2157. }
  2158. });
  2159. }
  2160. // Support: IE<9
  2161. // Use defaultValue in place of getAttribute("value")
  2162. if ( !support.attributes || !assert(function( div ) {
  2163. div.innerHTML = "<input/>";
  2164. div.firstChild.setAttribute( "value", "" );
  2165. return div.firstChild.getAttribute( "value" ) === "";
  2166. }) ) {
  2167. addHandle( "value", function( elem, name, isXML ) {
  2168. if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
  2169. return elem.defaultValue;
  2170. }
  2171. });
  2172. }
  2173. // Support: IE<9
  2174. // Use getAttributeNode to fetch booleans when getAttribute lies
  2175. if ( !assert(function( div ) {
  2176. return div.getAttribute("disabled") == null;
  2177. }) ) {
  2178. addHandle( booleans, function( elem, name, isXML ) {
  2179. var val;
  2180. if ( !isXML ) {
  2181. return elem[ name ] === true ? name.toLowerCase() :
  2182. (val = elem.getAttributeNode( name )) && val.specified ?
  2183. val.value :
  2184. null;
  2185. }
  2186. });
  2187. }
  2188. return Sizzle;
  2189. })( window );
  2190. jQuery.find = Sizzle;
  2191. jQuery.expr = Sizzle.selectors;
  2192. jQuery.expr[":"] = jQuery.expr.pseudos;
  2193. jQuery.unique = Sizzle.uniqueSort;
  2194. jQuery.text = Sizzle.getText;
  2195. jQuery.isXMLDoc = Sizzle.isXML;
  2196. jQuery.contains = Sizzle.contains;
  2197. var rneedsContext = jQuery.expr.match.needsContext;
  2198. var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
  2199. var risSimple = /^.[^:#\[\.,]*$/;
  2200. // Implement the identical functionality for filter and not
  2201. function winnow( elements, qualifier, not ) {
  2202. if ( jQuery.isFunction( qualifier ) ) {
  2203. return jQuery.grep( elements, function( elem, i ) {
  2204. /* jshint -W018 */
  2205. return !!qualifier.call( elem, i, elem ) !== not;
  2206. });
  2207. }
  2208. if ( qualifier.nodeType ) {
  2209. return jQuery.grep( elements, function( elem ) {
  2210. return ( elem === qualifier ) !== not;
  2211. });
  2212. }
  2213. if ( typeof qualifier === "string" ) {
  2214. if ( risSimple.test( qualifier ) ) {
  2215. return jQuery.filter( qualifier, elements, not );
  2216. }
  2217. qualifier = jQuery.filter( qualifier, elements );
  2218. }
  2219. return jQuery.grep( elements, function( elem ) {
  2220. return ( indexOf.call( qualifier, elem ) >= 0 ) !== not;
  2221. });
  2222. }
  2223. jQuery.filter = function( expr, elems, not ) {
  2224. var elem = elems[ 0 ];
  2225. if ( not ) {
  2226. expr = ":not(" + expr + ")";
  2227. }
  2228. return elems.length === 1 && elem.nodeType === 1 ?
  2229. jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
  2230. jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
  2231. return elem.nodeType === 1;
  2232. }));
  2233. };
  2234. jQuery.fn.extend({
  2235. find: function( selector ) {
  2236. var i,
  2237. len = this.length,
  2238. ret = [],
  2239. self = this;
  2240. if ( typeof selector !== "string" ) {
  2241. return this.pushStack( jQuery( selector ).filter(function() {
  2242. for ( i = 0; i < len; i++ ) {
  2243. if ( jQuery.contains( self[ i ], this ) ) {
  2244. return true;
  2245. }
  2246. }
  2247. }) );
  2248. }
  2249. for ( i = 0; i < len; i++ ) {
  2250. jQuery.find( selector, self[ i ], ret );
  2251. }
  2252. // Needed because $( selector, context ) becomes $( context ).find( selector )
  2253. ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
  2254. ret.selector = this.selector ? this.selector + " " + selector : selector;
  2255. return ret;
  2256. },
  2257. filter: function( selector ) {
  2258. return this.pushStack( winnow(this, selector || [], false) );
  2259. },
  2260. not: function( selector ) {
  2261. return this.pushStack( winnow(this, selector || [], true) );
  2262. },
  2263. is: function( selector ) {
  2264. return !!winnow(
  2265. this,
  2266. // If this is a positional/relative selector, check membership in the returned set
  2267. // so $("p:first").is("p:last") won't return true for a doc with two "p".
  2268. typeof selector === "string" && rneedsContext.test( selector ) ?
  2269. jQuery( selector ) :
  2270. selector || [],
  2271. false
  2272. ).length;
  2273. }
  2274. });
  2275. // Initialize a jQuery object
  2276. // A central reference to the root jQuery(document)
  2277. var rootjQuery,
  2278. // A simple way to check for HTML strings
  2279. // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
  2280. // Strict HTML recognition (#11290: must start with <)
  2281. rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
  2282. init = jQuery.fn.init = function( selector, context ) {
  2283. var match, elem;
  2284. // HANDLE: $(""), $(null), $(undefined), $(false)
  2285. if ( !selector ) {
  2286. return this;
  2287. }
  2288. // Handle HTML strings
  2289. if ( typeof selector === "string" ) {
  2290. if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) {
  2291. // Assume that strings that start and end with <> are HTML and skip the regex check
  2292. match = [ null, selector, null ];
  2293. } else {
  2294. match = rquickExpr.exec( selector );
  2295. }
  2296. // Match html or make sure no context is specified for #id
  2297. if ( match && (match[1] || !context) ) {
  2298. // HANDLE: $(html) -> $(array)
  2299. if ( match[1] ) {
  2300. context = context instanceof jQuery ? context[0] : context;
  2301. // scripts is true for back-compat
  2302. // Intentionally let the error be thrown if parseHTML is not present
  2303. jQuery.merge( this, jQuery.parseHTML(
  2304. match[1],
  2305. context && context.nodeType ? context.ownerDocument || context : document,
  2306. true
  2307. ) );
  2308. // HANDLE: $(html, props)
  2309. if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
  2310. for ( match in context ) {
  2311. // Properties of context are called as methods if possible
  2312. if ( jQuery.isFunction( this[ match ] ) ) {
  2313. this[ match ]( context[ match ] );
  2314. // ...and otherwise set as attributes
  2315. } else {
  2316. this.attr( match, context[ match ] );
  2317. }
  2318. }
  2319. }
  2320. return this;
  2321. // HANDLE: $(#id)
  2322. } else {
  2323. elem = document.getElementById( match[2] );
  2324. // Check parentNode to catch when Blackberry 4.6 returns
  2325. // nodes that are no longer in the document #6963
  2326. if ( elem && elem.parentNode ) {
  2327. // Inject the element directly into the jQuery object
  2328. this.length = 1;
  2329. this[0] = elem;
  2330. }
  2331. this.context = document;
  2332. this.selector = selector;
  2333. return this;
  2334. }
  2335. // HANDLE: $(expr, $(...))
  2336. } else if ( !context || context.jquery ) {
  2337. return ( context || rootjQuery ).find( selector );
  2338. // HANDLE: $(expr, context)
  2339. // (which is just equivalent to: $(context).find(expr)
  2340. } else {
  2341. return this.constructor( context ).find( selector );
  2342. }
  2343. // HANDLE: $(DOMElement)
  2344. } else if ( selector.nodeType ) {
  2345. this.context = this[0] = selector;
  2346. this.length = 1;
  2347. return this;
  2348. // HANDLE: $(function)
  2349. // Shortcut for document ready
  2350. } else if ( jQuery.isFunction( selector ) ) {
  2351. return typeof rootjQuery.ready !== "undefined" ?
  2352. rootjQuery.ready( selector ) :
  2353. // Execute immediately if ready is not present
  2354. selector( jQuery );
  2355. }
  2356. if ( selector.selector !== undefined ) {
  2357. this.selector = selector.selector;
  2358. this.context = selector.context;
  2359. }
  2360. return jQuery.makeArray( selector, this );
  2361. };
  2362. // Give the init function the jQuery prototype for later instantiation
  2363. init.prototype = jQuery.fn;
  2364. // Initialize central reference
  2365. rootjQuery = jQuery( document );
  2366. var rparentsprev = /^(?:parents|prev(?:Until|All))/,
  2367. // methods guaranteed to produce a unique set when starting from a unique set
  2368. guaranteedUnique = {
  2369. children: true,
  2370. contents: true,
  2371. next: true,
  2372. prev: true
  2373. };
  2374. jQuery.extend({
  2375. dir: function( elem, dir, until ) {
  2376. var matched = [],
  2377. truncate = until !== undefined;
  2378. while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
  2379. if ( elem.nodeType === 1 ) {
  2380. if ( truncate && jQuery( elem ).is( until ) ) {
  2381. break;
  2382. }
  2383. matched.push( elem );
  2384. }
  2385. }
  2386. return matched;
  2387. },
  2388. sibling: function( n, elem ) {
  2389. var matched = [];
  2390. for ( ; n; n = n.nextSibling ) {
  2391. if ( n.nodeType === 1 && n !== elem ) {
  2392. matched.push( n );
  2393. }
  2394. }
  2395. return matched;
  2396. }
  2397. });
  2398. jQuery.fn.extend({
  2399. has: function( target ) {
  2400. var targets = jQuery( target, this ),
  2401. l = targets.length;
  2402. return this.filter(function() {
  2403. var i = 0;
  2404. for ( ; i < l; i++ ) {
  2405. if ( jQuery.contains( this, targets[i] ) ) {
  2406. return true;
  2407. }
  2408. }
  2409. });
  2410. },
  2411. closest: function( selectors, context ) {
  2412. var cur,
  2413. i = 0,
  2414. l = this.length,
  2415. matched = [],
  2416. pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
  2417. jQuery( selectors, context || this.context ) :
  2418. 0;
  2419. for ( ; i < l; i++ ) {
  2420. for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
  2421. // Always skip document fragments
  2422. if ( cur.nodeType < 11 && (pos ?
  2423. pos.index(cur) > -1 :
  2424. // Don't pass non-elements to Sizzle
  2425. cur.nodeType === 1 &&
  2426. jQuery.find.matchesSelector(cur, selectors)) ) {
  2427. matched.push( cur );
  2428. break;
  2429. }
  2430. }
  2431. }
  2432. return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
  2433. },
  2434. // Determine the position of an element within
  2435. // the matched set of elements
  2436. index: function( elem ) {
  2437. // No argument, return index in parent
  2438. if ( !elem ) {
  2439. return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
  2440. }
  2441. // index in selector
  2442. if ( typeof elem === "string" ) {
  2443. return indexOf.call( jQuery( elem ), this[ 0 ] );
  2444. }
  2445. // Locate the position of the desired element
  2446. return indexOf.call( this,
  2447. // If it receives a jQuery object, the first element is used
  2448. elem.jquery ? elem[ 0 ] : elem
  2449. );
  2450. },
  2451. add: function( selector, context ) {
  2452. return this.pushStack(
  2453. jQuery.unique(
  2454. jQuery.merge( this.get(), jQuery( selector, context ) )
  2455. )
  2456. );
  2457. },
  2458. addBack: function( selector ) {
  2459. return this.add( selector == null ?
  2460. this.prevObject : this.prevObject.filter(selector)
  2461. );
  2462. }
  2463. });
  2464. function sibling( cur, dir ) {
  2465. while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
  2466. return cur;
  2467. }
  2468. jQuery.each({
  2469. parent: function( elem ) {
  2470. var parent = elem.parentNode;
  2471. return parent && parent.nodeType !== 11 ? parent : null;
  2472. },
  2473. parents: function( elem ) {
  2474. return jQuery.dir( elem, "parentNode" );
  2475. },
  2476. parentsUntil: function( elem, i, until ) {
  2477. return jQuery.dir( elem, "parentNode", until );
  2478. },
  2479. next: function( elem ) {
  2480. return sibling( elem, "nextSibling" );
  2481. },
  2482. prev: function( elem ) {
  2483. return sibling( elem, "previousSibling" );
  2484. },
  2485. nextAll: function( elem ) {
  2486. return jQuery.dir( elem, "nextSibling" );
  2487. },
  2488. prevAll: function( elem ) {
  2489. return jQuery.dir( elem, "previousSibling" );
  2490. },
  2491. nextUntil: function( elem, i, until ) {
  2492. return jQuery.dir( elem, "nextSibling", until );
  2493. },
  2494. prevUntil: function( elem, i, until ) {
  2495. return jQuery.dir( elem, "previousSibling", until );
  2496. },
  2497. siblings: function( elem ) {
  2498. return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
  2499. },
  2500. children: function( elem ) {
  2501. return jQuery.sibling( elem.firstChild );
  2502. },
  2503. contents: function( elem ) {
  2504. return elem.contentDocument || jQuery.merge( [], elem.childNodes );
  2505. }
  2506. }, function( name, fn ) {
  2507. jQuery.fn[ name ] = function( until, selector ) {
  2508. var matched = jQuery.map( this, fn, until );
  2509. if ( name.slice( -5 ) !== "Until" ) {
  2510. selector = until;
  2511. }
  2512. if ( selector && typeof selector === "string" ) {
  2513. matched = jQuery.filter( selector, matched );
  2514. }
  2515. if ( this.length > 1 ) {
  2516. // Remove duplicates
  2517. if ( !guaranteedUnique[ name ] ) {
  2518. jQuery.unique( matched );
  2519. }
  2520. // Reverse order for parents* and prev-derivatives
  2521. if ( rparentsprev.test( name ) ) {
  2522. matched.reverse();
  2523. }
  2524. }
  2525. return this.pushStack( matched );
  2526. };
  2527. });
  2528. var rnotwhite = (/\S+/g);
  2529. // String to Object options format cache
  2530. var optionsCache = {};
  2531. // Convert String-formatted options into Object-formatted ones and store in cache
  2532. function createOptions( options ) {
  2533. var object = optionsCache[ options ] = {};
  2534. jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
  2535. object[ flag ] = true;
  2536. });
  2537. return object;
  2538. }
  2539. /*
  2540. * Create a callback list using the following parameters:
  2541. *
  2542. * options: an optional list of space-separated options that will change how
  2543. * the callback list behaves or a more traditional option object
  2544. *
  2545. * By default a callback list will act like an event callback list and can be
  2546. * "fired" multiple times.
  2547. *
  2548. * Possible options:
  2549. *
  2550. * once: will ensure the callback list can only be fired once (like a Deferred)
  2551. *
  2552. * memory: will keep track of previous values and will call any callback added
  2553. * after the list has been fired right away with the latest "memorized"
  2554. * values (like a Deferred)
  2555. *
  2556. * unique: will ensure a callback can only be added once (no duplicate in the list)
  2557. *
  2558. * stopOnFalse: interrupt callings when a callback returns false
  2559. *
  2560. */
  2561. jQuery.Callbacks = function( options ) {
  2562. // Convert options from String-formatted to Object-formatted if needed
  2563. // (we check in cache first)
  2564. options = typeof options === "string" ?
  2565. ( optionsCache[ options ] || createOptions( options ) ) :
  2566. jQuery.extend( {}, options );
  2567. var // Last fire value (for non-forgettable lists)
  2568. memory,
  2569. // Flag to know if list was already fired
  2570. fired,
  2571. // Flag to know if list is currently firing
  2572. firing,
  2573. // First callback to fire (used internally by add and fireWith)
  2574. firingStart,
  2575. // End of the loop when firing
  2576. firingLength,
  2577. // Index of currently firing callback (modified by remove if needed)
  2578. firingIndex,
  2579. // Actual callback list
  2580. list = [],
  2581. // Stack of fire calls for repeatable lists
  2582. stack = !options.once && [],
  2583. // Fire callbacks
  2584. fire = function( data ) {
  2585. memory = options.memory && data;
  2586. fired = true;
  2587. firingIndex = firingStart || 0;
  2588. firingStart = 0;
  2589. firingLength = list.length;
  2590. firing = true;
  2591. for ( ; list && firingIndex < firingLength; firingIndex++ ) {
  2592. if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
  2593. memory = false; // To prevent further calls using add
  2594. break;
  2595. }
  2596. }
  2597. firing = false;
  2598. if ( list ) {
  2599. if ( stack ) {
  2600. if ( stack.length ) {
  2601. fire( stack.shift() );
  2602. }
  2603. } else if ( memory ) {
  2604. list = [];
  2605. } else {
  2606. self.disable();
  2607. }
  2608. }
  2609. },
  2610. // Actual Callbacks object
  2611. self = {
  2612. // Add a callback or a collection of callbacks to the list
  2613. add: function() {
  2614. if ( list ) {
  2615. // First, we save the current length
  2616. var start = list.length;
  2617. (function add( args ) {
  2618. jQuery.each( args, function( _, arg ) {
  2619. var type = jQuery.type( arg );
  2620. if ( type === "function" ) {
  2621. if ( !options.unique || !self.has( arg ) ) {
  2622. list.push( arg );
  2623. }
  2624. } else if ( arg && arg.length && type !== "string" ) {
  2625. // Inspect recursively
  2626. add( arg );
  2627. }
  2628. });
  2629. })( arguments );
  2630. // Do we need to add the callbacks to the
  2631. // current firing batch?
  2632. if ( firing ) {
  2633. firingLength = list.length;
  2634. // With memory, if we're not firing then
  2635. // we should call right away
  2636. } else if ( memory ) {
  2637. firingStart = start;
  2638. fire( memory );
  2639. }
  2640. }
  2641. return this;
  2642. },
  2643. // Remove a callback from the list
  2644. remove: function() {
  2645. if ( list ) {
  2646. jQuery.each( arguments, function( _, arg ) {
  2647. var index;
  2648. while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
  2649. list.splice( index, 1 );
  2650. // Handle firing indexes
  2651. if ( firing ) {
  2652. if ( index <= firingLength ) {
  2653. firingLength--;
  2654. }
  2655. if ( index <= firingIndex ) {
  2656. firingIndex--;
  2657. }
  2658. }
  2659. }
  2660. });
  2661. }
  2662. return this;
  2663. },
  2664. // Check if a given callback is in the list.
  2665. // If no argument is given, return whether or not list has callbacks attached.
  2666. has: function( fn ) {
  2667. return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
  2668. },
  2669. // Remove all callbacks from the list
  2670. empty: function() {
  2671. list = [];
  2672. firingLength = 0;
  2673. return this;
  2674. },
  2675. // Have the list do nothing anymore
  2676. disable: function() {
  2677. list = stack = memory = undefined;
  2678. return this;
  2679. },
  2680. // Is it disabled?
  2681. disabled: function() {
  2682. return !list;
  2683. },
  2684. // Lock the list in its current state
  2685. lock: function() {
  2686. stack = undefined;
  2687. if ( !memory ) {
  2688. self.disable();
  2689. }
  2690. return this;
  2691. },
  2692. // Is it locked?
  2693. locked: function() {
  2694. return !stack;
  2695. },
  2696. // Call all callbacks with the given context and arguments
  2697. fireWith: function( context, args ) {
  2698. if ( list && ( !fired || stack ) ) {
  2699. args = args || [];
  2700. args = [ context, args.slice ? args.slice() : args ];
  2701. if ( firing ) {
  2702. stack.push( args );
  2703. } else {
  2704. fire( args );
  2705. }
  2706. }
  2707. return this;
  2708. },
  2709. // Call all the callbacks with the given arguments
  2710. fire: function() {
  2711. self.fireWith( this, arguments );
  2712. return this;
  2713. },
  2714. // To know if the callbacks have already been called at least once
  2715. fired: function() {
  2716. return !!fired;
  2717. }
  2718. };
  2719. return self;
  2720. };
  2721. jQuery.extend({
  2722. Deferred: function( func ) {
  2723. var tuples = [
  2724. // action, add listener, listener list, final state
  2725. [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
  2726. [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
  2727. [ "notify", "progress", jQuery.Callbacks("memory") ]
  2728. ],
  2729. state = "pending",
  2730. promise = {
  2731. state: function() {
  2732. return state;
  2733. },
  2734. always: function() {
  2735. deferred.done( arguments ).fail( arguments );
  2736. return this;
  2737. },
  2738. then: function( /* fnDone, fnFail, fnProgress */ ) {
  2739. var fns = arguments;
  2740. return jQuery.Deferred(function( newDefer ) {
  2741. jQuery.each( tuples, function( i, tuple ) {
  2742. var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
  2743. // deferred[ done | fail | progress ] for forwarding actions to newDefer
  2744. deferred[ tuple[1] ](function() {
  2745. var returned = fn && fn.apply( this, arguments );
  2746. if ( returned && jQuery.isFunction( returned.promise ) ) {
  2747. returned.promise()
  2748. .done( newDefer.resolve )
  2749. .fail( newDefer.reject )
  2750. .progress( newDefer.notify );
  2751. } else {
  2752. newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
  2753. }
  2754. });
  2755. });
  2756. fns = null;
  2757. }).promise();
  2758. },
  2759. // Get a promise for this deferred
  2760. // If obj is provided, the promise aspect is added to the object
  2761. promise: function( obj ) {
  2762. return obj != null ? jQuery.extend( obj, promise ) : promise;
  2763. }
  2764. },
  2765. deferred = {};
  2766. // Keep pipe for back-compat
  2767. promise.pipe = promise.then;
  2768. // Add list-specific methods
  2769. jQuery.each( tuples, function( i, tuple ) {
  2770. var list = tuple[ 2 ],
  2771. stateString = tuple[ 3 ];
  2772. // promise[ done | fail | progress ] = list.add
  2773. promise[ tuple[1] ] = list.add;
  2774. // Handle state
  2775. if ( stateString ) {
  2776. list.add(function() {
  2777. // state = [ resolved | rejected ]
  2778. state = stateString;
  2779. // [ reject_list | resolve_list ].disable; progress_list.lock
  2780. }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
  2781. }
  2782. // deferred[ resolve | reject | notify ]
  2783. deferred[ tuple[0] ] = function() {
  2784. deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
  2785. return this;
  2786. };
  2787. deferred[ tuple[0] + "With" ] = list.fireWith;
  2788. });
  2789. // Make the deferred a promise
  2790. promise.promise( deferred );
  2791. // Call given func if any
  2792. if ( func ) {
  2793. func.call( deferred, deferred );
  2794. }
  2795. // All done!
  2796. return deferred;
  2797. },
  2798. // Deferred helper
  2799. when: function( subordinate /* , ..., subordinateN */ ) {
  2800. var i = 0,
  2801. resolveValues = slice.call( arguments ),
  2802. length = resolveValues.length,
  2803. // the count of uncompleted subordinates
  2804. remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
  2805. // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
  2806. deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
  2807. // Update function for both resolve and progress values
  2808. updateFunc = function( i, contexts, values ) {
  2809. return function( value ) {
  2810. contexts[ i ] = this;
  2811. values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
  2812. if ( values === progressValues ) {
  2813. deferred.notifyWith( contexts, values );
  2814. } else if ( !( --remaining ) ) {
  2815. deferred.resolveWith( contexts, values );
  2816. }
  2817. };
  2818. },
  2819. progressValues, progressContexts, resolveContexts;
  2820. // add listeners to Deferred subordinates; treat others as resolved
  2821. if ( length > 1 ) {
  2822. progressValues = new Array( length );
  2823. progressContexts = new Array( length );
  2824. resolveContexts = new Array( length );
  2825. for ( ; i < length; i++ ) {
  2826. if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
  2827. resolveValues[ i ].promise()
  2828. .done( updateFunc( i, resolveContexts, resolveValues ) )
  2829. .fail( deferred.reject )
  2830. .progress( updateFunc( i, progressContexts, progressValues ) );
  2831. } else {
  2832. --remaining;
  2833. }
  2834. }
  2835. }
  2836. // if we're not waiting on anything, resolve the master
  2837. if ( !remaining ) {
  2838. deferred.resolveWith( resolveContexts, resolveValues );
  2839. }
  2840. return deferred.promise();
  2841. }
  2842. });
  2843. // The deferred used on DOM ready
  2844. var readyList;
  2845. jQuery.fn.ready = function( fn ) {
  2846. // Add the callback
  2847. jQuery.ready.promise().done( fn );
  2848. return this;
  2849. };
  2850. jQuery.extend({
  2851. // Is the DOM ready to be used? Set to true once it occurs.
  2852. isReady: false,
  2853. // A counter to track how many items to wait for before
  2854. // the ready event fires. See #6781
  2855. readyWait: 1,
  2856. // Hold (or release) the ready event
  2857. holdReady: function( hold ) {
  2858. if ( hold ) {
  2859. jQuery.readyWait++;
  2860. } else {
  2861. jQuery.ready( true );
  2862. }
  2863. },
  2864. // Handle when the DOM is ready
  2865. ready: function( wait ) {
  2866. // Abort if there are pending holds or we're already ready
  2867. if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
  2868. return;
  2869. }
  2870. // Remember that the DOM is ready
  2871. jQuery.isReady = true;
  2872. // If a normal DOM Ready event fired, decrement, and wait if need be
  2873. if ( wait !== true && --jQuery.readyWait > 0 ) {
  2874. return;
  2875. }
  2876. // If there are functions bound, to execute
  2877. readyList.resolveWith( document, [ jQuery ] );
  2878. // Trigger any bound ready events
  2879. if ( jQuery.fn.triggerHandler ) {
  2880. jQuery( document ).triggerHandler( "ready" );
  2881. jQuery( document ).off( "ready" );
  2882. }
  2883. }
  2884. });
  2885. /**
  2886. * The ready event handler and self cleanup method
  2887. */
  2888. function completed() {
  2889. document.removeEventListener( "DOMContentLoaded", completed, false );
  2890. window.removeEventListener( "load", completed, false );
  2891. jQuery.ready();
  2892. }
  2893. jQuery.ready.promise = function( obj ) {
  2894. if ( !readyList ) {
  2895. readyList = jQuery.Deferred();
  2896. // Catch cases where $(document).ready() is called after the browser event has already occurred.
  2897. // we once tried to use readyState "interactive" here, but it caused issues like the one
  2898. // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
  2899. if ( document.readyState === "complete" ) {
  2900. // Handle it asynchronously to allow scripts the opportunity to delay ready
  2901. setTimeout( jQuery.ready );
  2902. } else {
  2903. // Use the handy event callback
  2904. document.addEventListener( "DOMContentLoaded", completed, false );
  2905. // A fallback to window.onload, that will always work
  2906. window.addEventListener( "load", completed, false );
  2907. }
  2908. }
  2909. return readyList.promise( obj );
  2910. };
  2911. // Kick off the DOM ready check even if the user does not
  2912. jQuery.ready.promise();
  2913. // Multifunctional method to get and set values of a collection
  2914. // The value/s can optionally be executed if it's a function
  2915. var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
  2916. var i = 0,
  2917. len = elems.length,
  2918. bulk = key == null;
  2919. // Sets many values
  2920. if ( jQuery.type( key ) === "object" ) {
  2921. chainable = true;
  2922. for ( i in key ) {
  2923. jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
  2924. }
  2925. // Sets one value
  2926. } else if ( value !== undefined ) {
  2927. chainable = true;
  2928. if ( !jQuery.isFunction( value ) ) {
  2929. raw = true;
  2930. }
  2931. if ( bulk ) {
  2932. // Bulk operations run against the entire set
  2933. if ( raw ) {
  2934. fn.call( elems, value );
  2935. fn = null;
  2936. // ...except when executing function values
  2937. } else {
  2938. bulk = fn;
  2939. fn = function( elem, key, value ) {
  2940. return bulk.call( jQuery( elem ), value );
  2941. };
  2942. }
  2943. }
  2944. if ( fn ) {
  2945. for ( ; i < len; i++ ) {
  2946. fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
  2947. }
  2948. }
  2949. }
  2950. return chainable ?
  2951. elems :
  2952. // Gets
  2953. bulk ?
  2954. fn.call( elems ) :
  2955. len ? fn( elems[0], key ) : emptyGet;
  2956. };
  2957. /**
  2958. * Determines whether an object can have data
  2959. */
  2960. jQuery.acceptData = function( owner ) {
  2961. // Accepts only:
  2962. // - Node
  2963. // - Node.ELEMENT_NODE
  2964. // - Node.DOCUMENT_NODE
  2965. // - Object
  2966. // - Any
  2967. /* jshint -W018 */
  2968. return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
  2969. };
  2970. function Data() {
  2971. // Support: Android < 4,
  2972. // Old WebKit does not have Object.preventExtensions/freeze method,
  2973. // return new empty object instead with no [[set]] accessor
  2974. Object.defineProperty( this.cache = {}, 0, {
  2975. get: function() {
  2976. return {};
  2977. }
  2978. });
  2979. this.expando = jQuery.expando + Math.random();
  2980. }
  2981. Data.uid = 1;
  2982. Data.accepts = jQuery.acceptData;
  2983. Data.prototype = {
  2984. key: function( owner ) {
  2985. // We can accept data for non-element nodes in modern browsers,
  2986. // but we should not, see #8335.
  2987. // Always return the key for a frozen object.
  2988. if ( !Data.accepts( owner ) ) {
  2989. return 0;
  2990. }
  2991. var descriptor = {},
  2992. // Check if the owner object already has a cache key
  2993. unlock = owner[ this.expando ];
  2994. // If not, create one
  2995. if ( !unlock ) {
  2996. unlock = Data.uid++;
  2997. // Secure it in a non-enumerable, non-writable property
  2998. try {
  2999. descriptor[ this.expando ] = { value: unlock };
  3000. Object.defineProperties( owner, descriptor );
  3001. // Support: Android < 4
  3002. // Fallback to a less secure definition
  3003. } catch ( e ) {
  3004. descriptor[ this.expando ] = unlock;
  3005. jQuery.extend( owner, descriptor );
  3006. }
  3007. }
  3008. // Ensure the cache object
  3009. if ( !this.cache[ unlock ] ) {
  3010. this.cache[ unlock ] = {};
  3011. }
  3012. return unlock;
  3013. },
  3014. set: function( owner, data, value ) {
  3015. var prop,
  3016. // There may be an unlock assigned to this node,
  3017. // if there is no entry for this "owner", create one inline
  3018. // and set the unlock as though an owner entry had always existed
  3019. unlock = this.key( owner ),
  3020. cache = this.cache[ unlock ];
  3021. // Handle: [ owner, key, value ] args
  3022. if ( typeof data === "string" ) {
  3023. cache[ data ] = value;
  3024. // Handle: [ owner, { properties } ] args
  3025. } else {
  3026. // Fresh assignments by object are shallow copied
  3027. if ( jQuery.isEmptyObject( cache ) ) {
  3028. jQuery.extend( this.cache[ unlock ], data );
  3029. // Otherwise, copy the properties one-by-one to the cache object
  3030. } else {
  3031. for ( prop in data ) {
  3032. cache[ prop ] = data[ prop ];
  3033. }
  3034. }
  3035. }
  3036. return cache;
  3037. },
  3038. get: function( owner, key ) {
  3039. // Either a valid cache is found, or will be created.
  3040. // New caches will be created and the unlock returned,
  3041. // allowing direct access to the newly created
  3042. // empty data object. A valid owner object must be provided.
  3043. var cache = this.cache[ this.key( owner ) ];
  3044. return key === undefined ?
  3045. cache : cache[ key ];
  3046. },
  3047. access: function( owner, key, value ) {
  3048. var stored;
  3049. // In cases where either:
  3050. //
  3051. // 1. No key was specified
  3052. // 2. A string key was specified, but no value provided
  3053. //
  3054. // Take the "read" path and allow the get method to determine
  3055. // which value to return, respectively either:
  3056. //
  3057. // 1. The entire cache object
  3058. // 2. The data stored at the key
  3059. //
  3060. if ( key === undefined ||
  3061. ((key && typeof key === "string") && value === undefined) ) {
  3062. stored = this.get( owner, key );
  3063. return stored !== undefined ?
  3064. stored : this.get( owner, jQuery.camelCase(key) );
  3065. }
  3066. // [*]When the key is not a string, or both a key and value
  3067. // are specified, set or extend (existing objects) with either:
  3068. //
  3069. // 1. An object of properties
  3070. // 2. A key and value
  3071. //
  3072. this.set( owner, key, value );
  3073. // Since the "set" path can have two possible entry points
  3074. // return the expected data based on which path was taken[*]
  3075. return value !== undefined ? value : key;
  3076. },
  3077. remove: function( owner, key ) {
  3078. var i, name, camel,
  3079. unlock = this.key( owner ),
  3080. cache = this.cache[ unlock ];
  3081. if ( key === undefined ) {
  3082. this.cache[ unlock ] = {};
  3083. } else {
  3084. // Support array or space separated string of keys
  3085. if ( jQuery.isArray( key ) ) {
  3086. // If "name" is an array of keys...
  3087. // When data is initially created, via ("key", "val") signature,
  3088. // keys will be converted to camelCase.
  3089. // Since there is no way to tell _how_ a key was added, remove
  3090. // both plain key and camelCase key. #12786
  3091. // This will only penalize the array argument path.
  3092. name = key.concat( key.map( jQuery.camelCase ) );
  3093. } else {
  3094. camel = jQuery.camelCase( key );
  3095. // Try the string as a key before any manipulation
  3096. if ( key in cache ) {
  3097. name = [ key, camel ];
  3098. } else {
  3099. // If a key with the spaces exists, use it.
  3100. // Otherwise, create an array by matching non-whitespace
  3101. name = camel;
  3102. name = name in cache ?
  3103. [ name ] : ( name.match( rnotwhite ) || [] );
  3104. }
  3105. }
  3106. i = name.length;
  3107. while ( i-- ) {
  3108. delete cache[ name[ i ] ];
  3109. }
  3110. }
  3111. },
  3112. hasData: function( owner ) {
  3113. return !jQuery.isEmptyObject(
  3114. this.cache[ owner[ this.expando ] ] || {}
  3115. );
  3116. },
  3117. discard: function( owner ) {
  3118. if ( owner[ this.expando ] ) {
  3119. delete this.cache[ owner[ this.expando ] ];
  3120. }
  3121. }
  3122. };
  3123. var data_priv = new Data();
  3124. var data_user = new Data();
  3125. /*
  3126. Implementation Summary
  3127. 1. Enforce API surface and semantic compatibility with 1.9.x branch
  3128. 2. Improve the module's maintainability by reducing the storage
  3129. paths to a single mechanism.
  3130. 3. Use the same single mechanism to support "private" and "user" data.
  3131. 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
  3132. 5. Avoid exposing implementation details on user objects (eg. expando properties)
  3133. 6. Provide a clear path for implementation upgrade to WeakMap in 2014
  3134. */
  3135. var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
  3136. rmultiDash = /([A-Z])/g;
  3137. function dataAttr( elem, key, data ) {
  3138. var name;
  3139. // If nothing was found internally, try to fetch any
  3140. // data from the HTML5 data-* attribute
  3141. if ( data === undefined && elem.nodeType === 1 ) {
  3142. name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
  3143. data = elem.getAttribute( name );
  3144. if ( typeof data === "string" ) {
  3145. try {
  3146. data = data === "true" ? true :
  3147. data === "false" ? false :
  3148. data === "null" ? null :
  3149. // Only convert to a number if it doesn't change the string
  3150. +data + "" === data ? +data :
  3151. rbrace.test( data ) ? jQuery.parseJSON( data ) :
  3152. data;
  3153. } catch( e ) {}
  3154. // Make sure we set the data so it isn't changed later
  3155. data_user.set( elem, key, data );
  3156. } else {
  3157. data = undefined;
  3158. }
  3159. }
  3160. return data;
  3161. }
  3162. jQuery.extend({
  3163. hasData: function( elem ) {
  3164. return data_user.hasData( elem ) || data_priv.hasData( elem );
  3165. },
  3166. data: function( elem, name, data ) {
  3167. return data_user.access( elem, name, data );
  3168. },
  3169. removeData: function( elem, name ) {
  3170. data_user.remove( elem, name );
  3171. },
  3172. // TODO: Now that all calls to _data and _removeData have been replaced
  3173. // with direct calls to data_priv methods, these can be deprecated.
  3174. _data: function( elem, name, data ) {
  3175. return data_priv.access( elem, name, data );
  3176. },
  3177. _removeData: function( elem, name ) {
  3178. data_priv.remove( elem, name );
  3179. }
  3180. });
  3181. jQuery.fn.extend({
  3182. data: function( key, value ) {
  3183. var i, name, data,
  3184. elem = this[ 0 ],
  3185. attrs = elem && elem.attributes;
  3186. // Gets all values
  3187. if ( key === undefined ) {
  3188. if ( this.length ) {
  3189. data = data_user.get( elem );
  3190. if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
  3191. i = attrs.length;
  3192. while ( i-- ) {
  3193. // Support: IE11+
  3194. // The attrs elements can be null (#14894)
  3195. if ( attrs[ i ] ) {
  3196. name = attrs[ i ].name;
  3197. if ( name.indexOf( "data-" ) === 0 ) {
  3198. name = jQuery.camelCase( name.slice(5) );
  3199. dataAttr( elem, name, data[ name ] );
  3200. }
  3201. }
  3202. }
  3203. data_priv.set( elem, "hasDataAttrs", true );
  3204. }
  3205. }
  3206. return data;
  3207. }
  3208. // Sets multiple values
  3209. if ( typeof key === "object" ) {
  3210. return this.each(function() {
  3211. data_user.set( this, key );
  3212. });
  3213. }
  3214. return access( this, function( value ) {
  3215. var data,
  3216. camelKey = jQuery.camelCase( key );
  3217. // The calling jQuery object (element matches) is not empty
  3218. // (and therefore has an element appears at this[ 0 ]) and the
  3219. // `value` parameter was not undefined. An empty jQuery object
  3220. // will result in `undefined` for elem = this[ 0 ] which will
  3221. // throw an exception if an attempt to read a data cache is made.
  3222. if ( elem && value === undefined ) {
  3223. // Attempt to get data from the cache
  3224. // with the key as-is
  3225. data = data_user.get( elem, key );
  3226. if ( data !== undefined ) {
  3227. return data;
  3228. }
  3229. // Attempt to get data from the cache
  3230. // with the key camelized
  3231. data = data_user.get( elem, camelKey );
  3232. if ( data !== undefined ) {
  3233. return data;
  3234. }
  3235. // Attempt to "discover" the data in
  3236. // HTML5 custom data-* attrs
  3237. data = dataAttr( elem, camelKey, undefined );
  3238. if ( data !== undefined ) {
  3239. return data;
  3240. }
  3241. // We tried really hard, but the data doesn't exist.
  3242. return;
  3243. }
  3244. // Set the data...
  3245. this.each(function() {
  3246. // First, attempt to store a copy or reference of any
  3247. // data that might've been store with a camelCased key.
  3248. var data = data_user.get( this, camelKey );
  3249. // For HTML5 data-* attribute interop, we have to
  3250. // store property names with dashes in a camelCase form.
  3251. // This might not apply to all properties...*
  3252. data_user.set( this, camelKey, value );
  3253. // *... In the case of properties that might _actually_
  3254. // have dashes, we need to also store a copy of that
  3255. // unchanged property.
  3256. if ( key.indexOf("-") !== -1 && data !== undefined ) {
  3257. data_user.set( this, key, value );
  3258. }
  3259. });
  3260. }, null, value, arguments.length > 1, null, true );
  3261. },
  3262. removeData: function( key ) {
  3263. return this.each(function() {
  3264. data_user.remove( this, key );
  3265. });
  3266. }
  3267. });
  3268. jQuery.extend({
  3269. queue: function( elem, type, data ) {
  3270. var queue;
  3271. if ( elem ) {
  3272. type = ( type || "fx" ) + "queue";
  3273. queue = data_priv.get( elem, type );
  3274. // Speed up dequeue by getting out quickly if this is just a lookup
  3275. if ( data ) {
  3276. if ( !queue || jQuery.isArray( data ) ) {
  3277. queue = data_priv.access( elem, type, jQuery.makeArray(data) );
  3278. } else {
  3279. queue.push( data );
  3280. }
  3281. }
  3282. return queue || [];
  3283. }
  3284. },
  3285. dequeue: function( elem, type ) {
  3286. type = type || "fx";
  3287. var queue = jQuery.queue( elem, type ),
  3288. startLength = queue.length,
  3289. fn = queue.shift(),
  3290. hooks = jQuery._queueHooks( elem, type ),
  3291. next = function() {
  3292. jQuery.dequeue( elem, type );
  3293. };
  3294. // If the fx queue is dequeued, always remove the progress sentinel
  3295. if ( fn === "inprogress" ) {
  3296. fn = queue.shift();
  3297. startLength--;
  3298. }
  3299. if ( fn ) {
  3300. // Add a progress sentinel to prevent the fx queue from being
  3301. // automatically dequeued
  3302. if ( type === "fx" ) {
  3303. queue.unshift( "inprogress" );
  3304. }
  3305. // clear up the last queue stop function
  3306. delete hooks.stop;
  3307. fn.call( elem, next, hooks );
  3308. }
  3309. if ( !startLength && hooks ) {
  3310. hooks.empty.fire();
  3311. }
  3312. },
  3313. // not intended for public consumption - generates a queueHooks object, or returns the current one
  3314. _queueHooks: function( elem, type ) {
  3315. var key = type + "queueHooks";
  3316. return data_priv.get( elem, key ) || data_priv.access( elem, key, {
  3317. empty: jQuery.Callbacks("once memory").add(function() {
  3318. data_priv.remove( elem, [ type + "queue", key ] );
  3319. })
  3320. });
  3321. }
  3322. });
  3323. jQuery.fn.extend({
  3324. queue: function( type, data ) {
  3325. var setter = 2;
  3326. if ( typeof type !== "string" ) {
  3327. data = type;
  3328. type = "fx";
  3329. setter--;
  3330. }
  3331. if ( arguments.length < setter ) {
  3332. return jQuery.queue( this[0], type );
  3333. }
  3334. return data === undefined ?
  3335. this :
  3336. this.each(function() {
  3337. var queue = jQuery.queue( this, type, data );
  3338. // ensure a hooks for this queue
  3339. jQuery._queueHooks( this, type );
  3340. if ( type === "fx" && queue[0] !== "inprogress" ) {
  3341. jQuery.dequeue( this, type );
  3342. }
  3343. });
  3344. },
  3345. dequeue: function( type ) {
  3346. return this.each(function() {
  3347. jQuery.dequeue( this, type );
  3348. });
  3349. },
  3350. clearQueue: function( type ) {
  3351. return this.queue( type || "fx", [] );
  3352. },
  3353. // Get a promise resolved when queues of a certain type
  3354. // are emptied (fx is the type by default)
  3355. promise: function( type, obj ) {
  3356. var tmp,
  3357. count = 1,
  3358. defer = jQuery.Deferred(),
  3359. elements = this,
  3360. i = this.length,
  3361. resolve = function() {
  3362. if ( !( --count ) ) {
  3363. defer.resolveWith( elements, [ elements ] );
  3364. }
  3365. };
  3366. if ( typeof type !== "string" ) {
  3367. obj = type;
  3368. type = undefined;
  3369. }
  3370. type = type || "fx";
  3371. while ( i-- ) {
  3372. tmp = data_priv.get( elements[ i ], type + "queueHooks" );
  3373. if ( tmp && tmp.empty ) {
  3374. count++;
  3375. tmp.empty.add( resolve );
  3376. }
  3377. }
  3378. resolve();
  3379. return defer.promise( obj );
  3380. }
  3381. });
  3382. var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
  3383. var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
  3384. var isHidden = function( elem, el ) {
  3385. // isHidden might be called from jQuery#filter function;
  3386. // in that case, element will be second argument
  3387. elem = el || elem;
  3388. return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
  3389. };
  3390. var rcheckableType = (/^(?:checkbox|radio)$/i);
  3391. (function() {
  3392. var fragment = document.createDocumentFragment(),
  3393. div = fragment.appendChild( document.createElement( "div" ) ),
  3394. input = document.createElement( "input" );
  3395. // #11217 - WebKit loses check when the name is after the checked attribute
  3396. // Support: Windows Web Apps (WWA)
  3397. // `name` and `type` need .setAttribute for WWA
  3398. input.setAttribute( "type", "radio" );
  3399. input.setAttribute( "checked", "checked" );
  3400. input.setAttribute( "name", "t" );
  3401. div.appendChild( input );
  3402. // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
  3403. // old WebKit doesn't clone checked state correctly in fragments
  3404. support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
  3405. // Make sure textarea (and checkbox) defaultValue is properly cloned
  3406. // Support: IE9-IE11+
  3407. div.innerHTML = "<textarea>x</textarea>";
  3408. support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
  3409. })();
  3410. var strundefined = typeof undefined;
  3411. support.focusinBubbles = "onfocusin" in window;
  3412. var
  3413. rkeyEvent = /^key/,
  3414. rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
  3415. rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
  3416. rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
  3417. function returnTrue() {
  3418. return true;
  3419. }
  3420. function returnFalse() {
  3421. return false;
  3422. }
  3423. function safeActiveElement() {
  3424. try {
  3425. return document.activeElement;
  3426. } catch ( err ) { }
  3427. }
  3428. /*
  3429. * Helper functions for managing events -- not part of the public interface.
  3430. * Props to Dean Edwards' addEvent library for many of the ideas.
  3431. */
  3432. jQuery.event = {
  3433. global: {},
  3434. add: function( elem, types, handler, data, selector ) {
  3435. var handleObjIn, eventHandle, tmp,
  3436. events, t, handleObj,
  3437. special, handlers, type, namespaces, origType,
  3438. elemData = data_priv.get( elem );
  3439. // Don't attach events to noData or text/comment nodes (but allow plain objects)
  3440. if ( !elemData ) {
  3441. return;
  3442. }
  3443. // Caller can pass in an object of custom data in lieu of the handler
  3444. if ( handler.handler ) {
  3445. handleObjIn = handler;
  3446. handler = handleObjIn.handler;
  3447. selector = handleObjIn.selector;
  3448. }
  3449. // Make sure that the handler has a unique ID, used to find/remove it later
  3450. if ( !handler.guid ) {
  3451. handler.guid = jQuery.guid++;
  3452. }
  3453. // Init the element's event structure and main handler, if this is the first
  3454. if ( !(events = elemData.events) ) {
  3455. events = elemData.events = {};
  3456. }
  3457. if ( !(eventHandle = elemData.handle) ) {
  3458. eventHandle = elemData.handle = function( e ) {
  3459. // Discard the second event of a jQuery.event.trigger() and
  3460. // when an event is called after a page has unloaded
  3461. return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?
  3462. jQuery.event.dispatch.apply( elem, arguments ) : undefined;
  3463. };
  3464. }
  3465. // Handle multiple events separated by a space
  3466. types = ( types || "" ).match( rnotwhite ) || [ "" ];
  3467. t = types.length;
  3468. while ( t-- ) {
  3469. tmp = rtypenamespace.exec( types[t] ) || [];
  3470. type = origType = tmp[1];
  3471. namespaces = ( tmp[2] || "" ).split( "." ).sort();
  3472. // There *must* be a type, no attaching namespace-only handlers
  3473. if ( !type ) {
  3474. continue;
  3475. }
  3476. // If event changes its type, use the special event handlers for the changed type
  3477. special = jQuery.event.special[ type ] || {};
  3478. // If selector defined, determine special event api type, otherwise given type
  3479. type = ( selector ? special.delegateType : special.bindType ) || type;
  3480. // Update special based on newly reset type
  3481. special = jQuery.event.special[ type ] || {};
  3482. // handleObj is passed to all event handlers
  3483. handleObj = jQuery.extend({
  3484. type: type,
  3485. origType: origType,
  3486. data: data,
  3487. handler: handler,
  3488. guid: handler.guid,
  3489. selector: selector,
  3490. needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
  3491. namespace: namespaces.join(".")
  3492. }, handleObjIn );
  3493. // Init the event handler queue if we're the first
  3494. if ( !(handlers = events[ type ]) ) {
  3495. handlers = events[ type ] = [];
  3496. handlers.delegateCount = 0;
  3497. // Only use addEventListener if the special events handler returns false
  3498. if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
  3499. if ( elem.addEventListener ) {
  3500. elem.addEventListener( type, eventHandle, false );
  3501. }
  3502. }
  3503. }
  3504. if ( special.add ) {
  3505. special.add.call( elem, handleObj );
  3506. if ( !handleObj.handler.guid ) {
  3507. handleObj.handler.guid = handler.guid;
  3508. }
  3509. }
  3510. // Add to the element's handler list, delegates in front
  3511. if ( selector ) {
  3512. handlers.splice( handlers.delegateCount++, 0, handleObj );
  3513. } else {
  3514. handlers.push( handleObj );
  3515. }
  3516. // Keep track of which events have ever been used, for event optimization
  3517. jQuery.event.global[ type ] = true;
  3518. }
  3519. },
  3520. // Detach an event or set of events from an element
  3521. remove: function( elem, types, handler, selector, mappedTypes ) {
  3522. var j, origCount, tmp,
  3523. events, t, handleObj,
  3524. special, handlers, type, namespaces, origType,
  3525. elemData = data_priv.hasData( elem ) && data_priv.get( elem );
  3526. if ( !elemData || !(events = elemData.events) ) {
  3527. return;
  3528. }
  3529. // Once for each type.namespace in types; type may be omitted
  3530. types = ( types || "" ).match( rnotwhite ) || [ "" ];
  3531. t = types.length;
  3532. while ( t-- ) {
  3533. tmp = rtypenamespace.exec( types[t] ) || [];
  3534. type = origType = tmp[1];
  3535. namespaces = ( tmp[2] || "" ).split( "." ).sort();
  3536. // Unbind all events (on this namespace, if provided) for the element
  3537. if ( !type ) {
  3538. for ( type in events ) {
  3539. jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
  3540. }
  3541. continue;
  3542. }
  3543. special = jQuery.event.special[ type ] || {};
  3544. type = ( selector ? special.delegateType : special.bindType ) || type;
  3545. handlers = events[ type ] || [];
  3546. tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
  3547. // Remove matching events
  3548. origCount = j = handlers.length;
  3549. while ( j-- ) {
  3550. handleObj = handlers[ j ];
  3551. if ( ( mappedTypes || origType === handleObj.origType ) &&
  3552. ( !handler || handler.guid === handleObj.guid ) &&
  3553. ( !tmp || tmp.test( handleObj.namespace ) ) &&
  3554. ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
  3555. handlers.splice( j, 1 );
  3556. if ( handleObj.selector ) {
  3557. handlers.delegateCount--;
  3558. }
  3559. if ( special.remove ) {
  3560. special.remove.call( elem, handleObj );
  3561. }
  3562. }
  3563. }
  3564. // Remove generic event handler if we removed something and no more handlers exist
  3565. // (avoids potential for endless recursion during removal of special event handlers)
  3566. if ( origCount && !handlers.length ) {
  3567. if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
  3568. jQuery.removeEvent( elem, type, elemData.handle );
  3569. }
  3570. delete events[ type ];
  3571. }
  3572. }
  3573. // Remove the expando if it's no longer used
  3574. if ( jQuery.isEmptyObject( events ) ) {
  3575. delete elemData.handle;
  3576. data_priv.remove( elem, "events" );
  3577. }
  3578. },
  3579. trigger: function( event, data, elem, onlyHandlers ) {
  3580. var i, cur, tmp, bubbleType, ontype, handle, special,
  3581. eventPath = [ elem || document ],
  3582. type = hasOwn.call( event, "type" ) ? event.type : event,
  3583. namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
  3584. cur = tmp = elem = elem || document;
  3585. // Don't do events on text and comment nodes
  3586. if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
  3587. return;
  3588. }
  3589. // focus/blur morphs to focusin/out; ensure we're not firing them right now
  3590. if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
  3591. return;
  3592. }
  3593. if ( type.indexOf(".") >= 0 ) {
  3594. // Namespaced trigger; create a regexp to match event type in handle()
  3595. namespaces = type.split(".");
  3596. type = namespaces.shift();
  3597. namespaces.sort();
  3598. }
  3599. ontype = type.indexOf(":") < 0 && "on" + type;
  3600. // Caller can pass in a jQuery.Event object, Object, or just an event type string
  3601. event = event[ jQuery.expando ] ?
  3602. event :
  3603. new jQuery.Event( type, typeof event === "object" && event );
  3604. // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
  3605. event.isTrigger = onlyHandlers ? 2 : 3;
  3606. event.namespace = namespaces.join(".");
  3607. event.namespace_re = event.namespace ?
  3608. new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
  3609. null;
  3610. // Clean up the event in case it is being reused
  3611. event.result = undefined;
  3612. if ( !event.target ) {
  3613. event.target = elem;
  3614. }
  3615. // Clone any incoming data and prepend the event, creating the handler arg list
  3616. data = data == null ?
  3617. [ event ] :
  3618. jQuery.makeArray( data, [ event ] );
  3619. // Allow special events to draw outside the lines
  3620. special = jQuery.event.special[ type ] || {};
  3621. if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
  3622. return;
  3623. }
  3624. // Determine event propagation path in advance, per W3C events spec (#9951)
  3625. // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
  3626. if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
  3627. bubbleType = special.delegateType || type;
  3628. if ( !rfocusMorph.test( bubbleType + type ) ) {
  3629. cur = cur.parentNode;
  3630. }
  3631. for ( ; cur; cur = cur.parentNode ) {
  3632. eventPath.push( cur );
  3633. tmp = cur;
  3634. }
  3635. // Only add window if we got to document (e.g., not plain obj or detached DOM)
  3636. if ( tmp === (elem.ownerDocument || document) ) {
  3637. eventPath.push( tmp.defaultView || tmp.parentWindow || window );
  3638. }
  3639. }
  3640. // Fire handlers on the event path
  3641. i = 0;
  3642. while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
  3643. event.type = i > 1 ?
  3644. bubbleType :
  3645. special.bindType || type;
  3646. // jQuery handler
  3647. handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
  3648. if ( handle ) {
  3649. handle.apply( cur, data );
  3650. }
  3651. // Native handler
  3652. handle = ontype && cur[ ontype ];
  3653. if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
  3654. event.result = handle.apply( cur, data );
  3655. if ( event.result === false ) {
  3656. event.preventDefault();
  3657. }
  3658. }
  3659. }
  3660. event.type = type;
  3661. // If nobody prevented the default action, do it now
  3662. if ( !onlyHandlers && !event.isDefaultPrevented() ) {
  3663. if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
  3664. jQuery.acceptData( elem ) ) {
  3665. // Call a native DOM method on the target with the same name name as the event.
  3666. // Don't do default actions on window, that's where global variables be (#6170)
  3667. if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
  3668. // Don't re-trigger an onFOO event when we call its FOO() method
  3669. tmp = elem[ ontype ];
  3670. if ( tmp ) {
  3671. elem[ ontype ] = null;
  3672. }
  3673. // Prevent re-triggering of the same event, since we already bubbled it above
  3674. jQuery.event.triggered = type;
  3675. elem[ type ]();
  3676. jQuery.event.triggered = undefined;
  3677. if ( tmp ) {
  3678. elem[ ontype ] = tmp;
  3679. }
  3680. }
  3681. }
  3682. }
  3683. return event.result;
  3684. },
  3685. dispatch: function( event ) {
  3686. // Make a writable jQuery.Event from the native event object
  3687. event = jQuery.event.fix( event );
  3688. var i, j, ret, matched, handleObj,
  3689. handlerQueue = [],
  3690. args = slice.call( arguments ),
  3691. handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
  3692. special = jQuery.event.special[ event.type ] || {};
  3693. // Use the fix-ed jQuery.Event rather than the (read-only) native event
  3694. args[0] = event;
  3695. event.delegateTarget = this;
  3696. // Call the preDispatch hook for the mapped type, and let it bail if desired
  3697. if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
  3698. return;
  3699. }
  3700. // Determine handlers
  3701. handlerQueue = jQuery.event.handlers.call( this, event, handlers );
  3702. // Run delegates first; they may want to stop propagation beneath us
  3703. i = 0;
  3704. while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
  3705. event.currentTarget = matched.elem;
  3706. j = 0;
  3707. while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
  3708. // Triggered event must either 1) have no namespace, or
  3709. // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
  3710. if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
  3711. event.handleObj = handleObj;
  3712. event.data = handleObj.data;
  3713. ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
  3714. .apply( matched.elem, args );
  3715. if ( ret !== undefined ) {
  3716. if ( (event.result = ret) === false ) {
  3717. event.preventDefault();
  3718. event.stopPropagation();
  3719. }
  3720. }
  3721. }
  3722. }
  3723. }
  3724. // Call the postDispatch hook for the mapped type
  3725. if ( special.postDispatch ) {
  3726. special.postDispatch.call( this, event );
  3727. }
  3728. return event.result;
  3729. },
  3730. handlers: function( event, handlers ) {
  3731. var i, matches, sel, handleObj,
  3732. handlerQueue = [],
  3733. delegateCount = handlers.delegateCount,
  3734. cur = event.target;
  3735. // Find delegate handlers
  3736. // Black-hole SVG <use> instance trees (#13180)
  3737. // Avoid non-left-click bubbling in Firefox (#3861)
  3738. if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
  3739. for ( ; cur !== this; cur = cur.parentNode || this ) {
  3740. // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
  3741. if ( cur.disabled !== true || event.type !== "click" ) {
  3742. matches = [];
  3743. for ( i = 0; i < delegateCount; i++ ) {
  3744. handleObj = handlers[ i ];
  3745. // Don't conflict with Object.prototype properties (#13203)
  3746. sel = handleObj.selector + " ";
  3747. if ( matches[ sel ] === undefined ) {
  3748. matches[ sel ] = handleObj.needsContext ?
  3749. jQuery( sel, this ).index( cur ) >= 0 :
  3750. jQuery.find( sel, this, null, [ cur ] ).length;
  3751. }
  3752. if ( matches[ sel ] ) {
  3753. matches.push( handleObj );
  3754. }
  3755. }
  3756. if ( matches.length ) {
  3757. handlerQueue.push({ elem: cur, handlers: matches });
  3758. }
  3759. }
  3760. }
  3761. }
  3762. // Add the remaining (directly-bound) handlers
  3763. if ( delegateCount < handlers.length ) {
  3764. handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
  3765. }
  3766. return handlerQueue;
  3767. },
  3768. // Includes some event props shared by KeyEvent and MouseEvent
  3769. props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
  3770. fixHooks: {},
  3771. keyHooks: {
  3772. props: "char charCode key keyCode".split(" "),
  3773. filter: function( event, original ) {
  3774. // Add which for key events
  3775. if ( event.which == null ) {
  3776. event.which = original.charCode != null ? original.charCode : original.keyCode;
  3777. }
  3778. return event;
  3779. }
  3780. },
  3781. mouseHooks: {
  3782. props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
  3783. filter: function( event, original ) {
  3784. var eventDoc, doc, body,
  3785. button = original.button;
  3786. // Calculate pageX/Y if missing and clientX/Y available
  3787. if ( event.pageX == null && original.clientX != null ) {
  3788. eventDoc = event.target.ownerDocument || document;
  3789. doc = eventDoc.documentElement;
  3790. body = eventDoc.body;
  3791. event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
  3792. event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
  3793. }
  3794. // Add which for click: 1 === left; 2 === middle; 3 === right
  3795. // Note: button is not normalized, so don't use it
  3796. if ( !event.which && button !== undefined ) {
  3797. event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
  3798. }
  3799. return event;
  3800. }
  3801. },
  3802. fix: function( event ) {
  3803. if ( event[ jQuery.expando ] ) {
  3804. return event;
  3805. }
  3806. // Create a writable copy of the event object and normalize some properties
  3807. var i, prop, copy,
  3808. type = event.type,
  3809. originalEvent = event,
  3810. fixHook = this.fixHooks[ type ];
  3811. if ( !fixHook ) {
  3812. this.fixHooks[ type ] = fixHook =
  3813. rmouseEvent.test( type ) ? this.mouseHooks :
  3814. rkeyEvent.test( type ) ? this.keyHooks :
  3815. {};
  3816. }
  3817. copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
  3818. event = new jQuery.Event( originalEvent );
  3819. i = copy.length;
  3820. while ( i-- ) {
  3821. prop = copy[ i ];
  3822. event[ prop ] = originalEvent[ prop ];
  3823. }
  3824. // Support: Cordova 2.5 (WebKit) (#13255)
  3825. // All events should have a target; Cordova deviceready doesn't
  3826. if ( !event.target ) {
  3827. event.target = document;
  3828. }
  3829. // Support: Safari 6.0+, Chrome < 28
  3830. // Target should not be a text node (#504, #13143)
  3831. if ( event.target.nodeType === 3 ) {
  3832. event.target = event.target.parentNode;
  3833. }
  3834. return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
  3835. },
  3836. special: {
  3837. load: {
  3838. // Prevent triggered image.load events from bubbling to window.load
  3839. noBubble: true
  3840. },
  3841. focus: {
  3842. // Fire native event if possible so blur/focus sequence is correct
  3843. trigger: function() {
  3844. if ( this !== safeActiveElement() && this.focus ) {
  3845. this.focus();
  3846. return false;
  3847. }
  3848. },
  3849. delegateType: "focusin"
  3850. },
  3851. blur: {
  3852. trigger: function() {
  3853. if ( this === safeActiveElement() && this.blur ) {
  3854. this.blur();
  3855. return false;
  3856. }
  3857. },
  3858. delegateType: "focusout"
  3859. },
  3860. click: {
  3861. // For checkbox, fire native event so checked state will be right
  3862. trigger: function() {
  3863. if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
  3864. this.click();
  3865. return false;
  3866. }
  3867. },
  3868. // For cross-browser consistency, don't fire native .click() on links
  3869. _default: function( event ) {
  3870. return jQuery.nodeName( event.target, "a" );
  3871. }
  3872. },
  3873. beforeunload: {
  3874. postDispatch: function( event ) {
  3875. // Support: Firefox 20+
  3876. // Firefox doesn't alert if the returnValue field is not set.
  3877. if ( event.result !== undefined && event.originalEvent ) {
  3878. event.originalEvent.returnValue = event.result;
  3879. }
  3880. }
  3881. }
  3882. },
  3883. simulate: function( type, elem, event, bubble ) {
  3884. // Piggyback on a donor event to simulate a different one.
  3885. // Fake originalEvent to avoid donor's stopPropagation, but if the
  3886. // simulated event prevents default then we do the same on the donor.
  3887. var e = jQuery.extend(
  3888. new jQuery.Event(),
  3889. event,
  3890. {
  3891. type: type,
  3892. isSimulated: true,
  3893. originalEvent: {}
  3894. }
  3895. );
  3896. if ( bubble ) {
  3897. jQuery.event.trigger( e, null, elem );
  3898. } else {
  3899. jQuery.event.dispatch.call( elem, e );
  3900. }
  3901. if ( e.isDefaultPrevented() ) {
  3902. event.preventDefault();
  3903. }
  3904. }
  3905. };
  3906. jQuery.removeEvent = function( elem, type, handle ) {
  3907. if ( elem.removeEventListener ) {
  3908. elem.removeEventListener( type, handle, false );
  3909. }
  3910. };
  3911. jQuery.Event = function( src, props ) {
  3912. // Allow instantiation without the 'new' keyword
  3913. if ( !(this instanceof jQuery.Event) ) {
  3914. return new jQuery.Event( src, props );
  3915. }
  3916. // Event object
  3917. if ( src && src.type ) {
  3918. this.originalEvent = src;
  3919. this.type = src.type;
  3920. // Events bubbling up the document may have been marked as prevented
  3921. // by a handler lower down the tree; reflect the correct value.
  3922. this.isDefaultPrevented = src.defaultPrevented ||
  3923. src.defaultPrevented === undefined &&
  3924. // Support: Android < 4.0
  3925. src.returnValue === false ?
  3926. returnTrue :
  3927. returnFalse;
  3928. // Event type
  3929. } else {
  3930. this.type = src;
  3931. }
  3932. // Put explicitly provided properties onto the event object
  3933. if ( props ) {
  3934. jQuery.extend( this, props );
  3935. }
  3936. // Create a timestamp if incoming event doesn't have one
  3937. this.timeStamp = src && src.timeStamp || jQuery.now();
  3938. // Mark it as fixed
  3939. this[ jQuery.expando ] = true;
  3940. };
  3941. // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
  3942. // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
  3943. jQuery.Event.prototype = {
  3944. isDefaultPrevented: returnFalse,
  3945. isPropagationStopped: returnFalse,
  3946. isImmediatePropagationStopped: returnFalse,
  3947. preventDefault: function() {
  3948. var e = this.originalEvent;
  3949. this.isDefaultPrevented = returnTrue;
  3950. if ( e && e.preventDefault ) {
  3951. e.preventDefault();
  3952. }
  3953. },
  3954. stopPropagation: function() {
  3955. var e = this.originalEvent;
  3956. this.isPropagationStopped = returnTrue;
  3957. if ( e && e.stopPropagation ) {
  3958. e.stopPropagation();
  3959. }
  3960. },
  3961. stopImmediatePropagation: function() {
  3962. var e = this.originalEvent;
  3963. this.isImmediatePropagationStopped = returnTrue;
  3964. if ( e && e.stopImmediatePropagation ) {
  3965. e.stopImmediatePropagation();
  3966. }
  3967. this.stopPropagation();
  3968. }
  3969. };
  3970. // Create mouseenter/leave events using mouseover/out and event-time checks
  3971. // Support: Chrome 15+
  3972. jQuery.each({
  3973. mouseenter: "mouseover",
  3974. mouseleave: "mouseout",
  3975. pointerenter: "pointerover",
  3976. pointerleave: "pointerout"
  3977. }, function( orig, fix ) {
  3978. jQuery.event.special[ orig ] = {
  3979. delegateType: fix,
  3980. bindType: fix,
  3981. handle: function( event ) {
  3982. var ret,
  3983. target = this,
  3984. related = event.relatedTarget,
  3985. handleObj = event.handleObj;
  3986. // For mousenter/leave call the handler if related is outside the target.
  3987. // NB: No relatedTarget if the mouse left/entered the browser window
  3988. if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
  3989. event.type = handleObj.origType;
  3990. ret = handleObj.handler.apply( this, arguments );
  3991. event.type = fix;
  3992. }
  3993. return ret;
  3994. }
  3995. };
  3996. });
  3997. // Create "bubbling" focus and blur events
  3998. // Support: Firefox, Chrome, Safari
  3999. if ( !support.focusinBubbles ) {
  4000. jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
  4001. // Attach a single capturing handler on the document while someone wants focusin/focusout
  4002. var handler = function( event ) {
  4003. jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
  4004. };
  4005. jQuery.event.special[ fix ] = {
  4006. setup: function() {
  4007. var doc = this.ownerDocument || this,
  4008. attaches = data_priv.access( doc, fix );
  4009. if ( !attaches ) {
  4010. doc.addEventListener( orig, handler, true );
  4011. }
  4012. data_priv.access( doc, fix, ( attaches || 0 ) + 1 );
  4013. },
  4014. teardown: function() {
  4015. var doc = this.ownerDocument || this,
  4016. attaches = data_priv.access( doc, fix ) - 1;
  4017. if ( !attaches ) {
  4018. doc.removeEventListener( orig, handler, true );
  4019. data_priv.remove( doc, fix );
  4020. } else {
  4021. data_priv.access( doc, fix, attaches );
  4022. }
  4023. }
  4024. };
  4025. });
  4026. }
  4027. jQuery.fn.extend({
  4028. on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
  4029. var origFn, type;
  4030. // Types can be a map of types/handlers
  4031. if ( typeof types === "object" ) {
  4032. // ( types-Object, selector, data )
  4033. if ( typeof selector !== "string" ) {
  4034. // ( types-Object, data )
  4035. data = data || selector;
  4036. selector = undefined;
  4037. }
  4038. for ( type in types ) {
  4039. this.on( type, selector, data, types[ type ], one );
  4040. }
  4041. return this;
  4042. }
  4043. if ( data == null && fn == null ) {
  4044. // ( types, fn )
  4045. fn = selector;
  4046. data = selector = undefined;
  4047. } else if ( fn == null ) {
  4048. if ( typeof selector === "string" ) {
  4049. // ( types, selector, fn )
  4050. fn = data;
  4051. data = undefined;
  4052. } else {
  4053. // ( types, data, fn )
  4054. fn = data;
  4055. data = selector;
  4056. selector = undefined;
  4057. }
  4058. }
  4059. if ( fn === false ) {
  4060. fn = returnFalse;
  4061. } else if ( !fn ) {
  4062. return this;
  4063. }
  4064. if ( one === 1 ) {
  4065. origFn = fn;
  4066. fn = function( event ) {
  4067. // Can use an empty set, since event contains the info
  4068. jQuery().off( event );
  4069. return origFn.apply( this, arguments );
  4070. };
  4071. // Use same guid so caller can remove using origFn
  4072. fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
  4073. }
  4074. return this.each( function() {
  4075. jQuery.event.add( this, types, fn, data, selector );
  4076. });
  4077. },
  4078. one: function( types, selector, data, fn ) {
  4079. return this.on( types, selector, data, fn, 1 );
  4080. },
  4081. off: function( types, selector, fn ) {
  4082. var handleObj, type;
  4083. if ( types && types.preventDefault && types.handleObj ) {
  4084. // ( event ) dispatched jQuery.Event
  4085. handleObj = types.handleObj;
  4086. jQuery( types.delegateTarget ).off(
  4087. handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
  4088. handleObj.selector,
  4089. handleObj.handler
  4090. );
  4091. return this;
  4092. }
  4093. if ( typeof types === "object" ) {
  4094. // ( types-object [, selector] )
  4095. for ( type in types ) {
  4096. this.off( type, selector, types[ type ] );
  4097. }
  4098. return this;
  4099. }
  4100. if ( selector === false || typeof selector === "function" ) {
  4101. // ( types [, fn] )
  4102. fn = selector;
  4103. selector = undefined;
  4104. }
  4105. if ( fn === false ) {
  4106. fn = returnFalse;
  4107. }
  4108. return this.each(function() {
  4109. jQuery.event.remove( this, types, fn, selector );
  4110. });
  4111. },
  4112. trigger: function( type, data ) {
  4113. return this.each(function() {
  4114. jQuery.event.trigger( type, data, this );
  4115. });
  4116. },
  4117. triggerHandler: function( type, data ) {
  4118. var elem = this[0];
  4119. if ( elem ) {
  4120. return jQuery.event.trigger( type, data, elem, true );
  4121. }
  4122. }
  4123. });
  4124. var
  4125. rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
  4126. rtagName = /<([\w:]+)/,
  4127. rhtml = /<|&#?\w+;/,
  4128. rnoInnerhtml = /<(?:script|style|link)/i,
  4129. // checked="checked" or checked
  4130. rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
  4131. rscriptType = /^$|\/(?:java|ecma)script/i,
  4132. rscriptTypeMasked = /^true\/(.*)/,
  4133. rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
  4134. // We have to close these tags to support XHTML (#13200)
  4135. wrapMap = {
  4136. // Support: IE 9
  4137. option: [ 1, "<select multiple='multiple'>", "</select>" ],
  4138. thead: [ 1, "<table>", "</table>" ],
  4139. col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
  4140. tr: [ 2, "<table><tbody>", "</tbody></table>" ],
  4141. td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
  4142. _default: [ 0, "", "" ]
  4143. };
  4144. // Support: IE 9
  4145. wrapMap.optgroup = wrapMap.option;
  4146. wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
  4147. wrapMap.th = wrapMap.td;
  4148. // Support: 1.x compatibility
  4149. // Manipulating tables requires a tbody
  4150. function manipulationTarget( elem, content ) {
  4151. return jQuery.nodeName( elem, "table" ) &&
  4152. jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
  4153. elem.getElementsByTagName("tbody")[0] ||
  4154. elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
  4155. elem;
  4156. }
  4157. // Replace/restore the type attribute of script elements for safe DOM manipulation
  4158. function disableScript( elem ) {
  4159. elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
  4160. return elem;
  4161. }
  4162. function restoreScript( elem ) {
  4163. var match = rscriptTypeMasked.exec( elem.type );
  4164. if ( match ) {
  4165. elem.type = match[ 1 ];
  4166. } else {
  4167. elem.removeAttribute("type");
  4168. }
  4169. return elem;
  4170. }
  4171. // Mark scripts as having already been evaluated
  4172. function setGlobalEval( elems, refElements ) {
  4173. var i = 0,
  4174. l = elems.length;
  4175. for ( ; i < l; i++ ) {
  4176. data_priv.set(
  4177. elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" )
  4178. );
  4179. }
  4180. }
  4181. function cloneCopyEvent( src, dest ) {
  4182. var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
  4183. if ( dest.nodeType !== 1 ) {
  4184. return;
  4185. }
  4186. // 1. Copy private data: events, handlers, etc.
  4187. if ( data_priv.hasData( src ) ) {
  4188. pdataOld = data_priv.access( src );
  4189. pdataCur = data_priv.set( dest, pdataOld );
  4190. events = pdataOld.events;
  4191. if ( events ) {
  4192. delete pdataCur.handle;
  4193. pdataCur.events = {};
  4194. for ( type in events ) {
  4195. for ( i = 0, l = events[ type ].length; i < l; i++ ) {
  4196. jQuery.event.add( dest, type, events[ type ][ i ] );
  4197. }
  4198. }
  4199. }
  4200. }
  4201. // 2. Copy user data
  4202. if ( data_user.hasData( src ) ) {
  4203. udataOld = data_user.access( src );
  4204. udataCur = jQuery.extend( {}, udataOld );
  4205. data_user.set( dest, udataCur );
  4206. }
  4207. }
  4208. function getAll( context, tag ) {
  4209. var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) :
  4210. context.querySelectorAll ? context.querySelectorAll( tag || "*" ) :
  4211. [];
  4212. return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
  4213. jQuery.merge( [ context ], ret ) :
  4214. ret;
  4215. }
  4216. // Support: IE >= 9
  4217. function fixInput( src, dest ) {
  4218. var nodeName = dest.nodeName.toLowerCase();
  4219. // Fails to persist the checked state of a cloned checkbox or radio button.
  4220. if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
  4221. dest.checked = src.checked;
  4222. // Fails to return the selected option to the default selected state when cloning options
  4223. } else if ( nodeName === "input" || nodeName === "textarea" ) {
  4224. dest.defaultValue = src.defaultValue;
  4225. }
  4226. }
  4227. jQuery.extend({
  4228. clone: function( elem, dataAndEvents, deepDataAndEvents ) {
  4229. var i, l, srcElements, destElements,
  4230. clone = elem.cloneNode( true ),
  4231. inPage = jQuery.contains( elem.ownerDocument, elem );
  4232. // Support: IE >= 9
  4233. // Fix Cloning issues
  4234. if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
  4235. !jQuery.isXMLDoc( elem ) ) {
  4236. // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
  4237. destElements = getAll( clone );
  4238. srcElements = getAll( elem );
  4239. for ( i = 0, l = srcElements.length; i < l; i++ ) {
  4240. fixInput( srcElements[ i ], destElements[ i ] );
  4241. }
  4242. }
  4243. // Copy the events from the original to the clone
  4244. if ( dataAndEvents ) {
  4245. if ( deepDataAndEvents ) {
  4246. srcElements = srcElements || getAll( elem );
  4247. destElements = destElements || getAll( clone );
  4248. for ( i = 0, l = srcElements.length; i < l; i++ ) {
  4249. cloneCopyEvent( srcElements[ i ], destElements[ i ] );
  4250. }
  4251. } else {
  4252. cloneCopyEvent( elem, clone );
  4253. }
  4254. }
  4255. // Preserve script evaluation history
  4256. destElements = getAll( clone, "script" );
  4257. if ( destElements.length > 0 ) {
  4258. setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
  4259. }
  4260. // Return the cloned set
  4261. return clone;
  4262. },
  4263. buildFragment: function( elems, context, scripts, selection ) {
  4264. var elem, tmp, tag, wrap, contains, j,
  4265. fragment = context.createDocumentFragment(),
  4266. nodes = [],
  4267. i = 0,
  4268. l = elems.length;
  4269. for ( ; i < l; i++ ) {
  4270. elem = elems[ i ];
  4271. if ( elem || elem === 0 ) {
  4272. // Add nodes directly
  4273. if ( jQuery.type( elem ) === "object" ) {
  4274. // Support: QtWebKit
  4275. // jQuery.merge because push.apply(_, arraylike) throws
  4276. jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
  4277. // Convert non-html into a text node
  4278. } else if ( !rhtml.test( elem ) ) {
  4279. nodes.push( context.createTextNode( elem ) );
  4280. // Convert html into DOM nodes
  4281. } else {
  4282. tmp = tmp || fragment.appendChild( context.createElement("div") );
  4283. // Deserialize a standard representation
  4284. tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
  4285. wrap = wrapMap[ tag ] || wrapMap._default;
  4286. tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];
  4287. // Descend through wrappers to the right content
  4288. j = wrap[ 0 ];
  4289. while ( j-- ) {
  4290. tmp = tmp.lastChild;
  4291. }
  4292. // Support: QtWebKit
  4293. // jQuery.merge because push.apply(_, arraylike) throws
  4294. jQuery.merge( nodes, tmp.childNodes );
  4295. // Remember the top-level container
  4296. tmp = fragment.firstChild;
  4297. // Fixes #12346
  4298. // Support: Webkit, IE
  4299. tmp.textContent = "";
  4300. }
  4301. }
  4302. }
  4303. // Remove wrapper from fragment
  4304. fragment.textContent = "";
  4305. i = 0;
  4306. while ( (elem = nodes[ i++ ]) ) {
  4307. // #4087 - If origin and destination elements are the same, and this is
  4308. // that element, do not do anything
  4309. if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
  4310. continue;
  4311. }
  4312. contains = jQuery.contains( elem.ownerDocument, elem );
  4313. // Append to fragment
  4314. tmp = getAll( fragment.appendChild( elem ), "script" );
  4315. // Preserve script evaluation history
  4316. if ( contains ) {
  4317. setGlobalEval( tmp );
  4318. }
  4319. // Capture executables
  4320. if ( scripts ) {
  4321. j = 0;
  4322. while ( (elem = tmp[ j++ ]) ) {
  4323. if ( rscriptType.test( elem.type || "" ) ) {
  4324. scripts.push( elem );
  4325. }
  4326. }
  4327. }
  4328. }
  4329. return fragment;
  4330. },
  4331. cleanData: function( elems ) {
  4332. var data, elem, type, key,
  4333. special = jQuery.event.special,
  4334. i = 0;
  4335. for ( ; (elem = elems[ i ]) !== undefined; i++ ) {
  4336. if ( jQuery.acceptData( elem ) ) {
  4337. key = elem[ data_priv.expando ];
  4338. if ( key && (data = data_priv.cache[ key ]) ) {
  4339. if ( data.events ) {
  4340. for ( type in data.events ) {
  4341. if ( special[ type ] ) {
  4342. jQuery.event.remove( elem, type );
  4343. // This is a shortcut to avoid jQuery.event.remove's overhead
  4344. } else {
  4345. jQuery.removeEvent( elem, type, data.handle );
  4346. }
  4347. }
  4348. }
  4349. if ( data_priv.cache[ key ] ) {
  4350. // Discard any remaining `private` data
  4351. delete data_priv.cache[ key ];
  4352. }
  4353. }
  4354. }
  4355. // Discard any remaining `user` data
  4356. delete data_user.cache[ elem[ data_user.expando ] ];
  4357. }
  4358. }
  4359. });
  4360. jQuery.fn.extend({
  4361. text: function( value ) {
  4362. return access( this, function( value ) {
  4363. return value === undefined ?
  4364. jQuery.text( this ) :
  4365. this.empty().each(function() {
  4366. if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  4367. this.textContent = value;
  4368. }
  4369. });
  4370. }, null, value, arguments.length );
  4371. },
  4372. append: function() {
  4373. return this.domManip( arguments, function( elem ) {
  4374. if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  4375. var target = manipulationTarget( this, elem );
  4376. target.appendChild( elem );
  4377. }
  4378. });
  4379. },
  4380. prepend: function() {
  4381. return this.domManip( arguments, function( elem ) {
  4382. if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  4383. var target = manipulationTarget( this, elem );
  4384. target.insertBefore( elem, target.firstChild );
  4385. }
  4386. });
  4387. },
  4388. before: function() {
  4389. return this.domManip( arguments, function( elem ) {
  4390. if ( this.parentNode ) {
  4391. this.parentNode.insertBefore( elem, this );
  4392. }
  4393. });
  4394. },
  4395. after: function() {
  4396. return this.domManip( arguments, function( elem ) {
  4397. if ( this.parentNode ) {
  4398. this.parentNode.insertBefore( elem, this.nextSibling );
  4399. }
  4400. });
  4401. },
  4402. remove: function( selector, keepData /* Internal Use Only */ ) {
  4403. var elem,
  4404. elems = selector ? jQuery.filter( selector, this ) : this,
  4405. i = 0;
  4406. for ( ; (elem = elems[i]) != null; i++ ) {
  4407. if ( !keepData && elem.nodeType === 1 ) {
  4408. jQuery.cleanData( getAll( elem ) );
  4409. }
  4410. if ( elem.parentNode ) {
  4411. if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
  4412. setGlobalEval( getAll( elem, "script" ) );
  4413. }
  4414. elem.parentNode.removeChild( elem );
  4415. }
  4416. }
  4417. return this;
  4418. },
  4419. empty: function() {
  4420. var elem,
  4421. i = 0;
  4422. for ( ; (elem = this[i]) != null; i++ ) {
  4423. if ( elem.nodeType === 1 ) {
  4424. // Prevent memory leaks
  4425. jQuery.cleanData( getAll( elem, false ) );
  4426. // Remove any remaining nodes
  4427. elem.textContent = "";
  4428. }
  4429. }
  4430. return this;
  4431. },
  4432. clone: function( dataAndEvents, deepDataAndEvents ) {
  4433. dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
  4434. deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
  4435. return this.map(function() {
  4436. return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
  4437. });
  4438. },
  4439. html: function( value ) {
  4440. return access( this, function( value ) {
  4441. var elem = this[ 0 ] || {},
  4442. i = 0,
  4443. l = this.length;
  4444. if ( value === undefined && elem.nodeType === 1 ) {
  4445. return elem.innerHTML;
  4446. }
  4447. // See if we can take a shortcut and just use innerHTML
  4448. if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
  4449. !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
  4450. value = value.replace( rxhtmlTag, "<$1></$2>" );
  4451. try {
  4452. for ( ; i < l; i++ ) {
  4453. elem = this[ i ] || {};
  4454. // Remove element nodes and prevent memory leaks
  4455. if ( elem.nodeType === 1 ) {
  4456. jQuery.cleanData( getAll( elem, false ) );
  4457. elem.innerHTML = value;
  4458. }
  4459. }
  4460. elem = 0;
  4461. // If using innerHTML throws an exception, use the fallback method
  4462. } catch( e ) {}
  4463. }
  4464. if ( elem ) {
  4465. this.empty().append( value );
  4466. }
  4467. }, null, value, arguments.length );
  4468. },
  4469. replaceWith: function() {
  4470. var arg = arguments[ 0 ];
  4471. // Make the changes, replacing each context element with the new content
  4472. this.domManip( arguments, function( elem ) {
  4473. arg = this.parentNode;
  4474. jQuery.cleanData( getAll( this ) );
  4475. if ( arg ) {
  4476. arg.replaceChild( elem, this );
  4477. }
  4478. });
  4479. // Force removal if there was no new content (e.g., from empty arguments)
  4480. return arg && (arg.length || arg.nodeType) ? this : this.remove();
  4481. },
  4482. detach: function( selector ) {
  4483. return this.remove( selector, true );
  4484. },
  4485. domManip: function( args, callback ) {
  4486. // Flatten any nested arrays
  4487. args = concat.apply( [], args );
  4488. var fragment, first, scripts, hasScripts, node, doc,
  4489. i = 0,
  4490. l = this.length,
  4491. set = this,
  4492. iNoClone = l - 1,
  4493. value = args[ 0 ],
  4494. isFunction = jQuery.isFunction( value );
  4495. // We can't cloneNode fragments that contain checked, in WebKit
  4496. if ( isFunction ||
  4497. ( l > 1 && typeof value === "string" &&
  4498. !support.checkClone && rchecked.test( value ) ) ) {
  4499. return this.each(function( index ) {
  4500. var self = set.eq( index );
  4501. if ( isFunction ) {
  4502. args[ 0 ] = value.call( this, index, self.html() );
  4503. }
  4504. self.domManip( args, callback );
  4505. });
  4506. }
  4507. if ( l ) {
  4508. fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
  4509. first = fragment.firstChild;
  4510. if ( fragment.childNodes.length === 1 ) {
  4511. fragment = first;
  4512. }
  4513. if ( first ) {
  4514. scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
  4515. hasScripts = scripts.length;
  4516. // Use the original fragment for the last item instead of the first because it can end up
  4517. // being emptied incorrectly in certain situations (#8070).
  4518. for ( ; i < l; i++ ) {
  4519. node = fragment;
  4520. if ( i !== iNoClone ) {
  4521. node = jQuery.clone( node, true, true );
  4522. // Keep references to cloned scripts for later restoration
  4523. if ( hasScripts ) {
  4524. // Support: QtWebKit
  4525. // jQuery.merge because push.apply(_, arraylike) throws
  4526. jQuery.merge( scripts, getAll( node, "script" ) );
  4527. }
  4528. }
  4529. callback.call( this[ i ], node, i );
  4530. }
  4531. if ( hasScripts ) {
  4532. doc = scripts[ scripts.length - 1 ].ownerDocument;
  4533. // Reenable scripts
  4534. jQuery.map( scripts, restoreScript );
  4535. // Evaluate executable scripts on first document insertion
  4536. for ( i = 0; i < hasScripts; i++ ) {
  4537. node = scripts[ i ];
  4538. if ( rscriptType.test( node.type || "" ) &&
  4539. !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
  4540. if ( node.src ) {
  4541. // Optional AJAX dependency, but won't run scripts if not present
  4542. if ( jQuery._evalUrl ) {
  4543. jQuery._evalUrl( node.src );
  4544. }
  4545. } else {
  4546. jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
  4547. }
  4548. }
  4549. }
  4550. }
  4551. }
  4552. }
  4553. return this;
  4554. }
  4555. });
  4556. jQuery.each({
  4557. appendTo: "append",
  4558. prependTo: "prepend",
  4559. insertBefore: "before",
  4560. insertAfter: "after",
  4561. replaceAll: "replaceWith"
  4562. }, function( name, original ) {
  4563. jQuery.fn[ name ] = function( selector ) {
  4564. var elems,
  4565. ret = [],
  4566. insert = jQuery( selector ),
  4567. last = insert.length - 1,
  4568. i = 0;
  4569. for ( ; i <= last; i++ ) {
  4570. elems = i === last ? this : this.clone( true );
  4571. jQuery( insert[ i ] )[ original ]( elems );
  4572. // Support: QtWebKit
  4573. // .get() because push.apply(_, arraylike) throws
  4574. push.apply( ret, elems.get() );
  4575. }
  4576. return this.pushStack( ret );
  4577. };
  4578. });
  4579. var iframe,
  4580. elemdisplay = {};
  4581. /**
  4582. * Retrieve the actual display of a element
  4583. * @param {String} name nodeName of the element
  4584. * @param {Object} doc Document object
  4585. */
  4586. // Called only from within defaultDisplay
  4587. function actualDisplay( name, doc ) {
  4588. var style,
  4589. elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
  4590. // getDefaultComputedStyle might be reliably used only on attached element
  4591. display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
  4592. // Use of this method is a temporary fix (more like optmization) until something better comes along,
  4593. // since it was removed from specification and supported only in FF
  4594. style.display : jQuery.css( elem[ 0 ], "display" );
  4595. // We don't have any data stored on the element,
  4596. // so use "detach" method as fast way to get rid of the element
  4597. elem.detach();
  4598. return display;
  4599. }
  4600. /**
  4601. * Try to determine the default display value of an element
  4602. * @param {String} nodeName
  4603. */
  4604. function defaultDisplay( nodeName ) {
  4605. var doc = document,
  4606. display = elemdisplay[ nodeName ];
  4607. if ( !display ) {
  4608. display = actualDisplay( nodeName, doc );
  4609. // If the simple way fails, read from inside an iframe
  4610. if ( display === "none" || !display ) {
  4611. // Use the already-created iframe if possible
  4612. iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );
  4613. // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
  4614. doc = iframe[ 0 ].contentDocument;
  4615. // Support: IE
  4616. doc.write();
  4617. doc.close();
  4618. display = actualDisplay( nodeName, doc );
  4619. iframe.detach();
  4620. }
  4621. // Store the correct default display
  4622. elemdisplay[ nodeName ] = display;
  4623. }
  4624. return display;
  4625. }
  4626. var rmargin = (/^margin/);
  4627. var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
  4628. var getStyles = function( elem ) {
  4629. return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
  4630. };
  4631. function curCSS( elem, name, computed ) {
  4632. var width, minWidth, maxWidth, ret,
  4633. style = elem.style;
  4634. computed = computed || getStyles( elem );
  4635. // Support: IE9
  4636. // getPropertyValue is only needed for .css('filter') in IE9, see #12537
  4637. if ( computed ) {
  4638. ret = computed.getPropertyValue( name ) || computed[ name ];
  4639. }
  4640. if ( computed ) {
  4641. if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
  4642. ret = jQuery.style( elem, name );
  4643. }
  4644. // Support: iOS < 6
  4645. // A tribute to the "awesome hack by Dean Edwards"
  4646. // iOS < 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
  4647. // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
  4648. if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
  4649. // Remember the original values
  4650. width = style.width;
  4651. minWidth = style.minWidth;
  4652. maxWidth = style.maxWidth;
  4653. // Put in the new values to get a computed value out
  4654. style.minWidth = style.maxWidth = style.width = ret;
  4655. ret = computed.width;
  4656. // Revert the changed values
  4657. style.width = width;
  4658. style.minWidth = minWidth;
  4659. style.maxWidth = maxWidth;
  4660. }
  4661. }
  4662. return ret !== undefined ?
  4663. // Support: IE
  4664. // IE returns zIndex value as an integer.
  4665. ret + "" :
  4666. ret;
  4667. }
  4668. function addGetHookIf( conditionFn, hookFn ) {
  4669. // Define the hook, we'll check on the first run if it's really needed.
  4670. return {
  4671. get: function() {
  4672. if ( conditionFn() ) {
  4673. // Hook not needed (or it's not possible to use it due to missing dependency),
  4674. // remove it.
  4675. // Since there are no other hooks for marginRight, remove the whole object.
  4676. delete this.get;
  4677. return;
  4678. }
  4679. // Hook needed; redefine it so that the support test is not executed again.
  4680. return (this.get = hookFn).apply( this, arguments );
  4681. }
  4682. };
  4683. }
  4684. (function() {
  4685. var pixelPositionVal, boxSizingReliableVal,
  4686. docElem = document.documentElement,
  4687. container = document.createElement( "div" ),
  4688. div = document.createElement( "div" );
  4689. if ( !div.style ) {
  4690. return;
  4691. }
  4692. div.style.backgroundClip = "content-box";
  4693. div.cloneNode( true ).style.backgroundClip = "";
  4694. support.clearCloneStyle = div.style.backgroundClip === "content-box";
  4695. container.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" +
  4696. "position:absolute";
  4697. container.appendChild( div );
  4698. // Executing both pixelPosition & boxSizingReliable tests require only one layout
  4699. // so they're executed at the same time to save the second computation.
  4700. function computePixelPositionAndBoxSizingReliable() {
  4701. div.style.cssText =
  4702. // Support: Firefox<29, Android 2.3
  4703. // Vendor-prefix box-sizing
  4704. "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
  4705. "box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
  4706. "border:1px;padding:1px;width:4px;position:absolute";
  4707. div.innerHTML = "";
  4708. docElem.appendChild( container );
  4709. var divStyle = window.getComputedStyle( div, null );
  4710. pixelPositionVal = divStyle.top !== "1%";
  4711. boxSizingReliableVal = divStyle.width === "4px";
  4712. docElem.removeChild( container );
  4713. }
  4714. // Support: node.js jsdom
  4715. // Don't assume that getComputedStyle is a property of the global object
  4716. if ( window.getComputedStyle ) {
  4717. jQuery.extend( support, {
  4718. pixelPosition: function() {
  4719. // This test is executed only once but we still do memoizing
  4720. // since we can use the boxSizingReliable pre-computing.
  4721. // No need to check if the test was already performed, though.
  4722. computePixelPositionAndBoxSizingReliable();
  4723. return pixelPositionVal;
  4724. },
  4725. boxSizingReliable: function() {
  4726. if ( boxSizingReliableVal == null ) {
  4727. computePixelPositionAndBoxSizingReliable();
  4728. }
  4729. return boxSizingReliableVal;
  4730. },
  4731. reliableMarginRight: function() {
  4732. // Support: Android 2.3
  4733. // Check if div with explicit width and no margin-right incorrectly
  4734. // gets computed margin-right based on width of container. (#3333)
  4735. // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
  4736. // This support function is only executed once so no memoizing is needed.
  4737. var ret,
  4738. marginDiv = div.appendChild( document.createElement( "div" ) );
  4739. // Reset CSS: box-sizing; display; margin; border; padding
  4740. marginDiv.style.cssText = div.style.cssText =
  4741. // Support: Firefox<29, Android 2.3
  4742. // Vendor-prefix box-sizing
  4743. "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
  4744. "box-sizing:content-box;display:block;margin:0;border:0;padding:0";
  4745. marginDiv.style.marginRight = marginDiv.style.width = "0";
  4746. div.style.width = "1px";
  4747. docElem.appendChild( container );
  4748. ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight );
  4749. docElem.removeChild( container );
  4750. return ret;
  4751. }
  4752. });
  4753. }
  4754. })();
  4755. // A method for quickly swapping in/out CSS properties to get correct calculations.
  4756. jQuery.swap = function( elem, options, callback, args ) {
  4757. var ret, name,
  4758. old = {};
  4759. // Remember the old values, and insert the new ones
  4760. for ( name in options ) {
  4761. old[ name ] = elem.style[ name ];
  4762. elem.style[ name ] = options[ name ];
  4763. }
  4764. ret = callback.apply( elem, args || [] );
  4765. // Revert the old values
  4766. for ( name in options ) {
  4767. elem.style[ name ] = old[ name ];
  4768. }
  4769. return ret;
  4770. };
  4771. var
  4772. // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
  4773. // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
  4774. rdisplayswap = /^(none|table(?!-c[ea]).+)/,
  4775. rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
  4776. rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
  4777. cssShow = { position: "absolute", visibility: "hidden", display: "block" },
  4778. cssNormalTransform = {
  4779. letterSpacing: "0",
  4780. fontWeight: "400"
  4781. },
  4782. cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
  4783. // return a css property mapped to a potentially vendor prefixed property
  4784. function vendorPropName( style, name ) {
  4785. // shortcut for names that are not vendor prefixed
  4786. if ( name in style ) {
  4787. return name;
  4788. }
  4789. // check for vendor prefixed names
  4790. var capName = name[0].toUpperCase() + name.slice(1),
  4791. origName = name,
  4792. i = cssPrefixes.length;
  4793. while ( i-- ) {
  4794. name = cssPrefixes[ i ] + capName;
  4795. if ( name in style ) {
  4796. return name;
  4797. }
  4798. }
  4799. return origName;
  4800. }
  4801. function setPositiveNumber( elem, value, subtract ) {
  4802. var matches = rnumsplit.exec( value );
  4803. return matches ?
  4804. // Guard against undefined "subtract", e.g., when used as in cssHooks
  4805. Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
  4806. value;
  4807. }
  4808. function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
  4809. var i = extra === ( isBorderBox ? "border" : "content" ) ?
  4810. // If we already have the right measurement, avoid augmentation
  4811. 4 :
  4812. // Otherwise initialize for horizontal or vertical properties
  4813. name === "width" ? 1 : 0,
  4814. val = 0;
  4815. for ( ; i < 4; i += 2 ) {
  4816. // both box models exclude margin, so add it if we want it
  4817. if ( extra === "margin" ) {
  4818. val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
  4819. }
  4820. if ( isBorderBox ) {
  4821. // border-box includes padding, so remove it if we want content
  4822. if ( extra === "content" ) {
  4823. val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
  4824. }
  4825. // at this point, extra isn't border nor margin, so remove border
  4826. if ( extra !== "margin" ) {
  4827. val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  4828. }
  4829. } else {
  4830. // at this point, extra isn't content, so add padding
  4831. val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
  4832. // at this point, extra isn't content nor padding, so add border
  4833. if ( extra !== "padding" ) {
  4834. val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  4835. }
  4836. }
  4837. }
  4838. return val;
  4839. }
  4840. function getWidthOrHeight( elem, name, extra ) {
  4841. // Start with offset property, which is equivalent to the border-box value
  4842. var valueIsBorderBox = true,
  4843. val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
  4844. styles = getStyles( elem ),
  4845. isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
  4846. // some non-html elements return undefined for offsetWidth, so check for null/undefined
  4847. // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
  4848. // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
  4849. if ( val <= 0 || val == null ) {
  4850. // Fall back to computed then uncomputed css if necessary
  4851. val = curCSS( elem, name, styles );
  4852. if ( val < 0 || val == null ) {
  4853. val = elem.style[ name ];
  4854. }
  4855. // Computed unit is not pixels. Stop here and return.
  4856. if ( rnumnonpx.test(val) ) {
  4857. return val;
  4858. }
  4859. // we need the check for style in case a browser which returns unreliable values
  4860. // for getComputedStyle silently falls back to the reliable elem.style
  4861. valueIsBorderBox = isBorderBox &&
  4862. ( support.boxSizingReliable() || val === elem.style[ name ] );
  4863. // Normalize "", auto, and prepare for extra
  4864. val = parseFloat( val ) || 0;
  4865. }
  4866. // use the active box-sizing model to add/subtract irrelevant styles
  4867. return ( val +
  4868. augmentWidthOrHeight(
  4869. elem,
  4870. name,
  4871. extra || ( isBorderBox ? "border" : "content" ),
  4872. valueIsBorderBox,
  4873. styles
  4874. )
  4875. ) + "px";
  4876. }
  4877. function showHide( elements, show ) {
  4878. var display, elem, hidden,
  4879. values = [],
  4880. index = 0,
  4881. length = elements.length;
  4882. for ( ; index < length; index++ ) {
  4883. elem = elements[ index ];
  4884. if ( !elem.style ) {
  4885. continue;
  4886. }
  4887. values[ index ] = data_priv.get( elem, "olddisplay" );
  4888. display = elem.style.display;
  4889. if ( show ) {
  4890. // Reset the inline display of this element to learn if it is
  4891. // being hidden by cascaded rules or not
  4892. if ( !values[ index ] && display === "none" ) {
  4893. elem.style.display = "";
  4894. }
  4895. // Set elements which have been overridden with display: none
  4896. // in a stylesheet to whatever the default browser style is
  4897. // for such an element
  4898. if ( elem.style.display === "" && isHidden( elem ) ) {
  4899. values[ index ] = data_priv.access( elem, "olddisplay", defaultDisplay(elem.nodeName) );
  4900. }
  4901. } else {
  4902. hidden = isHidden( elem );
  4903. if ( display !== "none" || !hidden ) {
  4904. data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
  4905. }
  4906. }
  4907. }
  4908. // Set the display of most of the elements in a second loop
  4909. // to avoid the constant reflow
  4910. for ( index = 0; index < length; index++ ) {
  4911. elem = elements[ index ];
  4912. if ( !elem.style ) {
  4913. continue;
  4914. }
  4915. if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
  4916. elem.style.display = show ? values[ index ] || "" : "none";
  4917. }
  4918. }
  4919. return elements;
  4920. }
  4921. jQuery.extend({
  4922. // Add in style property hooks for overriding the default
  4923. // behavior of getting and setting a style property
  4924. cssHooks: {
  4925. opacity: {
  4926. get: function( elem, computed ) {
  4927. if ( computed ) {
  4928. // We should always get a number back from opacity
  4929. var ret = curCSS( elem, "opacity" );
  4930. return ret === "" ? "1" : ret;
  4931. }
  4932. }
  4933. }
  4934. },
  4935. // Don't automatically add "px" to these possibly-unitless properties
  4936. cssNumber: {
  4937. "columnCount": true,
  4938. "fillOpacity": true,
  4939. "flexGrow": true,
  4940. "flexShrink": true,
  4941. "fontWeight": true,
  4942. "lineHeight": true,
  4943. "opacity": true,
  4944. "order": true,
  4945. "orphans": true,
  4946. "widows": true,
  4947. "zIndex": true,
  4948. "zoom": true
  4949. },
  4950. // Add in properties whose names you wish to fix before
  4951. // setting or getting the value
  4952. cssProps: {
  4953. // normalize float css property
  4954. "float": "cssFloat"
  4955. },
  4956. // Get and set the style property on a DOM Node
  4957. style: function( elem, name, value, extra ) {
  4958. // Don't set styles on text and comment nodes
  4959. if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
  4960. return;
  4961. }
  4962. // Make sure that we're working with the right name
  4963. var ret, type, hooks,
  4964. origName = jQuery.camelCase( name ),
  4965. style = elem.style;
  4966. name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
  4967. // gets hook for the prefixed version
  4968. // followed by the unprefixed version
  4969. hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  4970. // Check if we're setting a value
  4971. if ( value !== undefined ) {
  4972. type = typeof value;
  4973. // convert relative number strings (+= or -=) to relative numbers. #7345
  4974. if ( type === "string" && (ret = rrelNum.exec( value )) ) {
  4975. value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
  4976. // Fixes bug #9237
  4977. type = "number";
  4978. }
  4979. // Make sure that null and NaN values aren't set. See: #7116
  4980. if ( value == null || value !== value ) {
  4981. return;
  4982. }
  4983. // If a number was passed in, add 'px' to the (except for certain CSS properties)
  4984. if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
  4985. value += "px";
  4986. }
  4987. // Fixes #8908, it can be done more correctly by specifying setters in cssHooks,
  4988. // but it would mean to define eight (for every problematic property) identical functions
  4989. if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
  4990. style[ name ] = "inherit";
  4991. }
  4992. // If a hook was provided, use that value, otherwise just set the specified value
  4993. if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
  4994. style[ name ] = value;
  4995. }
  4996. } else {
  4997. // If a hook was provided get the non-computed value from there
  4998. if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
  4999. return ret;
  5000. }
  5001. // Otherwise just get the value from the style object
  5002. return style[ name ];
  5003. }
  5004. },
  5005. css: function( elem, name, extra, styles ) {
  5006. var val, num, hooks,
  5007. origName = jQuery.camelCase( name );
  5008. // Make sure that we're working with the right name
  5009. name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
  5010. // gets hook for the prefixed version
  5011. // followed by the unprefixed version
  5012. hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  5013. // If a hook was provided get the computed value from there
  5014. if ( hooks && "get" in hooks ) {
  5015. val = hooks.get( elem, true, extra );
  5016. }
  5017. // Otherwise, if a way to get the computed value exists, use that
  5018. if ( val === undefined ) {
  5019. val = curCSS( elem, name, styles );
  5020. }
  5021. //convert "normal" to computed value
  5022. if ( val === "normal" && name in cssNormalTransform ) {
  5023. val = cssNormalTransform[ name ];
  5024. }
  5025. // Return, converting to number if forced or a qualifier was provided and val looks numeric
  5026. if ( extra === "" || extra ) {
  5027. num = parseFloat( val );
  5028. return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
  5029. }
  5030. return val;
  5031. }
  5032. });
  5033. jQuery.each([ "height", "width" ], function( i, name ) {
  5034. jQuery.cssHooks[ name ] = {
  5035. get: function( elem, computed, extra ) {
  5036. if ( computed ) {
  5037. // certain elements can have dimension info if we invisibly show them
  5038. // however, it must have a current display style that would benefit from this
  5039. return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
  5040. jQuery.swap( elem, cssShow, function() {
  5041. return getWidthOrHeight( elem, name, extra );
  5042. }) :
  5043. getWidthOrHeight( elem, name, extra );
  5044. }
  5045. },
  5046. set: function( elem, value, extra ) {
  5047. var styles = extra && getStyles( elem );
  5048. return setPositiveNumber( elem, value, extra ?
  5049. augmentWidthOrHeight(
  5050. elem,
  5051. name,
  5052. extra,
  5053. jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
  5054. styles
  5055. ) : 0
  5056. );
  5057. }
  5058. };
  5059. });
  5060. // Support: Android 2.3
  5061. jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
  5062. function( elem, computed ) {
  5063. if ( computed ) {
  5064. // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
  5065. // Work around by temporarily setting element display to inline-block
  5066. return jQuery.swap( elem, { "display": "inline-block" },
  5067. curCSS, [ elem, "marginRight" ] );
  5068. }
  5069. }
  5070. );
  5071. // These hooks are used by animate to expand properties
  5072. jQuery.each({
  5073. margin: "",
  5074. padding: "",
  5075. border: "Width"
  5076. }, function( prefix, suffix ) {
  5077. jQuery.cssHooks[ prefix + suffix ] = {
  5078. expand: function( value ) {
  5079. var i = 0,
  5080. expanded = {},
  5081. // assumes a single number if not a string
  5082. parts = typeof value === "string" ? value.split(" ") : [ value ];
  5083. for ( ; i < 4; i++ ) {
  5084. expanded[ prefix + cssExpand[ i ] + suffix ] =
  5085. parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
  5086. }
  5087. return expanded;
  5088. }
  5089. };
  5090. if ( !rmargin.test( prefix ) ) {
  5091. jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
  5092. }
  5093. });
  5094. jQuery.fn.extend({
  5095. css: function( name, value ) {
  5096. return access( this, function( elem, name, value ) {
  5097. var styles, len,
  5098. map = {},
  5099. i = 0;
  5100. if ( jQuery.isArray( name ) ) {
  5101. styles = getStyles( elem );
  5102. len = name.length;
  5103. for ( ; i < len; i++ ) {
  5104. map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
  5105. }
  5106. return map;
  5107. }
  5108. return value !== undefined ?
  5109. jQuery.style( elem, name, value ) :
  5110. jQuery.css( elem, name );
  5111. }, name, value, arguments.length > 1 );
  5112. },
  5113. show: function() {
  5114. return showHide( this, true );
  5115. },
  5116. hide: function() {
  5117. return showHide( this );
  5118. },
  5119. toggle: function( state ) {
  5120. if ( typeof state === "boolean" ) {
  5121. return state ? this.show() : this.hide();
  5122. }
  5123. return this.each(function() {
  5124. if ( isHidden( this ) ) {
  5125. jQuery( this ).show();
  5126. } else {
  5127. jQuery( this ).hide();
  5128. }
  5129. });
  5130. }
  5131. });
  5132. function Tween( elem, options, prop, end, easing ) {
  5133. return new Tween.prototype.init( elem, options, prop, end, easing );
  5134. }
  5135. jQuery.Tween = Tween;
  5136. Tween.prototype = {
  5137. constructor: Tween,
  5138. init: function( elem, options, prop, end, easing, unit ) {
  5139. this.elem = elem;
  5140. this.prop = prop;
  5141. this.easing = easing || "swing";
  5142. this.options = options;
  5143. this.start = this.now = this.cur();
  5144. this.end = end;
  5145. this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
  5146. },
  5147. cur: function() {
  5148. var hooks = Tween.propHooks[ this.prop ];
  5149. return hooks && hooks.get ?
  5150. hooks.get( this ) :
  5151. Tween.propHooks._default.get( this );
  5152. },
  5153. run: function( percent ) {
  5154. var eased,
  5155. hooks = Tween.propHooks[ this.prop ];
  5156. if ( this.options.duration ) {
  5157. this.pos = eased = jQuery.easing[ this.easing ](
  5158. percent, this.options.duration * percent, 0, 1, this.options.duration
  5159. );
  5160. } else {
  5161. this.pos = eased = percent;
  5162. }
  5163. this.now = ( this.end - this.start ) * eased + this.start;
  5164. if ( this.options.step ) {
  5165. this.options.step.call( this.elem, this.now, this );
  5166. }
  5167. if ( hooks && hooks.set ) {
  5168. hooks.set( this );
  5169. } else {
  5170. Tween.propHooks._default.set( this );
  5171. }
  5172. return this;
  5173. }
  5174. };
  5175. Tween.prototype.init.prototype = Tween.prototype;
  5176. Tween.propHooks = {
  5177. _default: {
  5178. get: function( tween ) {
  5179. var result;
  5180. if ( tween.elem[ tween.prop ] != null &&
  5181. (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
  5182. return tween.elem[ tween.prop ];
  5183. }
  5184. // passing an empty string as a 3rd parameter to .css will automatically
  5185. // attempt a parseFloat and fallback to a string if the parse fails
  5186. // so, simple values such as "10px" are parsed to Float.
  5187. // complex values such as "rotate(1rad)" are returned as is.
  5188. result = jQuery.css( tween.elem, tween.prop, "" );
  5189. // Empty strings, null, undefined and "auto" are converted to 0.
  5190. return !result || result === "auto" ? 0 : result;
  5191. },
  5192. set: function( tween ) {
  5193. // use step hook for back compat - use cssHook if its there - use .style if its
  5194. // available and use plain properties where available
  5195. if ( jQuery.fx.step[ tween.prop ] ) {
  5196. jQuery.fx.step[ tween.prop ]( tween );
  5197. } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
  5198. jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
  5199. } else {
  5200. tween.elem[ tween.prop ] = tween.now;
  5201. }
  5202. }
  5203. }
  5204. };
  5205. // Support: IE9
  5206. // Panic based approach to setting things on disconnected nodes
  5207. Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
  5208. set: function( tween ) {
  5209. if ( tween.elem.nodeType && tween.elem.parentNode ) {
  5210. tween.elem[ tween.prop ] = tween.now;
  5211. }
  5212. }
  5213. };
  5214. jQuery.easing = {
  5215. linear: function( p ) {
  5216. return p;
  5217. },
  5218. swing: function( p ) {
  5219. return 0.5 - Math.cos( p * Math.PI ) / 2;
  5220. }
  5221. };
  5222. jQuery.fx = Tween.prototype.init;
  5223. // Back Compat <1.8 extension point
  5224. jQuery.fx.step = {};
  5225. var
  5226. fxNow, timerId,
  5227. rfxtypes = /^(?:toggle|show|hide)$/,
  5228. rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
  5229. rrun = /queueHooks$/,
  5230. animationPrefilters = [ defaultPrefilter ],
  5231. tweeners = {
  5232. "*": [ function( prop, value ) {
  5233. var tween = this.createTween( prop, value ),
  5234. target = tween.cur(),
  5235. parts = rfxnum.exec( value ),
  5236. unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
  5237. // Starting value computation is required for potential unit mismatches
  5238. start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
  5239. rfxnum.exec( jQuery.css( tween.elem, prop ) ),
  5240. scale = 1,
  5241. maxIterations = 20;
  5242. if ( start && start[ 3 ] !== unit ) {
  5243. // Trust units reported by jQuery.css
  5244. unit = unit || start[ 3 ];
  5245. // Make sure we update the tween properties later on
  5246. parts = parts || [];
  5247. // Iteratively approximate from a nonzero starting point
  5248. start = +target || 1;
  5249. do {
  5250. // If previous iteration zeroed out, double until we get *something*
  5251. // Use a string for doubling factor so we don't accidentally see scale as unchanged below
  5252. scale = scale || ".5";
  5253. // Adjust and apply
  5254. start = start / scale;
  5255. jQuery.style( tween.elem, prop, start + unit );
  5256. // Update scale, tolerating zero or NaN from tween.cur()
  5257. // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
  5258. } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
  5259. }
  5260. // Update tween properties
  5261. if ( parts ) {
  5262. start = tween.start = +start || +target || 0;
  5263. tween.unit = unit;
  5264. // If a +=/-= token was provided, we're doing a relative animation
  5265. tween.end = parts[ 1 ] ?
  5266. start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
  5267. +parts[ 2 ];
  5268. }
  5269. return tween;
  5270. } ]
  5271. };
  5272. // Animations created synchronously will run synchronously
  5273. function createFxNow() {
  5274. setTimeout(function() {
  5275. fxNow = undefined;
  5276. });
  5277. return ( fxNow = jQuery.now() );
  5278. }
  5279. // Generate parameters to create a standard animation
  5280. function genFx( type, includeWidth ) {
  5281. var which,
  5282. i = 0,
  5283. attrs = { height: type };
  5284. // if we include width, step value is 1 to do all cssExpand values,
  5285. // if we don't include width, step value is 2 to skip over Left and Right
  5286. includeWidth = includeWidth ? 1 : 0;
  5287. for ( ; i < 4 ; i += 2 - includeWidth ) {
  5288. which = cssExpand[ i ];
  5289. attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
  5290. }
  5291. if ( includeWidth ) {
  5292. attrs.opacity = attrs.width = type;
  5293. }
  5294. return attrs;
  5295. }
  5296. function createTween( value, prop, animation ) {
  5297. var tween,
  5298. collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
  5299. index = 0,
  5300. length = collection.length;
  5301. for ( ; index < length; index++ ) {
  5302. if ( (tween = collection[ index ].call( animation, prop, value )) ) {
  5303. // we're done with this property
  5304. return tween;
  5305. }
  5306. }
  5307. }
  5308. function defaultPrefilter( elem, props, opts ) {
  5309. /* jshint validthis: true */
  5310. var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
  5311. anim = this,
  5312. orig = {},
  5313. style = elem.style,
  5314. hidden = elem.nodeType && isHidden( elem ),
  5315. dataShow = data_priv.get( elem, "fxshow" );
  5316. // handle queue: false promises
  5317. if ( !opts.queue ) {
  5318. hooks = jQuery._queueHooks( elem, "fx" );
  5319. if ( hooks.unqueued == null ) {
  5320. hooks.unqueued = 0;
  5321. oldfire = hooks.empty.fire;
  5322. hooks.empty.fire = function() {
  5323. if ( !hooks.unqueued ) {
  5324. oldfire();
  5325. }
  5326. };
  5327. }
  5328. hooks.unqueued++;
  5329. anim.always(function() {
  5330. // doing this makes sure that the complete handler will be called
  5331. // before this completes
  5332. anim.always(function() {
  5333. hooks.unqueued--;
  5334. if ( !jQuery.queue( elem, "fx" ).length ) {
  5335. hooks.empty.fire();
  5336. }
  5337. });
  5338. });
  5339. }
  5340. // height/width overflow pass
  5341. if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
  5342. // Make sure that nothing sneaks out
  5343. // Record all 3 overflow attributes because IE9-10 do not
  5344. // change the overflow attribute when overflowX and
  5345. // overflowY are set to the same value
  5346. opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
  5347. // Set display property to inline-block for height/width
  5348. // animations on inline elements that are having width/height animated
  5349. display = jQuery.css( elem, "display" );
  5350. // Test default display if display is currently "none"
  5351. checkDisplay = display === "none" ?
  5352. data_priv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
  5353. if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
  5354. style.display = "inline-block";
  5355. }
  5356. }
  5357. if ( opts.overflow ) {
  5358. style.overflow = "hidden";
  5359. anim.always(function() {
  5360. style.overflow = opts.overflow[ 0 ];
  5361. style.overflowX = opts.overflow[ 1 ];
  5362. style.overflowY = opts.overflow[ 2 ];
  5363. });
  5364. }
  5365. // show/hide pass
  5366. for ( prop in props ) {
  5367. value = props[ prop ];
  5368. if ( rfxtypes.exec( value ) ) {
  5369. delete props[ prop ];
  5370. toggle = toggle || value === "toggle";
  5371. if ( value === ( hidden ? "hide" : "show" ) ) {
  5372. // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
  5373. if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
  5374. hidden = true;
  5375. } else {
  5376. continue;
  5377. }
  5378. }
  5379. orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
  5380. // Any non-fx value stops us from restoring the original display value
  5381. } else {
  5382. display = undefined;
  5383. }
  5384. }
  5385. if ( !jQuery.isEmptyObject( orig ) ) {
  5386. if ( dataShow ) {
  5387. if ( "hidden" in dataShow ) {
  5388. hidden = dataShow.hidden;
  5389. }
  5390. } else {
  5391. dataShow = data_priv.access( elem, "fxshow", {} );
  5392. }
  5393. // store state if its toggle - enables .stop().toggle() to "reverse"
  5394. if ( toggle ) {
  5395. dataShow.hidden = !hidden;
  5396. }
  5397. if ( hidden ) {
  5398. jQuery( elem ).show();
  5399. } else {
  5400. anim.done(function() {
  5401. jQuery( elem ).hide();
  5402. });
  5403. }
  5404. anim.done(function() {
  5405. var prop;
  5406. data_priv.remove( elem, "fxshow" );
  5407. for ( prop in orig ) {
  5408. jQuery.style( elem, prop, orig[ prop ] );
  5409. }
  5410. });
  5411. for ( prop in orig ) {
  5412. tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
  5413. if ( !( prop in dataShow ) ) {
  5414. dataShow[ prop ] = tween.start;
  5415. if ( hidden ) {
  5416. tween.end = tween.start;
  5417. tween.start = prop === "width" || prop === "height" ? 1 : 0;
  5418. }
  5419. }
  5420. }
  5421. // If this is a noop like .hide().hide(), restore an overwritten display value
  5422. } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
  5423. style.display = display;
  5424. }
  5425. }
  5426. function propFilter( props, specialEasing ) {
  5427. var index, name, easing, value, hooks;
  5428. // camelCase, specialEasing and expand cssHook pass
  5429. for ( index in props ) {
  5430. name = jQuery.camelCase( index );
  5431. easing = specialEasing[ name ];
  5432. value = props[ index ];
  5433. if ( jQuery.isArray( value ) ) {
  5434. easing = value[ 1 ];
  5435. value = props[ index ] = value[ 0 ];
  5436. }
  5437. if ( index !== name ) {
  5438. props[ name ] = value;
  5439. delete props[ index ];
  5440. }
  5441. hooks = jQuery.cssHooks[ name ];
  5442. if ( hooks && "expand" in hooks ) {
  5443. value = hooks.expand( value );
  5444. delete props[ name ];
  5445. // not quite $.extend, this wont overwrite keys already present.
  5446. // also - reusing 'index' from above because we have the correct "name"
  5447. for ( index in value ) {
  5448. if ( !( index in props ) ) {
  5449. props[ index ] = value[ index ];
  5450. specialEasing[ index ] = easing;
  5451. }
  5452. }
  5453. } else {
  5454. specialEasing[ name ] = easing;
  5455. }
  5456. }
  5457. }
  5458. function Animation( elem, properties, options ) {
  5459. var result,
  5460. stopped,
  5461. index = 0,
  5462. length = animationPrefilters.length,
  5463. deferred = jQuery.Deferred().always( function() {
  5464. // don't match elem in the :animated selector
  5465. delete tick.elem;
  5466. }),
  5467. tick = function() {
  5468. if ( stopped ) {
  5469. return false;
  5470. }
  5471. var currentTime = fxNow || createFxNow(),
  5472. remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
  5473. // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
  5474. temp = remaining / animation.duration || 0,
  5475. percent = 1 - temp,
  5476. index = 0,
  5477. length = animation.tweens.length;
  5478. for ( ; index < length ; index++ ) {
  5479. animation.tweens[ index ].run( percent );
  5480. }
  5481. deferred.notifyWith( elem, [ animation, percent, remaining ]);
  5482. if ( percent < 1 && length ) {
  5483. return remaining;
  5484. } else {
  5485. deferred.resolveWith( elem, [ animation ] );
  5486. return false;
  5487. }
  5488. },
  5489. animation = deferred.promise({
  5490. elem: elem,
  5491. props: jQuery.extend( {}, properties ),
  5492. opts: jQuery.extend( true, { specialEasing: {} }, options ),
  5493. originalProperties: properties,
  5494. originalOptions: options,
  5495. startTime: fxNow || createFxNow(),
  5496. duration: options.duration,
  5497. tweens: [],
  5498. createTween: function( prop, end ) {
  5499. var tween = jQuery.Tween( elem, animation.opts, prop, end,
  5500. animation.opts.specialEasing[ prop ] || animation.opts.easing );
  5501. animation.tweens.push( tween );
  5502. return tween;
  5503. },
  5504. stop: function( gotoEnd ) {
  5505. var index = 0,
  5506. // if we are going to the end, we want to run all the tweens
  5507. // otherwise we skip this part
  5508. length = gotoEnd ? animation.tweens.length : 0;
  5509. if ( stopped ) {
  5510. return this;
  5511. }
  5512. stopped = true;
  5513. for ( ; index < length ; index++ ) {
  5514. animation.tweens[ index ].run( 1 );
  5515. }
  5516. // resolve when we played the last frame
  5517. // otherwise, reject
  5518. if ( gotoEnd ) {
  5519. deferred.resolveWith( elem, [ animation, gotoEnd ] );
  5520. } else {
  5521. deferred.rejectWith( elem, [ animation, gotoEnd ] );
  5522. }
  5523. return this;
  5524. }
  5525. }),
  5526. props = animation.props;
  5527. propFilter( props, animation.opts.specialEasing );
  5528. for ( ; index < length ; index++ ) {
  5529. result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
  5530. if ( result ) {
  5531. return result;
  5532. }
  5533. }
  5534. jQuery.map( props, createTween, animation );
  5535. if ( jQuery.isFunction( animation.opts.start ) ) {
  5536. animation.opts.start.call( elem, animation );
  5537. }
  5538. jQuery.fx.timer(
  5539. jQuery.extend( tick, {
  5540. elem: elem,
  5541. anim: animation,
  5542. queue: animation.opts.queue
  5543. })
  5544. );
  5545. // attach callbacks from options
  5546. return animation.progress( animation.opts.progress )
  5547. .done( animation.opts.done, animation.opts.complete )
  5548. .fail( animation.opts.fail )
  5549. .always( animation.opts.always );
  5550. }
  5551. jQuery.Animation = jQuery.extend( Animation, {
  5552. tweener: function( props, callback ) {
  5553. if ( jQuery.isFunction( props ) ) {
  5554. callback = props;
  5555. props = [ "*" ];
  5556. } else {
  5557. props = props.split(" ");
  5558. }
  5559. var prop,
  5560. index = 0,
  5561. length = props.length;
  5562. for ( ; index < length ; index++ ) {
  5563. prop = props[ index ];
  5564. tweeners[ prop ] = tweeners[ prop ] || [];
  5565. tweeners[ prop ].unshift( callback );
  5566. }
  5567. },
  5568. prefilter: function( callback, prepend ) {
  5569. if ( prepend ) {
  5570. animationPrefilters.unshift( callback );
  5571. } else {
  5572. animationPrefilters.push( callback );
  5573. }
  5574. }
  5575. });
  5576. jQuery.speed = function( speed, easing, fn ) {
  5577. var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
  5578. complete: fn || !fn && easing ||
  5579. jQuery.isFunction( speed ) && speed,
  5580. duration: speed,
  5581. easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
  5582. };
  5583. opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
  5584. opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
  5585. // normalize opt.queue - true/undefined/null -> "fx"
  5586. if ( opt.queue == null || opt.queue === true ) {
  5587. opt.queue = "fx";
  5588. }
  5589. // Queueing
  5590. opt.old = opt.complete;
  5591. opt.complete = function() {
  5592. if ( jQuery.isFunction( opt.old ) ) {
  5593. opt.old.call( this );
  5594. }
  5595. if ( opt.queue ) {
  5596. jQuery.dequeue( this, opt.queue );
  5597. }
  5598. };
  5599. return opt;
  5600. };
  5601. jQuery.fn.extend({
  5602. fadeTo: function( speed, to, easing, callback ) {
  5603. // show any hidden elements after setting opacity to 0
  5604. return this.filter( isHidden ).css( "opacity", 0 ).show()
  5605. // animate to the value specified
  5606. .end().animate({ opacity: to }, speed, easing, callback );
  5607. },
  5608. animate: function( prop, speed, easing, callback ) {
  5609. var empty = jQuery.isEmptyObject( prop ),
  5610. optall = jQuery.speed( speed, easing, callback ),
  5611. doAnimation = function() {
  5612. // Operate on a copy of prop so per-property easing won't be lost
  5613. var anim = Animation( this, jQuery.extend( {}, prop ), optall );
  5614. // Empty animations, or finishing resolves immediately
  5615. if ( empty || data_priv.get( this, "finish" ) ) {
  5616. anim.stop( true );
  5617. }
  5618. };
  5619. doAnimation.finish = doAnimation;
  5620. return empty || optall.queue === false ?
  5621. this.each( doAnimation ) :
  5622. this.queue( optall.queue, doAnimation );
  5623. },
  5624. stop: function( type, clearQueue, gotoEnd ) {
  5625. var stopQueue = function( hooks ) {
  5626. var stop = hooks.stop;
  5627. delete hooks.stop;
  5628. stop( gotoEnd );
  5629. };
  5630. if ( typeof type !== "string" ) {
  5631. gotoEnd = clearQueue;
  5632. clearQueue = type;
  5633. type = undefined;
  5634. }
  5635. if ( clearQueue && type !== false ) {
  5636. this.queue( type || "fx", [] );
  5637. }
  5638. return this.each(function() {
  5639. var dequeue = true,
  5640. index = type != null && type + "queueHooks",
  5641. timers = jQuery.timers,
  5642. data = data_priv.get( this );
  5643. if ( index ) {
  5644. if ( data[ index ] && data[ index ].stop ) {
  5645. stopQueue( data[ index ] );
  5646. }
  5647. } else {
  5648. for ( index in data ) {
  5649. if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
  5650. stopQueue( data[ index ] );
  5651. }
  5652. }
  5653. }
  5654. for ( index = timers.length; index--; ) {
  5655. if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
  5656. timers[ index ].anim.stop( gotoEnd );
  5657. dequeue = false;
  5658. timers.splice( index, 1 );
  5659. }
  5660. }
  5661. // start the next in the queue if the last step wasn't forced
  5662. // timers currently will call their complete callbacks, which will dequeue
  5663. // but only if they were gotoEnd
  5664. if ( dequeue || !gotoEnd ) {
  5665. jQuery.dequeue( this, type );
  5666. }
  5667. });
  5668. },
  5669. finish: function( type ) {
  5670. if ( type !== false ) {
  5671. type = type || "fx";
  5672. }
  5673. return this.each(function() {
  5674. var index,
  5675. data = data_priv.get( this ),
  5676. queue = data[ type + "queue" ],
  5677. hooks = data[ type + "queueHooks" ],
  5678. timers = jQuery.timers,
  5679. length = queue ? queue.length : 0;
  5680. // enable finishing flag on private data
  5681. data.finish = true;
  5682. // empty the queue first
  5683. jQuery.queue( this, type, [] );
  5684. if ( hooks && hooks.stop ) {
  5685. hooks.stop.call( this, true );
  5686. }
  5687. // look for any active animations, and finish them
  5688. for ( index = timers.length; index--; ) {
  5689. if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
  5690. timers[ index ].anim.stop( true );
  5691. timers.splice( index, 1 );
  5692. }
  5693. }
  5694. // look for any animations in the old queue and finish them
  5695. for ( index = 0; index < length; index++ ) {
  5696. if ( queue[ index ] && queue[ index ].finish ) {
  5697. queue[ index ].finish.call( this );
  5698. }
  5699. }
  5700. // turn off finishing flag
  5701. delete data.finish;
  5702. });
  5703. }
  5704. });
  5705. jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
  5706. var cssFn = jQuery.fn[ name ];
  5707. jQuery.fn[ name ] = function( speed, easing, callback ) {
  5708. return speed == null || typeof speed === "boolean" ?
  5709. cssFn.apply( this, arguments ) :
  5710. this.animate( genFx( name, true ), speed, easing, callback );
  5711. };
  5712. });
  5713. // Generate shortcuts for custom animations
  5714. jQuery.each({
  5715. slideDown: genFx("show"),
  5716. slideUp: genFx("hide"),
  5717. slideToggle: genFx("toggle"),
  5718. fadeIn: { opacity: "show" },
  5719. fadeOut: { opacity: "hide" },
  5720. fadeToggle: { opacity: "toggle" }
  5721. }, function( name, props ) {
  5722. jQuery.fn[ name ] = function( speed, easing, callback ) {
  5723. return this.animate( props, speed, easing, callback );
  5724. };
  5725. });
  5726. jQuery.timers = [];
  5727. jQuery.fx.tick = function() {
  5728. var timer,
  5729. i = 0,
  5730. timers = jQuery.timers;
  5731. fxNow = jQuery.now();
  5732. for ( ; i < timers.length; i++ ) {
  5733. timer = timers[ i ];
  5734. // Checks the timer has not already been removed
  5735. if ( !timer() && timers[ i ] === timer ) {
  5736. timers.splice( i--, 1 );
  5737. }
  5738. }
  5739. if ( !timers.length ) {
  5740. jQuery.fx.stop();
  5741. }
  5742. fxNow = undefined;
  5743. };
  5744. jQuery.fx.timer = function( timer ) {
  5745. jQuery.timers.push( timer );
  5746. if ( timer() ) {
  5747. jQuery.fx.start();
  5748. } else {
  5749. jQuery.timers.pop();
  5750. }
  5751. };
  5752. jQuery.fx.interval = 13;
  5753. jQuery.fx.start = function() {
  5754. if ( !timerId ) {
  5755. timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
  5756. }
  5757. };
  5758. jQuery.fx.stop = function() {
  5759. clearInterval( timerId );
  5760. timerId = null;
  5761. };
  5762. jQuery.fx.speeds = {
  5763. slow: 600,
  5764. fast: 200,
  5765. // Default speed
  5766. _default: 400
  5767. };
  5768. // Based off of the plugin by Clint Helfers, with permission.
  5769. // http://blindsignals.com/index.php/2009/07/jquery-delay/
  5770. jQuery.fn.delay = function( time, type ) {
  5771. time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
  5772. type = type || "fx";
  5773. return this.queue( type, function( next, hooks ) {
  5774. var timeout = setTimeout( next, time );
  5775. hooks.stop = function() {
  5776. clearTimeout( timeout );
  5777. };
  5778. });
  5779. };
  5780. (function() {
  5781. var input = document.createElement( "input" ),
  5782. select = document.createElement( "select" ),
  5783. opt = select.appendChild( document.createElement( "option" ) );
  5784. input.type = "checkbox";
  5785. // Support: iOS 5.1, Android 4.x, Android 2.3
  5786. // Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere)
  5787. support.checkOn = input.value !== "";
  5788. // Must access the parent to make an option select properly
  5789. // Support: IE9, IE10
  5790. support.optSelected = opt.selected;
  5791. // Make sure that the options inside disabled selects aren't marked as disabled
  5792. // (WebKit marks them as disabled)
  5793. select.disabled = true;
  5794. support.optDisabled = !opt.disabled;
  5795. // Check if an input maintains its value after becoming a radio
  5796. // Support: IE9, IE10
  5797. input = document.createElement( "input" );
  5798. input.value = "t";
  5799. input.type = "radio";
  5800. support.radioValue = input.value === "t";
  5801. })();
  5802. var nodeHook, boolHook,
  5803. attrHandle = jQuery.expr.attrHandle;
  5804. jQuery.fn.extend({
  5805. attr: function( name, value ) {
  5806. return access( this, jQuery.attr, name, value, arguments.length > 1 );
  5807. },
  5808. removeAttr: function( name ) {
  5809. return this.each(function() {
  5810. jQuery.removeAttr( this, name );
  5811. });
  5812. }
  5813. });
  5814. jQuery.extend({
  5815. attr: function( elem, name, value ) {
  5816. var hooks, ret,
  5817. nType = elem.nodeType;
  5818. // don't get/set attributes on text, comment and attribute nodes
  5819. if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
  5820. return;
  5821. }
  5822. // Fallback to prop when attributes are not supported
  5823. if ( typeof elem.getAttribute === strundefined ) {
  5824. return jQuery.prop( elem, name, value );
  5825. }
  5826. // All attributes are lowercase
  5827. // Grab necessary hook if one is defined
  5828. if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
  5829. name = name.toLowerCase();
  5830. hooks = jQuery.attrHooks[ name ] ||
  5831. ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
  5832. }
  5833. if ( value !== undefined ) {
  5834. if ( value === null ) {
  5835. jQuery.removeAttr( elem, name );
  5836. } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
  5837. return ret;
  5838. } else {
  5839. elem.setAttribute( name, value + "" );
  5840. return value;
  5841. }
  5842. } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
  5843. return ret;
  5844. } else {
  5845. ret = jQuery.find.attr( elem, name );
  5846. // Non-existent attributes return null, we normalize to undefined
  5847. return ret == null ?
  5848. undefined :
  5849. ret;
  5850. }
  5851. },
  5852. removeAttr: function( elem, value ) {
  5853. var name, propName,
  5854. i = 0,
  5855. attrNames = value && value.match( rnotwhite );
  5856. if ( attrNames && elem.nodeType === 1 ) {
  5857. while ( (name = attrNames[i++]) ) {
  5858. propName = jQuery.propFix[ name ] || name;
  5859. // Boolean attributes get special treatment (#10870)
  5860. if ( jQuery.expr.match.bool.test( name ) ) {
  5861. // Set corresponding property to false
  5862. elem[ propName ] = false;
  5863. }
  5864. elem.removeAttribute( name );
  5865. }
  5866. }
  5867. },
  5868. attrHooks: {
  5869. type: {
  5870. set: function( elem, value ) {
  5871. if ( !support.radioValue && value === "radio" &&
  5872. jQuery.nodeName( elem, "input" ) ) {
  5873. // Setting the type on a radio button after the value resets the value in IE6-9
  5874. // Reset value to default in case type is set after value during creation
  5875. var val = elem.value;
  5876. elem.setAttribute( "type", value );
  5877. if ( val ) {
  5878. elem.value = val;
  5879. }
  5880. return value;
  5881. }
  5882. }
  5883. }
  5884. }
  5885. });
  5886. // Hooks for boolean attributes
  5887. boolHook = {
  5888. set: function( elem, value, name ) {
  5889. if ( value === false ) {
  5890. // Remove boolean attributes when set to false
  5891. jQuery.removeAttr( elem, name );
  5892. } else {
  5893. elem.setAttribute( name, name );
  5894. }
  5895. return name;
  5896. }
  5897. };
  5898. jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
  5899. var getter = attrHandle[ name ] || jQuery.find.attr;
  5900. attrHandle[ name ] = function( elem, name, isXML ) {
  5901. var ret, handle;
  5902. if ( !isXML ) {
  5903. // Avoid an infinite loop by temporarily removing this function from the getter
  5904. handle = attrHandle[ name ];
  5905. attrHandle[ name ] = ret;
  5906. ret = getter( elem, name, isXML ) != null ?
  5907. name.toLowerCase() :
  5908. null;
  5909. attrHandle[ name ] = handle;
  5910. }
  5911. return ret;
  5912. };
  5913. });
  5914. var rfocusable = /^(?:input|select|textarea|button)$/i;
  5915. jQuery.fn.extend({
  5916. prop: function( name, value ) {
  5917. return access( this, jQuery.prop, name, value, arguments.length > 1 );
  5918. },
  5919. removeProp: function( name ) {
  5920. return this.each(function() {
  5921. delete this[ jQuery.propFix[ name ] || name ];
  5922. });
  5923. }
  5924. });
  5925. jQuery.extend({
  5926. propFix: {
  5927. "for": "htmlFor",
  5928. "class": "className"
  5929. },
  5930. prop: function( elem, name, value ) {
  5931. var ret, hooks, notxml,
  5932. nType = elem.nodeType;
  5933. // don't get/set properties on text, comment and attribute nodes
  5934. if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
  5935. return;
  5936. }
  5937. notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
  5938. if ( notxml ) {
  5939. // Fix name and attach hooks
  5940. name = jQuery.propFix[ name ] || name;
  5941. hooks = jQuery.propHooks[ name ];
  5942. }
  5943. if ( value !== undefined ) {
  5944. return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
  5945. ret :
  5946. ( elem[ name ] = value );
  5947. } else {
  5948. return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
  5949. ret :
  5950. elem[ name ];
  5951. }
  5952. },
  5953. propHooks: {
  5954. tabIndex: {
  5955. get: function( elem ) {
  5956. return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ?
  5957. elem.tabIndex :
  5958. -1;
  5959. }
  5960. }
  5961. }
  5962. });
  5963. // Support: IE9+
  5964. // Selectedness for an option in an optgroup can be inaccurate
  5965. if ( !support.optSelected ) {
  5966. jQuery.propHooks.selected = {
  5967. get: function( elem ) {
  5968. var parent = elem.parentNode;
  5969. if ( parent && parent.parentNode ) {
  5970. parent.parentNode.selectedIndex;
  5971. }
  5972. return null;
  5973. }
  5974. };
  5975. }
  5976. jQuery.each([
  5977. "tabIndex",
  5978. "readOnly",
  5979. "maxLength",
  5980. "cellSpacing",
  5981. "cellPadding",
  5982. "rowSpan",
  5983. "colSpan",
  5984. "useMap",
  5985. "frameBorder",
  5986. "contentEditable"
  5987. ], function() {
  5988. jQuery.propFix[ this.toLowerCase() ] = this;
  5989. });
  5990. var rclass = /[\t\r\n\f]/g;
  5991. jQuery.fn.extend({
  5992. addClass: function( value ) {
  5993. var classes, elem, cur, clazz, j, finalValue,
  5994. proceed = typeof value === "string" && value,
  5995. i = 0,
  5996. len = this.length;
  5997. if ( jQuery.isFunction( value ) ) {
  5998. return this.each(function( j ) {
  5999. jQuery( this ).addClass( value.call( this, j, this.className ) );
  6000. });
  6001. }
  6002. if ( proceed ) {
  6003. // The disjunction here is for better compressibility (see removeClass)
  6004. classes = ( value || "" ).match( rnotwhite ) || [];
  6005. for ( ; i < len; i++ ) {
  6006. elem = this[ i ];
  6007. cur = elem.nodeType === 1 && ( elem.className ?
  6008. ( " " + elem.className + " " ).replace( rclass, " " ) :
  6009. " "
  6010. );
  6011. if ( cur ) {
  6012. j = 0;
  6013. while ( (clazz = classes[j++]) ) {
  6014. if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
  6015. cur += clazz + " ";
  6016. }
  6017. }
  6018. // only assign if different to avoid unneeded rendering.
  6019. finalValue = jQuery.trim( cur );
  6020. if ( elem.className !== finalValue ) {
  6021. elem.className = finalValue;
  6022. }
  6023. }
  6024. }
  6025. }
  6026. return this;
  6027. },
  6028. removeClass: function( value ) {
  6029. var classes, elem, cur, clazz, j, finalValue,
  6030. proceed = arguments.length === 0 || typeof value === "string" && value,
  6031. i = 0,
  6032. len = this.length;
  6033. if ( jQuery.isFunction( value ) ) {
  6034. return this.each(function( j ) {
  6035. jQuery( this ).removeClass( value.call( this, j, this.className ) );
  6036. });
  6037. }
  6038. if ( proceed ) {
  6039. classes = ( value || "" ).match( rnotwhite ) || [];
  6040. for ( ; i < len; i++ ) {
  6041. elem = this[ i ];
  6042. // This expression is here for better compressibility (see addClass)
  6043. cur = elem.nodeType === 1 && ( elem.className ?
  6044. ( " " + elem.className + " " ).replace( rclass, " " ) :
  6045. ""
  6046. );
  6047. if ( cur ) {
  6048. j = 0;
  6049. while ( (clazz = classes[j++]) ) {
  6050. // Remove *all* instances
  6051. while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
  6052. cur = cur.replace( " " + clazz + " ", " " );
  6053. }
  6054. }
  6055. // only assign if different to avoid unneeded rendering.
  6056. finalValue = value ? jQuery.trim( cur ) : "";
  6057. if ( elem.className !== finalValue ) {
  6058. elem.className = finalValue;
  6059. }
  6060. }
  6061. }
  6062. }
  6063. return this;
  6064. },
  6065. toggleClass: function( value, stateVal ) {
  6066. var type = typeof value;
  6067. if ( typeof stateVal === "boolean" && type === "string" ) {
  6068. return stateVal ? this.addClass( value ) : this.removeClass( value );
  6069. }
  6070. if ( jQuery.isFunction( value ) ) {
  6071. return this.each(function( i ) {
  6072. jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
  6073. });
  6074. }
  6075. return this.each(function() {
  6076. if ( type === "string" ) {
  6077. // toggle individual class names
  6078. var className,
  6079. i = 0,
  6080. self = jQuery( this ),
  6081. classNames = value.match( rnotwhite ) || [];
  6082. while ( (className = classNames[ i++ ]) ) {
  6083. // check each className given, space separated list
  6084. if ( self.hasClass( className ) ) {
  6085. self.removeClass( className );
  6086. } else {
  6087. self.addClass( className );
  6088. }
  6089. }
  6090. // Toggle whole class name
  6091. } else if ( type === strundefined || type === "boolean" ) {
  6092. if ( this.className ) {
  6093. // store className if set
  6094. data_priv.set( this, "__className__", this.className );
  6095. }
  6096. // If the element has a class name or if we're passed "false",
  6097. // then remove the whole classname (if there was one, the above saved it).
  6098. // Otherwise bring back whatever was previously saved (if anything),
  6099. // falling back to the empty string if nothing was stored.
  6100. this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
  6101. }
  6102. });
  6103. },
  6104. hasClass: function( selector ) {
  6105. var className = " " + selector + " ",
  6106. i = 0,
  6107. l = this.length;
  6108. for ( ; i < l; i++ ) {
  6109. if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
  6110. return true;
  6111. }
  6112. }
  6113. return false;
  6114. }
  6115. });
  6116. var rreturn = /\r/g;
  6117. jQuery.fn.extend({
  6118. val: function( value ) {
  6119. var hooks, ret, isFunction,
  6120. elem = this[0];
  6121. if ( !arguments.length ) {
  6122. if ( elem ) {
  6123. hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
  6124. if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
  6125. return ret;
  6126. }
  6127. ret = elem.value;
  6128. return typeof ret === "string" ?
  6129. // handle most common string cases
  6130. ret.replace(rreturn, "") :
  6131. // handle cases where value is null/undef or number
  6132. ret == null ? "" : ret;
  6133. }
  6134. return;
  6135. }
  6136. isFunction = jQuery.isFunction( value );
  6137. return this.each(function( i ) {
  6138. var val;
  6139. if ( this.nodeType !== 1 ) {
  6140. return;
  6141. }
  6142. if ( isFunction ) {
  6143. val = value.call( this, i, jQuery( this ).val() );
  6144. } else {
  6145. val = value;
  6146. }
  6147. // Treat null/undefined as ""; convert numbers to string
  6148. if ( val == null ) {
  6149. val = "";
  6150. } else if ( typeof val === "number" ) {
  6151. val += "";
  6152. } else if ( jQuery.isArray( val ) ) {
  6153. val = jQuery.map( val, function( value ) {
  6154. return value == null ? "" : value + "";
  6155. });
  6156. }
  6157. hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
  6158. // If set returns undefined, fall back to normal setting
  6159. if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
  6160. this.value = val;
  6161. }
  6162. });
  6163. }
  6164. });
  6165. jQuery.extend({
  6166. valHooks: {
  6167. option: {
  6168. get: function( elem ) {
  6169. var val = jQuery.find.attr( elem, "value" );
  6170. return val != null ?
  6171. val :
  6172. // Support: IE10-11+
  6173. // option.text throws exceptions (#14686, #14858)
  6174. jQuery.trim( jQuery.text( elem ) );
  6175. }
  6176. },
  6177. select: {
  6178. get: function( elem ) {
  6179. var value, option,
  6180. options = elem.options,
  6181. index = elem.selectedIndex,
  6182. one = elem.type === "select-one" || index < 0,
  6183. values = one ? null : [],
  6184. max = one ? index + 1 : options.length,
  6185. i = index < 0 ?
  6186. max :
  6187. one ? index : 0;
  6188. // Loop through all the selected options
  6189. for ( ; i < max; i++ ) {
  6190. option = options[ i ];
  6191. // IE6-9 doesn't update selected after form reset (#2551)
  6192. if ( ( option.selected || i === index ) &&
  6193. // Don't return options that are disabled or in a disabled optgroup
  6194. ( support.optDisabled ? !option.disabled : option.getAttribute( "disabled" ) === null ) &&
  6195. ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
  6196. // Get the specific value for the option
  6197. value = jQuery( option ).val();
  6198. // We don't need an array for one selects
  6199. if ( one ) {
  6200. return value;
  6201. }
  6202. // Multi-Selects return an array
  6203. values.push( value );
  6204. }
  6205. }
  6206. return values;
  6207. },
  6208. set: function( elem, value ) {
  6209. var optionSet, option,
  6210. options = elem.options,
  6211. values = jQuery.makeArray( value ),
  6212. i = options.length;
  6213. while ( i-- ) {
  6214. option = options[ i ];
  6215. if ( (option.selected = jQuery.inArray( option.value, values ) >= 0) ) {
  6216. optionSet = true;
  6217. }
  6218. }
  6219. // force browsers to behave consistently when non-matching value is set
  6220. if ( !optionSet ) {
  6221. elem.selectedIndex = -1;
  6222. }
  6223. return values;
  6224. }
  6225. }
  6226. }
  6227. });
  6228. // Radios and checkboxes getter/setter
  6229. jQuery.each([ "radio", "checkbox" ], function() {
  6230. jQuery.valHooks[ this ] = {
  6231. set: function( elem, value ) {
  6232. if ( jQuery.isArray( value ) ) {
  6233. return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
  6234. }
  6235. }
  6236. };
  6237. if ( !support.checkOn ) {
  6238. jQuery.valHooks[ this ].get = function( elem ) {
  6239. // Support: Webkit
  6240. // "" is returned instead of "on" if a value isn't specified
  6241. return elem.getAttribute("value") === null ? "on" : elem.value;
  6242. };
  6243. }
  6244. });
  6245. // Return jQuery for attributes-only inclusion
  6246. jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
  6247. "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
  6248. "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
  6249. // Handle event binding
  6250. jQuery.fn[ name ] = function( data, fn ) {
  6251. return arguments.length > 0 ?
  6252. this.on( name, null, data, fn ) :
  6253. this.trigger( name );
  6254. };
  6255. });
  6256. jQuery.fn.extend({
  6257. hover: function( fnOver, fnOut ) {
  6258. return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
  6259. },
  6260. bind: function( types, data, fn ) {
  6261. return this.on( types, null, data, fn );
  6262. },
  6263. unbind: function( types, fn ) {
  6264. return this.off( types, null, fn );
  6265. },
  6266. delegate: function( selector, types, data, fn ) {
  6267. return this.on( types, selector, data, fn );
  6268. },
  6269. undelegate: function( selector, types, fn ) {
  6270. // ( namespace ) or ( selector, types [, fn] )
  6271. return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
  6272. }
  6273. });
  6274. var nonce = jQuery.now();
  6275. var rquery = (/\?/);
  6276. // Support: Android 2.3
  6277. // Workaround failure to string-cast null input
  6278. jQuery.parseJSON = function( data ) {
  6279. return JSON.parse( data + "" );
  6280. };
  6281. // Cross-browser xml parsing
  6282. jQuery.parseXML = function( data ) {
  6283. var xml, tmp;
  6284. if ( !data || typeof data !== "string" ) {
  6285. return null;
  6286. }
  6287. // Support: IE9
  6288. try {
  6289. tmp = new DOMParser();
  6290. xml = tmp.parseFromString( data, "text/xml" );
  6291. } catch ( e ) {
  6292. xml = undefined;
  6293. }
  6294. if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
  6295. jQuery.error( "Invalid XML: " + data );
  6296. }
  6297. return xml;
  6298. };
  6299. var
  6300. // Document location
  6301. ajaxLocParts,
  6302. ajaxLocation,
  6303. rhash = /#.*$/,
  6304. rts = /([?&])_=[^&]*/,
  6305. rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
  6306. // #7653, #8125, #8152: local protocol detection
  6307. rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
  6308. rnoContent = /^(?:GET|HEAD)$/,
  6309. rprotocol = /^\/\//,
  6310. rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
  6311. /* Prefilters
  6312. * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
  6313. * 2) These are called:
  6314. * - BEFORE asking for a transport
  6315. * - AFTER param serialization (s.data is a string if s.processData is true)
  6316. * 3) key is the dataType
  6317. * 4) the catchall symbol "*" can be used
  6318. * 5) execution will start with transport dataType and THEN continue down to "*" if needed
  6319. */
  6320. prefilters = {},
  6321. /* Transports bindings
  6322. * 1) key is the dataType
  6323. * 2) the catchall symbol "*" can be used
  6324. * 3) selection will start with transport dataType and THEN go to "*" if needed
  6325. */
  6326. transports = {},
  6327. // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
  6328. allTypes = "*/".concat("*");
  6329. // #8138, IE may throw an exception when accessing
  6330. // a field from window.location if document.domain has been set
  6331. try {
  6332. ajaxLocation = location.href;
  6333. } catch( e ) {
  6334. // Use the href attribute of an A element
  6335. // since IE will modify it given document.location
  6336. ajaxLocation = document.createElement( "a" );
  6337. ajaxLocation.href = "";
  6338. ajaxLocation = ajaxLocation.href;
  6339. }
  6340. // Segment location into parts
  6341. ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
  6342. // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
  6343. function addToPrefiltersOrTransports( structure ) {
  6344. // dataTypeExpression is optional and defaults to "*"
  6345. return function( dataTypeExpression, func ) {
  6346. if ( typeof dataTypeExpression !== "string" ) {
  6347. func = dataTypeExpression;
  6348. dataTypeExpression = "*";
  6349. }
  6350. var dataType,
  6351. i = 0,
  6352. dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
  6353. if ( jQuery.isFunction( func ) ) {
  6354. // For each dataType in the dataTypeExpression
  6355. while ( (dataType = dataTypes[i++]) ) {
  6356. // Prepend if requested
  6357. if ( dataType[0] === "+" ) {
  6358. dataType = dataType.slice( 1 ) || "*";
  6359. (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
  6360. // Otherwise append
  6361. } else {
  6362. (structure[ dataType ] = structure[ dataType ] || []).push( func );
  6363. }
  6364. }
  6365. }
  6366. };
  6367. }
  6368. // Base inspection function for prefilters and transports
  6369. function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
  6370. var inspected = {},
  6371. seekingTransport = ( structure === transports );
  6372. function inspect( dataType ) {
  6373. var selected;
  6374. inspected[ dataType ] = true;
  6375. jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
  6376. var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
  6377. if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
  6378. options.dataTypes.unshift( dataTypeOrTransport );
  6379. inspect( dataTypeOrTransport );
  6380. return false;
  6381. } else if ( seekingTransport ) {
  6382. return !( selected = dataTypeOrTransport );
  6383. }
  6384. });
  6385. return selected;
  6386. }
  6387. return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
  6388. }
  6389. // A special extend for ajax options
  6390. // that takes "flat" options (not to be deep extended)
  6391. // Fixes #9887
  6392. function ajaxExtend( target, src ) {
  6393. var key, deep,
  6394. flatOptions = jQuery.ajaxSettings.flatOptions || {};
  6395. for ( key in src ) {
  6396. if ( src[ key ] !== undefined ) {
  6397. ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
  6398. }
  6399. }
  6400. if ( deep ) {
  6401. jQuery.extend( true, target, deep );
  6402. }
  6403. return target;
  6404. }
  6405. /* Handles responses to an ajax request:
  6406. * - finds the right dataType (mediates between content-type and expected dataType)
  6407. * - returns the corresponding response
  6408. */
  6409. function ajaxHandleResponses( s, jqXHR, responses ) {
  6410. var ct, type, finalDataType, firstDataType,
  6411. contents = s.contents,
  6412. dataTypes = s.dataTypes;
  6413. // Remove auto dataType and get content-type in the process
  6414. while ( dataTypes[ 0 ] === "*" ) {
  6415. dataTypes.shift();
  6416. if ( ct === undefined ) {
  6417. ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
  6418. }
  6419. }
  6420. // Check if we're dealing with a known content-type
  6421. if ( ct ) {
  6422. for ( type in contents ) {
  6423. if ( contents[ type ] && contents[ type ].test( ct ) ) {
  6424. dataTypes.unshift( type );
  6425. break;
  6426. }
  6427. }
  6428. }
  6429. // Check to see if we have a response for the expected dataType
  6430. if ( dataTypes[ 0 ] in responses ) {
  6431. finalDataType = dataTypes[ 0 ];
  6432. } else {
  6433. // Try convertible dataTypes
  6434. for ( type in responses ) {
  6435. if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
  6436. finalDataType = type;
  6437. break;
  6438. }
  6439. if ( !firstDataType ) {
  6440. firstDataType = type;
  6441. }
  6442. }
  6443. // Or just use first one
  6444. finalDataType = finalDataType || firstDataType;
  6445. }
  6446. // If we found a dataType
  6447. // We add the dataType to the list if needed
  6448. // and return the corresponding response
  6449. if ( finalDataType ) {
  6450. if ( finalDataType !== dataTypes[ 0 ] ) {
  6451. dataTypes.unshift( finalDataType );
  6452. }
  6453. return responses[ finalDataType ];
  6454. }
  6455. }
  6456. /* Chain conversions given the request and the original response
  6457. * Also sets the responseXXX fields on the jqXHR instance
  6458. */
  6459. function ajaxConvert( s, response, jqXHR, isSuccess ) {
  6460. var conv2, current, conv, tmp, prev,
  6461. converters = {},
  6462. // Work with a copy of dataTypes in case we need to modify it for conversion
  6463. dataTypes = s.dataTypes.slice();
  6464. // Create converters map with lowercased keys
  6465. if ( dataTypes[ 1 ] ) {
  6466. for ( conv in s.converters ) {
  6467. converters[ conv.toLowerCase() ] = s.converters[ conv ];
  6468. }
  6469. }
  6470. current = dataTypes.shift();
  6471. // Convert to each sequential dataType
  6472. while ( current ) {
  6473. if ( s.responseFields[ current ] ) {
  6474. jqXHR[ s.responseFields[ current ] ] = response;
  6475. }
  6476. // Apply the dataFilter if provided
  6477. if ( !prev && isSuccess && s.dataFilter ) {
  6478. response = s.dataFilter( response, s.dataType );
  6479. }
  6480. prev = current;
  6481. current = dataTypes.shift();
  6482. if ( current ) {
  6483. // There's only work to do if current dataType is non-auto
  6484. if ( current === "*" ) {
  6485. current = prev;
  6486. // Convert response if prev dataType is non-auto and differs from current
  6487. } else if ( prev !== "*" && prev !== current ) {
  6488. // Seek a direct converter
  6489. conv = converters[ prev + " " + current ] || converters[ "* " + current ];
  6490. // If none found, seek a pair
  6491. if ( !conv ) {
  6492. for ( conv2 in converters ) {
  6493. // If conv2 outputs current
  6494. tmp = conv2.split( " " );
  6495. if ( tmp[ 1 ] === current ) {
  6496. // If prev can be converted to accepted input
  6497. conv = converters[ prev + " " + tmp[ 0 ] ] ||
  6498. converters[ "* " + tmp[ 0 ] ];
  6499. if ( conv ) {
  6500. // Condense equivalence converters
  6501. if ( conv === true ) {
  6502. conv = converters[ conv2 ];
  6503. // Otherwise, insert the intermediate dataType
  6504. } else if ( converters[ conv2 ] !== true ) {
  6505. current = tmp[ 0 ];
  6506. dataTypes.unshift( tmp[ 1 ] );
  6507. }
  6508. break;
  6509. }
  6510. }
  6511. }
  6512. }
  6513. // Apply converter (if not an equivalence)
  6514. if ( conv !== true ) {
  6515. // Unless errors are allowed to bubble, catch and return them
  6516. if ( conv && s[ "throws" ] ) {
  6517. response = conv( response );
  6518. } else {
  6519. try {
  6520. response = conv( response );
  6521. } catch ( e ) {
  6522. return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
  6523. }
  6524. }
  6525. }
  6526. }
  6527. }
  6528. }
  6529. return { state: "success", data: response };
  6530. }
  6531. jQuery.extend({
  6532. // Counter for holding the number of active queries
  6533. active: 0,
  6534. // Last-Modified header cache for next request
  6535. lastModified: {},
  6536. etag: {},
  6537. ajaxSettings: {
  6538. url: ajaxLocation,
  6539. type: "GET",
  6540. isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
  6541. global: true,
  6542. processData: true,
  6543. async: true,
  6544. contentType: "application/x-www-form-urlencoded; charset=UTF-8",
  6545. /*
  6546. timeout: 0,
  6547. data: null,
  6548. dataType: null,
  6549. username: null,
  6550. password: null,
  6551. cache: null,
  6552. throws: false,
  6553. traditional: false,
  6554. headers: {},
  6555. */
  6556. accepts: {
  6557. "*": allTypes,
  6558. text: "text/plain",
  6559. html: "text/html",
  6560. xml: "application/xml, text/xml",
  6561. json: "application/json, text/javascript"
  6562. },
  6563. contents: {
  6564. xml: /xml/,
  6565. html: /html/,
  6566. json: /json/
  6567. },
  6568. responseFields: {
  6569. xml: "responseXML",
  6570. text: "responseText",
  6571. json: "responseJSON"
  6572. },
  6573. // Data converters
  6574. // Keys separate source (or catchall "*") and destination types with a single space
  6575. converters: {
  6576. // Convert anything to text
  6577. "* text": String,
  6578. // Text to html (true = no transformation)
  6579. "text html": true,
  6580. // Evaluate text as a json expression
  6581. "text json": jQuery.parseJSON,
  6582. // Parse text as xml
  6583. "text xml": jQuery.parseXML
  6584. },
  6585. // For options that shouldn't be deep extended:
  6586. // you can add your own custom options here if
  6587. // and when you create one that shouldn't be
  6588. // deep extended (see ajaxExtend)
  6589. flatOptions: {
  6590. url: true,
  6591. context: true
  6592. }
  6593. },
  6594. // Creates a full fledged settings object into target
  6595. // with both ajaxSettings and settings fields.
  6596. // If target is omitted, writes into ajaxSettings.
  6597. ajaxSetup: function( target, settings ) {
  6598. return settings ?
  6599. // Building a settings object
  6600. ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
  6601. // Extending ajaxSettings
  6602. ajaxExtend( jQuery.ajaxSettings, target );
  6603. },
  6604. ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
  6605. ajaxTransport: addToPrefiltersOrTransports( transports ),
  6606. // Main method
  6607. ajax: function( url, options ) {
  6608. // If url is an object, simulate pre-1.5 signature
  6609. if ( typeof url === "object" ) {
  6610. options = url;
  6611. url = undefined;
  6612. }
  6613. // Force options to be an object
  6614. options = options || {};
  6615. var transport,
  6616. // URL without anti-cache param
  6617. cacheURL,
  6618. // Response headers
  6619. responseHeadersString,
  6620. responseHeaders,
  6621. // timeout handle
  6622. timeoutTimer,
  6623. // Cross-domain detection vars
  6624. parts,
  6625. // To know if global events are to be dispatched
  6626. fireGlobals,
  6627. // Loop variable
  6628. i,
  6629. // Create the final options object
  6630. s = jQuery.ajaxSetup( {}, options ),
  6631. // Callbacks context
  6632. callbackContext = s.context || s,
  6633. // Context for global events is callbackContext if it is a DOM node or jQuery collection
  6634. globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
  6635. jQuery( callbackContext ) :
  6636. jQuery.event,
  6637. // Deferreds
  6638. deferred = jQuery.Deferred(),
  6639. completeDeferred = jQuery.Callbacks("once memory"),
  6640. // Status-dependent callbacks
  6641. statusCode = s.statusCode || {},
  6642. // Headers (they are sent all at once)
  6643. requestHeaders = {},
  6644. requestHeadersNames = {},
  6645. // The jqXHR state
  6646. state = 0,
  6647. // Default abort message
  6648. strAbort = "canceled",
  6649. // Fake xhr
  6650. jqXHR = {
  6651. readyState: 0,
  6652. // Builds headers hashtable if needed
  6653. getResponseHeader: function( key ) {
  6654. var match;
  6655. if ( state === 2 ) {
  6656. if ( !responseHeaders ) {
  6657. responseHeaders = {};
  6658. while ( (match = rheaders.exec( responseHeadersString )) ) {
  6659. responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
  6660. }
  6661. }
  6662. match = responseHeaders[ key.toLowerCase() ];
  6663. }
  6664. return match == null ? null : match;
  6665. },
  6666. // Raw string
  6667. getAllResponseHeaders: function() {
  6668. return state === 2 ? responseHeadersString : null;
  6669. },
  6670. // Caches the header
  6671. setRequestHeader: function( name, value ) {
  6672. var lname = name.toLowerCase();
  6673. if ( !state ) {
  6674. name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
  6675. requestHeaders[ name ] = value;
  6676. }
  6677. return this;
  6678. },
  6679. // Overrides response content-type header
  6680. overrideMimeType: function( type ) {
  6681. if ( !state ) {
  6682. s.mimeType = type;
  6683. }
  6684. return this;
  6685. },
  6686. // Status-dependent callbacks
  6687. statusCode: function( map ) {
  6688. var code;
  6689. if ( map ) {
  6690. if ( state < 2 ) {
  6691. for ( code in map ) {
  6692. // Lazy-add the new callback in a way that preserves old ones
  6693. statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
  6694. }
  6695. } else {
  6696. // Execute the appropriate callbacks
  6697. jqXHR.always( map[ jqXHR.status ] );
  6698. }
  6699. }
  6700. return this;
  6701. },
  6702. // Cancel the request
  6703. abort: function( statusText ) {
  6704. var finalText = statusText || strAbort;
  6705. if ( transport ) {
  6706. transport.abort( finalText );
  6707. }
  6708. done( 0, finalText );
  6709. return this;
  6710. }
  6711. };
  6712. // Attach deferreds
  6713. deferred.promise( jqXHR ).complete = completeDeferred.add;
  6714. jqXHR.success = jqXHR.done;
  6715. jqXHR.error = jqXHR.fail;
  6716. // Remove hash character (#7531: and string promotion)
  6717. // Add protocol if not provided (prefilters might expect it)
  6718. // Handle falsy url in the settings object (#10093: consistency with old signature)
  6719. // We also use the url parameter if available
  6720. s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" )
  6721. .replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
  6722. // Alias method option to type as per ticket #12004
  6723. s.type = options.method || options.type || s.method || s.type;
  6724. // Extract dataTypes list
  6725. s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
  6726. // A cross-domain request is in order when we have a protocol:host:port mismatch
  6727. if ( s.crossDomain == null ) {
  6728. parts = rurl.exec( s.url.toLowerCase() );
  6729. s.crossDomain = !!( parts &&
  6730. ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
  6731. ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
  6732. ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
  6733. );
  6734. }
  6735. // Convert data if not already a string
  6736. if ( s.data && s.processData && typeof s.data !== "string" ) {
  6737. s.data = jQuery.param( s.data, s.traditional );
  6738. }
  6739. // Apply prefilters
  6740. inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
  6741. // If request was aborted inside a prefilter, stop there
  6742. if ( state === 2 ) {
  6743. return jqXHR;
  6744. }
  6745. // We can fire global events as of now if asked to
  6746. fireGlobals = s.global;
  6747. // Watch for a new set of requests
  6748. if ( fireGlobals && jQuery.active++ === 0 ) {
  6749. jQuery.event.trigger("ajaxStart");
  6750. }
  6751. // Uppercase the type
  6752. s.type = s.type.toUpperCase();
  6753. // Determine if request has content
  6754. s.hasContent = !rnoContent.test( s.type );
  6755. // Save the URL in case we're toying with the If-Modified-Since
  6756. // and/or If-None-Match header later on
  6757. cacheURL = s.url;
  6758. // More options handling for requests with no content
  6759. if ( !s.hasContent ) {
  6760. // If data is available, append data to url
  6761. if ( s.data ) {
  6762. cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
  6763. // #9682: remove data so that it's not used in an eventual retry
  6764. delete s.data;
  6765. }
  6766. // Add anti-cache in url if needed
  6767. if ( s.cache === false ) {
  6768. s.url = rts.test( cacheURL ) ?
  6769. // If there is already a '_' parameter, set its value
  6770. cacheURL.replace( rts, "$1_=" + nonce++ ) :
  6771. // Otherwise add one to the end
  6772. cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
  6773. }
  6774. }
  6775. // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  6776. if ( s.ifModified ) {
  6777. if ( jQuery.lastModified[ cacheURL ] ) {
  6778. jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
  6779. }
  6780. if ( jQuery.etag[ cacheURL ] ) {
  6781. jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
  6782. }
  6783. }
  6784. // Set the correct header, if data is being sent
  6785. if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
  6786. jqXHR.setRequestHeader( "Content-Type", s.contentType );
  6787. }
  6788. // Set the Accepts header for the server, depending on the dataType
  6789. jqXHR.setRequestHeader(
  6790. "Accept",
  6791. s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
  6792. s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
  6793. s.accepts[ "*" ]
  6794. );
  6795. // Check for headers option
  6796. for ( i in s.headers ) {
  6797. jqXHR.setRequestHeader( i, s.headers[ i ] );
  6798. }
  6799. // Allow custom headers/mimetypes and early abort
  6800. if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
  6801. // Abort if not done already and return
  6802. return jqXHR.abort();
  6803. }
  6804. // aborting is no longer a cancellation
  6805. strAbort = "abort";
  6806. // Install callbacks on deferreds
  6807. for ( i in { success: 1, error: 1, complete: 1 } ) {
  6808. jqXHR[ i ]( s[ i ] );
  6809. }
  6810. // Get transport
  6811. transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
  6812. // If no transport, we auto-abort
  6813. if ( !transport ) {
  6814. done( -1, "No Transport" );
  6815. } else {
  6816. jqXHR.readyState = 1;
  6817. // Send global event
  6818. if ( fireGlobals ) {
  6819. globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
  6820. }
  6821. // Timeout
  6822. if ( s.async && s.timeout > 0 ) {
  6823. timeoutTimer = setTimeout(function() {
  6824. jqXHR.abort("timeout");
  6825. }, s.timeout );
  6826. }
  6827. try {
  6828. state = 1;
  6829. transport.send( requestHeaders, done );
  6830. } catch ( e ) {
  6831. // Propagate exception as error if not done
  6832. if ( state < 2 ) {
  6833. done( -1, e );
  6834. // Simply rethrow otherwise
  6835. } else {
  6836. throw e;
  6837. }
  6838. }
  6839. }
  6840. // Callback for when everything is done
  6841. function done( status, nativeStatusText, responses, headers ) {
  6842. var isSuccess, success, error, response, modified,
  6843. statusText = nativeStatusText;
  6844. // Called once
  6845. if ( state === 2 ) {
  6846. return;
  6847. }
  6848. // State is "done" now
  6849. state = 2;
  6850. // Clear timeout if it exists
  6851. if ( timeoutTimer ) {
  6852. clearTimeout( timeoutTimer );
  6853. }
  6854. // Dereference transport for early garbage collection
  6855. // (no matter how long the jqXHR object will be used)
  6856. transport = undefined;
  6857. // Cache response headers
  6858. responseHeadersString = headers || "";
  6859. // Set readyState
  6860. jqXHR.readyState = status > 0 ? 4 : 0;
  6861. // Determine if successful
  6862. isSuccess = status >= 200 && status < 300 || status === 304;
  6863. // Get response data
  6864. if ( responses ) {
  6865. response = ajaxHandleResponses( s, jqXHR, responses );
  6866. }
  6867. // Convert no matter what (that way responseXXX fields are always set)
  6868. response = ajaxConvert( s, response, jqXHR, isSuccess );
  6869. // If successful, handle type chaining
  6870. if ( isSuccess ) {
  6871. // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  6872. if ( s.ifModified ) {
  6873. modified = jqXHR.getResponseHeader("Last-Modified");
  6874. if ( modified ) {
  6875. jQuery.lastModified[ cacheURL ] = modified;
  6876. }
  6877. modified = jqXHR.getResponseHeader("etag");
  6878. if ( modified ) {
  6879. jQuery.etag[ cacheURL ] = modified;
  6880. }
  6881. }
  6882. // if no content
  6883. if ( status === 204 || s.type === "HEAD" ) {
  6884. statusText = "nocontent";
  6885. // if not modified
  6886. } else if ( status === 304 ) {
  6887. statusText = "notmodified";
  6888. // If we have data, let's convert it
  6889. } else {
  6890. statusText = response.state;
  6891. success = response.data;
  6892. error = response.error;
  6893. isSuccess = !error;
  6894. }
  6895. } else {
  6896. // We extract error from statusText
  6897. // then normalize statusText and status for non-aborts
  6898. error = statusText;
  6899. if ( status || !statusText ) {
  6900. statusText = "error";
  6901. if ( status < 0 ) {
  6902. status = 0;
  6903. }
  6904. }
  6905. }
  6906. // Set data for the fake xhr object
  6907. jqXHR.status = status;
  6908. jqXHR.statusText = ( nativeStatusText || statusText ) + "";
  6909. // Success/Error
  6910. if ( isSuccess ) {
  6911. deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
  6912. } else {
  6913. deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
  6914. }
  6915. // Status-dependent callbacks
  6916. jqXHR.statusCode( statusCode );
  6917. statusCode = undefined;
  6918. if ( fireGlobals ) {
  6919. globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
  6920. [ jqXHR, s, isSuccess ? success : error ] );
  6921. }
  6922. // Complete
  6923. completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
  6924. if ( fireGlobals ) {
  6925. globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
  6926. // Handle the global AJAX counter
  6927. if ( !( --jQuery.active ) ) {
  6928. jQuery.event.trigger("ajaxStop");
  6929. }
  6930. }
  6931. }
  6932. return jqXHR;
  6933. },
  6934. getJSON: function( url, data, callback ) {
  6935. return jQuery.get( url, data, callback, "json" );
  6936. },
  6937. getScript: function( url, callback ) {
  6938. return jQuery.get( url, undefined, callback, "script" );
  6939. }
  6940. });
  6941. jQuery.each( [ "get", "post" ], function( i, method ) {
  6942. jQuery[ method ] = function( url, data, callback, type ) {
  6943. // shift arguments if data argument was omitted
  6944. if ( jQuery.isFunction( data ) ) {
  6945. type = type || callback;
  6946. callback = data;
  6947. data = undefined;
  6948. }
  6949. return jQuery.ajax({
  6950. url: url,
  6951. type: method,
  6952. dataType: type,
  6953. data: data,
  6954. success: callback
  6955. });
  6956. };
  6957. });
  6958. // Attach a bunch of functions for handling common AJAX events
  6959. jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
  6960. jQuery.fn[ type ] = function( fn ) {
  6961. return this.on( type, fn );
  6962. };
  6963. });
  6964. jQuery._evalUrl = function( url ) {
  6965. return jQuery.ajax({
  6966. url: url,
  6967. type: "GET",
  6968. dataType: "script",
  6969. async: false,
  6970. global: false,
  6971. "throws": true
  6972. });
  6973. };
  6974. jQuery.fn.extend({
  6975. wrapAll: function( html ) {
  6976. var wrap;
  6977. if ( jQuery.isFunction( html ) ) {
  6978. return this.each(function( i ) {
  6979. jQuery( this ).wrapAll( html.call(this, i) );
  6980. });
  6981. }
  6982. if ( this[ 0 ] ) {
  6983. // The elements to wrap the target around
  6984. wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
  6985. if ( this[ 0 ].parentNode ) {
  6986. wrap.insertBefore( this[ 0 ] );
  6987. }
  6988. wrap.map(function() {
  6989. var elem = this;
  6990. while ( elem.firstElementChild ) {
  6991. elem = elem.firstElementChild;
  6992. }
  6993. return elem;
  6994. }).append( this );
  6995. }
  6996. return this;
  6997. },
  6998. wrapInner: function( html ) {
  6999. if ( jQuery.isFunction( html ) ) {
  7000. return this.each(function( i ) {
  7001. jQuery( this ).wrapInner( html.call(this, i) );
  7002. });
  7003. }
  7004. return this.each(function() {
  7005. var self = jQuery( this ),
  7006. contents = self.contents();
  7007. if ( contents.length ) {
  7008. contents.wrapAll( html );
  7009. } else {
  7010. self.append( html );
  7011. }
  7012. });
  7013. },
  7014. wrap: function( html ) {
  7015. var isFunction = jQuery.isFunction( html );
  7016. return this.each(function( i ) {
  7017. jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
  7018. });
  7019. },
  7020. unwrap: function() {
  7021. return this.parent().each(function() {
  7022. if ( !jQuery.nodeName( this, "body" ) ) {
  7023. jQuery( this ).replaceWith( this.childNodes );
  7024. }
  7025. }).end();
  7026. }
  7027. });
  7028. jQuery.expr.filters.hidden = function( elem ) {
  7029. // Support: Opera <= 12.12
  7030. // Opera reports offsetWidths and offsetHeights less than zero on some elements
  7031. return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
  7032. };
  7033. jQuery.expr.filters.visible = function( elem ) {
  7034. return !jQuery.expr.filters.hidden( elem );
  7035. };
  7036. var r20 = /%20/g,
  7037. rbracket = /\[\]$/,
  7038. rCRLF = /\r?\n/g,
  7039. rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
  7040. rsubmittable = /^(?:input|select|textarea|keygen)/i;
  7041. function buildParams( prefix, obj, traditional, add ) {
  7042. var name;
  7043. if ( jQuery.isArray( obj ) ) {
  7044. // Serialize array item.
  7045. jQuery.each( obj, function( i, v ) {
  7046. if ( traditional || rbracket.test( prefix ) ) {
  7047. // Treat each array item as a scalar.
  7048. add( prefix, v );
  7049. } else {
  7050. // Item is non-scalar (array or object), encode its numeric index.
  7051. buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
  7052. }
  7053. });
  7054. } else if ( !traditional && jQuery.type( obj ) === "object" ) {
  7055. // Serialize object item.
  7056. for ( name in obj ) {
  7057. buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
  7058. }
  7059. } else {
  7060. // Serialize scalar item.
  7061. add( prefix, obj );
  7062. }
  7063. }
  7064. // Serialize an array of form elements or a set of
  7065. // key/values into a query string
  7066. jQuery.param = function( a, traditional ) {
  7067. var prefix,
  7068. s = [],
  7069. add = function( key, value ) {
  7070. // If value is a function, invoke it and return its value
  7071. value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
  7072. s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
  7073. };
  7074. // Set traditional to true for jQuery <= 1.3.2 behavior.
  7075. if ( traditional === undefined ) {
  7076. traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
  7077. }
  7078. // If an array was passed in, assume that it is an array of form elements.
  7079. if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
  7080. // Serialize the form elements
  7081. jQuery.each( a, function() {
  7082. add( this.name, this.value );
  7083. });
  7084. } else {
  7085. // If traditional, encode the "old" way (the way 1.3.2 or older
  7086. // did it), otherwise encode params recursively.
  7087. for ( prefix in a ) {
  7088. buildParams( prefix, a[ prefix ], traditional, add );
  7089. }
  7090. }
  7091. // Return the resulting serialization
  7092. return s.join( "&" ).replace( r20, "+" );
  7093. };
  7094. jQuery.fn.extend({
  7095. serialize: function() {
  7096. return jQuery.param( this.serializeArray() );
  7097. },
  7098. serializeArray: function() {
  7099. return this.map(function() {
  7100. // Can add propHook for "elements" to filter or add form elements
  7101. var elements = jQuery.prop( this, "elements" );
  7102. return elements ? jQuery.makeArray( elements ) : this;
  7103. })
  7104. .filter(function() {
  7105. var type = this.type;
  7106. // Use .is( ":disabled" ) so that fieldset[disabled] works
  7107. return this.name && !jQuery( this ).is( ":disabled" ) &&
  7108. rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
  7109. ( this.checked || !rcheckableType.test( type ) );
  7110. })
  7111. .map(function( i, elem ) {
  7112. var val = jQuery( this ).val();
  7113. return val == null ?
  7114. null :
  7115. jQuery.isArray( val ) ?
  7116. jQuery.map( val, function( val ) {
  7117. return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
  7118. }) :
  7119. { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
  7120. }).get();
  7121. }
  7122. });
  7123. jQuery.ajaxSettings.xhr = function() {
  7124. try {
  7125. return new XMLHttpRequest();
  7126. } catch( e ) {}
  7127. };
  7128. var xhrId = 0,
  7129. xhrCallbacks = {},
  7130. xhrSuccessStatus = {
  7131. // file protocol always yields status code 0, assume 200
  7132. 0: 200,
  7133. // Support: IE9
  7134. // #1450: sometimes IE returns 1223 when it should be 204
  7135. 1223: 204
  7136. },
  7137. xhrSupported = jQuery.ajaxSettings.xhr();
  7138. // Support: IE9
  7139. // Open requests must be manually aborted on unload (#5280)
  7140. if ( window.ActiveXObject ) {
  7141. jQuery( window ).on( "unload", function() {
  7142. for ( var key in xhrCallbacks ) {
  7143. xhrCallbacks[ key ]();
  7144. }
  7145. });
  7146. }
  7147. support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
  7148. support.ajax = xhrSupported = !!xhrSupported;
  7149. jQuery.ajaxTransport(function( options ) {
  7150. var callback;
  7151. // Cross domain only allowed if supported through XMLHttpRequest
  7152. if ( support.cors || xhrSupported && !options.crossDomain ) {
  7153. return {
  7154. send: function( headers, complete ) {
  7155. var i,
  7156. xhr = options.xhr(),
  7157. id = ++xhrId;
  7158. xhr.open( options.type, options.url, options.async, options.username, options.password );
  7159. // Apply custom fields if provided
  7160. if ( options.xhrFields ) {
  7161. for ( i in options.xhrFields ) {
  7162. xhr[ i ] = options.xhrFields[ i ];
  7163. }
  7164. }
  7165. // Override mime type if needed
  7166. if ( options.mimeType && xhr.overrideMimeType ) {
  7167. xhr.overrideMimeType( options.mimeType );
  7168. }
  7169. // X-Requested-With header
  7170. // For cross-domain requests, seeing as conditions for a preflight are
  7171. // akin to a jigsaw puzzle, we simply never set it to be sure.
  7172. // (it can always be set on a per-request basis or even using ajaxSetup)
  7173. // For same-domain requests, won't change header if already provided.
  7174. if ( !options.crossDomain && !headers["X-Requested-With"] ) {
  7175. headers["X-Requested-With"] = "XMLHttpRequest";
  7176. }
  7177. // Set headers
  7178. for ( i in headers ) {
  7179. xhr.setRequestHeader( i, headers[ i ] );
  7180. }
  7181. // Callback
  7182. callback = function( type ) {
  7183. return function() {
  7184. if ( callback ) {
  7185. delete xhrCallbacks[ id ];
  7186. callback = xhr.onload = xhr.onerror = null;
  7187. if ( type === "abort" ) {
  7188. xhr.abort();
  7189. } else if ( type === "error" ) {
  7190. complete(
  7191. // file: protocol always yields status 0; see #8605, #14207
  7192. xhr.status,
  7193. xhr.statusText
  7194. );
  7195. } else {
  7196. complete(
  7197. xhrSuccessStatus[ xhr.status ] || xhr.status,
  7198. xhr.statusText,
  7199. // Support: IE9
  7200. // Accessing binary-data responseText throws an exception
  7201. // (#11426)
  7202. typeof xhr.responseText === "string" ? {
  7203. text: xhr.responseText
  7204. } : undefined,
  7205. xhr.getAllResponseHeaders()
  7206. );
  7207. }
  7208. }
  7209. };
  7210. };
  7211. // Listen to events
  7212. xhr.onload = callback();
  7213. xhr.onerror = callback("error");
  7214. // Create the abort callback
  7215. callback = xhrCallbacks[ id ] = callback("abort");
  7216. try {
  7217. // Do send the request (this may raise an exception)
  7218. xhr.send( options.hasContent && options.data || null );
  7219. } catch ( e ) {
  7220. // #14683: Only rethrow if this hasn't been notified as an error yet
  7221. if ( callback ) {
  7222. throw e;
  7223. }
  7224. }
  7225. },
  7226. abort: function() {
  7227. if ( callback ) {
  7228. callback();
  7229. }
  7230. }
  7231. };
  7232. }
  7233. });
  7234. // Install script dataType
  7235. jQuery.ajaxSetup({
  7236. accepts: {
  7237. script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
  7238. },
  7239. contents: {
  7240. script: /(?:java|ecma)script/
  7241. },
  7242. converters: {
  7243. "text script": function( text ) {
  7244. jQuery.globalEval( text );
  7245. return text;
  7246. }
  7247. }
  7248. });
  7249. // Handle cache's special case and crossDomain
  7250. jQuery.ajaxPrefilter( "script", function( s ) {
  7251. if ( s.cache === undefined ) {
  7252. s.cache = false;
  7253. }
  7254. if ( s.crossDomain ) {
  7255. s.type = "GET";
  7256. }
  7257. });
  7258. // Bind script tag hack transport
  7259. jQuery.ajaxTransport( "script", function( s ) {
  7260. // This transport only deals with cross domain requests
  7261. if ( s.crossDomain ) {
  7262. var script, callback;
  7263. return {
  7264. send: function( _, complete ) {
  7265. script = jQuery("<script>").prop({
  7266. async: true,
  7267. charset: s.scriptCharset,
  7268. src: s.url
  7269. }).on(
  7270. "load error",
  7271. callback = function( evt ) {
  7272. script.remove();
  7273. callback = null;
  7274. if ( evt ) {
  7275. complete( evt.type === "error" ? 404 : 200, evt.type );
  7276. }
  7277. }
  7278. );
  7279. document.head.appendChild( script[ 0 ] );
  7280. },
  7281. abort: function() {
  7282. if ( callback ) {
  7283. callback();
  7284. }
  7285. }
  7286. };
  7287. }
  7288. });
  7289. var oldCallbacks = [],
  7290. rjsonp = /(=)\?(?=&|$)|\?\?/;
  7291. // Default jsonp settings
  7292. jQuery.ajaxSetup({
  7293. jsonp: "callback",
  7294. jsonpCallback: function() {
  7295. var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
  7296. this[ callback ] = true;
  7297. return callback;
  7298. }
  7299. });
  7300. // Detect, normalize options and install callbacks for jsonp requests
  7301. jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
  7302. var callbackName, overwritten, responseContainer,
  7303. jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
  7304. "url" :
  7305. typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
  7306. );
  7307. // Handle iff the expected data type is "jsonp" or we have a parameter to set
  7308. if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
  7309. // Get callback name, remembering preexisting value associated with it
  7310. callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
  7311. s.jsonpCallback() :
  7312. s.jsonpCallback;
  7313. // Insert callback into url or form data
  7314. if ( jsonProp ) {
  7315. s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
  7316. } else if ( s.jsonp !== false ) {
  7317. s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
  7318. }
  7319. // Use data converter to retrieve json after script execution
  7320. s.converters["script json"] = function() {
  7321. if ( !responseContainer ) {
  7322. jQuery.error( callbackName + " was not called" );
  7323. }
  7324. return responseContainer[ 0 ];
  7325. };
  7326. // force json dataType
  7327. s.dataTypes[ 0 ] = "json";
  7328. // Install callback
  7329. overwritten = window[ callbackName ];
  7330. window[ callbackName ] = function() {
  7331. responseContainer = arguments;
  7332. };
  7333. // Clean-up function (fires after converters)
  7334. jqXHR.always(function() {
  7335. // Restore preexisting value
  7336. window[ callbackName ] = overwritten;
  7337. // Save back as free
  7338. if ( s[ callbackName ] ) {
  7339. // make sure that re-using the options doesn't screw things around
  7340. s.jsonpCallback = originalSettings.jsonpCallback;
  7341. // save the callback name for future use
  7342. oldCallbacks.push( callbackName );
  7343. }
  7344. // Call if it was a function and we have a response
  7345. if ( responseContainer && jQuery.isFunction( overwritten ) ) {
  7346. overwritten( responseContainer[ 0 ] );
  7347. }
  7348. responseContainer = overwritten = undefined;
  7349. });
  7350. // Delegate to script
  7351. return "script";
  7352. }
  7353. });
  7354. // data: string of html
  7355. // context (optional): If specified, the fragment will be created in this context, defaults to document
  7356. // keepScripts (optional): If true, will include scripts passed in the html string
  7357. jQuery.parseHTML = function( data, context, keepScripts ) {
  7358. if ( !data || typeof data !== "string" ) {
  7359. return null;
  7360. }
  7361. if ( typeof context === "boolean" ) {
  7362. keepScripts = context;
  7363. context = false;
  7364. }
  7365. context = context || document;
  7366. var parsed = rsingleTag.exec( data ),
  7367. scripts = !keepScripts && [];
  7368. // Single tag
  7369. if ( parsed ) {
  7370. return [ context.createElement( parsed[1] ) ];
  7371. }
  7372. parsed = jQuery.buildFragment( [ data ], context, scripts );
  7373. if ( scripts && scripts.length ) {
  7374. jQuery( scripts ).remove();
  7375. }
  7376. return jQuery.merge( [], parsed.childNodes );
  7377. };
  7378. // Keep a copy of the old load method
  7379. var _load = jQuery.fn.load;
  7380. /**
  7381. * Load a url into a page
  7382. */
  7383. jQuery.fn.load = function( url, params, callback ) {
  7384. if ( typeof url !== "string" && _load ) {
  7385. return _load.apply( this, arguments );
  7386. }
  7387. var selector, type, response,
  7388. self = this,
  7389. off = url.indexOf(" ");
  7390. if ( off >= 0 ) {
  7391. selector = jQuery.trim( url.slice( off ) );
  7392. url = url.slice( 0, off );
  7393. }
  7394. // If it's a function
  7395. if ( jQuery.isFunction( params ) ) {
  7396. // We assume that it's the callback
  7397. callback = params;
  7398. params = undefined;
  7399. // Otherwise, build a param string
  7400. } else if ( params && typeof params === "object" ) {
  7401. type = "POST";
  7402. }
  7403. // If we have elements to modify, make the request
  7404. if ( self.length > 0 ) {
  7405. jQuery.ajax({
  7406. url: url,
  7407. // if "type" variable is undefined, then "GET" method will be used
  7408. type: type,
  7409. dataType: "html",
  7410. data: params
  7411. }).done(function( responseText ) {
  7412. // Save response for use in complete callback
  7413. response = arguments;
  7414. self.html( selector ?
  7415. // If a selector was specified, locate the right elements in a dummy div
  7416. // Exclude scripts to avoid IE 'Permission Denied' errors
  7417. jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
  7418. // Otherwise use the full result
  7419. responseText );
  7420. }).complete( callback && function( jqXHR, status ) {
  7421. self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
  7422. });
  7423. }
  7424. return this;
  7425. };
  7426. jQuery.expr.filters.animated = function( elem ) {
  7427. return jQuery.grep(jQuery.timers, function( fn ) {
  7428. return elem === fn.elem;
  7429. }).length;
  7430. };
  7431. var docElem = window.document.documentElement;
  7432. /**
  7433. * Gets a window from an element
  7434. */
  7435. function getWindow( elem ) {
  7436. return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
  7437. }
  7438. jQuery.offset = {
  7439. setOffset: function( elem, options, i ) {
  7440. var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
  7441. position = jQuery.css( elem, "position" ),
  7442. curElem = jQuery( elem ),
  7443. props = {};
  7444. // Set position first, in-case top/left are set even on static elem
  7445. if ( position === "static" ) {
  7446. elem.style.position = "relative";
  7447. }
  7448. curOffset = curElem.offset();
  7449. curCSSTop = jQuery.css( elem, "top" );
  7450. curCSSLeft = jQuery.css( elem, "left" );
  7451. calculatePosition = ( position === "absolute" || position === "fixed" ) &&
  7452. ( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
  7453. // Need to be able to calculate position if either top or left is auto and position is either absolute or fixed
  7454. if ( calculatePosition ) {
  7455. curPosition = curElem.position();
  7456. curTop = curPosition.top;
  7457. curLeft = curPosition.left;
  7458. } else {
  7459. curTop = parseFloat( curCSSTop ) || 0;
  7460. curLeft = parseFloat( curCSSLeft ) || 0;
  7461. }
  7462. if ( jQuery.isFunction( options ) ) {
  7463. options = options.call( elem, i, curOffset );
  7464. }
  7465. if ( options.top != null ) {
  7466. props.top = ( options.top - curOffset.top ) + curTop;
  7467. }
  7468. if ( options.left != null ) {
  7469. props.left = ( options.left - curOffset.left ) + curLeft;
  7470. }
  7471. if ( "using" in options ) {
  7472. options.using.call( elem, props );
  7473. } else {
  7474. curElem.css( props );
  7475. }
  7476. }
  7477. };
  7478. jQuery.fn.extend({
  7479. offset: function( options ) {
  7480. if ( arguments.length ) {
  7481. return options === undefined ?
  7482. this :
  7483. this.each(function( i ) {
  7484. jQuery.offset.setOffset( this, options, i );
  7485. });
  7486. }
  7487. var docElem, win,
  7488. elem = this[ 0 ],
  7489. box = { top: 0, left: 0 },
  7490. doc = elem && elem.ownerDocument;
  7491. if ( !doc ) {
  7492. return;
  7493. }
  7494. docElem = doc.documentElement;
  7495. // Make sure it's not a disconnected DOM node
  7496. if ( !jQuery.contains( docElem, elem ) ) {
  7497. return box;
  7498. }
  7499. // If we don't have gBCR, just use 0,0 rather than error
  7500. // BlackBerry 5, iOS 3 (original iPhone)
  7501. if ( typeof elem.getBoundingClientRect !== strundefined ) {
  7502. box = elem.getBoundingClientRect();
  7503. }
  7504. win = getWindow( doc );
  7505. return {
  7506. top: box.top + win.pageYOffset - docElem.clientTop,
  7507. left: box.left + win.pageXOffset - docElem.clientLeft
  7508. };
  7509. },
  7510. position: function() {
  7511. if ( !this[ 0 ] ) {
  7512. return;
  7513. }
  7514. var offsetParent, offset,
  7515. elem = this[ 0 ],
  7516. parentOffset = { top: 0, left: 0 };
  7517. // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
  7518. if ( jQuery.css( elem, "position" ) === "fixed" ) {
  7519. // We assume that getBoundingClientRect is available when computed position is fixed
  7520. offset = elem.getBoundingClientRect();
  7521. } else {
  7522. // Get *real* offsetParent
  7523. offsetParent = this.offsetParent();
  7524. // Get correct offsets
  7525. offset = this.offset();
  7526. if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
  7527. parentOffset = offsetParent.offset();
  7528. }
  7529. // Add offsetParent borders
  7530. parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
  7531. parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
  7532. }
  7533. // Subtract parent offsets and element margins
  7534. return {
  7535. top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
  7536. left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
  7537. };
  7538. },
  7539. offsetParent: function() {
  7540. return this.map(function() {
  7541. var offsetParent = this.offsetParent || docElem;
  7542. while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
  7543. offsetParent = offsetParent.offsetParent;
  7544. }
  7545. return offsetParent || docElem;
  7546. });
  7547. }
  7548. });
  7549. // Create scrollLeft and scrollTop methods
  7550. jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
  7551. var top = "pageYOffset" === prop;
  7552. jQuery.fn[ method ] = function( val ) {
  7553. return access( this, function( elem, method, val ) {
  7554. var win = getWindow( elem );
  7555. if ( val === undefined ) {
  7556. return win ? win[ prop ] : elem[ method ];
  7557. }
  7558. if ( win ) {
  7559. win.scrollTo(
  7560. !top ? val : window.pageXOffset,
  7561. top ? val : window.pageYOffset
  7562. );
  7563. } else {
  7564. elem[ method ] = val;
  7565. }
  7566. }, method, val, arguments.length, null );
  7567. };
  7568. });
  7569. // Add the top/left cssHooks using jQuery.fn.position
  7570. // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
  7571. // getComputedStyle returns percent when specified for top/left/bottom/right
  7572. // rather than make the css module depend on the offset module, we just check for it here
  7573. jQuery.each( [ "top", "left" ], function( i, prop ) {
  7574. jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
  7575. function( elem, computed ) {
  7576. if ( computed ) {
  7577. computed = curCSS( elem, prop );
  7578. // if curCSS returns percentage, fallback to offset
  7579. return rnumnonpx.test( computed ) ?
  7580. jQuery( elem ).position()[ prop ] + "px" :
  7581. computed;
  7582. }
  7583. }
  7584. );
  7585. });
  7586. // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
  7587. jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
  7588. jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
  7589. // margin is only for outerHeight, outerWidth
  7590. jQuery.fn[ funcName ] = function( margin, value ) {
  7591. var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
  7592. extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
  7593. return access( this, function( elem, type, value ) {
  7594. var doc;
  7595. if ( jQuery.isWindow( elem ) ) {
  7596. // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
  7597. // isn't a whole lot we can do. See pull request at this URL for discussion:
  7598. // https://github.com/jquery/jquery/pull/764
  7599. return elem.document.documentElement[ "client" + name ];
  7600. }
  7601. // Get document width or height
  7602. if ( elem.nodeType === 9 ) {
  7603. doc = elem.documentElement;
  7604. // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
  7605. // whichever is greatest
  7606. return Math.max(
  7607. elem.body[ "scroll" + name ], doc[ "scroll" + name ],
  7608. elem.body[ "offset" + name ], doc[ "offset" + name ],
  7609. doc[ "client" + name ]
  7610. );
  7611. }
  7612. return value === undefined ?
  7613. // Get width or height on the element, requesting but not forcing parseFloat
  7614. jQuery.css( elem, type, extra ) :
  7615. // Set width or height on the element
  7616. jQuery.style( elem, type, value, extra );
  7617. }, type, chainable ? margin : undefined, chainable, null );
  7618. };
  7619. });
  7620. });
  7621. // The number of elements contained in the matched element set
  7622. jQuery.fn.size = function() {
  7623. return this.length;
  7624. };
  7625. jQuery.fn.andSelf = jQuery.fn.addBack;
  7626. // Register as a named AMD module, since jQuery can be concatenated with other
  7627. // files that may use define, but not via a proper concatenation script that
  7628. // understands anonymous AMD modules. A named AMD is safest and most robust
  7629. // way to register. Lowercase jquery is used because AMD module names are
  7630. // derived from file names, and jQuery is normally delivered in a lowercase
  7631. // file name. Do this after creating the global so that if an AMD module wants
  7632. // to call noConflict to hide this version of jQuery, it will work.
  7633. // Note that for maximum portability, libraries that are not jQuery should
  7634. // declare themselves as anonymous modules, and avoid setting a global if an
  7635. // AMD loader is present. jQuery is a special case. For more information, see
  7636. // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
  7637. if ( typeof define === "function" && define.amd ) {
  7638. define( "jquery", [], function() {
  7639. return jQuery;
  7640. });
  7641. }
  7642. var
  7643. // Map over jQuery in case of overwrite
  7644. _jQuery = window.jQuery,
  7645. // Map over the $ in case of overwrite
  7646. _$ = window.$;
  7647. jQuery.noConflict = function( deep ) {
  7648. if ( window.$ === jQuery ) {
  7649. window.$ = _$;
  7650. }
  7651. if ( deep && window.jQuery === jQuery ) {
  7652. window.jQuery = _jQuery;
  7653. }
  7654. return jQuery;
  7655. };
  7656. // Expose jQuery and $ identifiers, even in
  7657. // AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
  7658. // and CommonJS for browser emulators (#13566)
  7659. if ( typeof noGlobal === strundefined ) {
  7660. window.jQuery = window.$ = jQuery;
  7661. }
  7662. return jQuery;
  7663. }));
  7664. (function() {
  7665. var define, requireModule, require, requirejs;
  7666. (function() {
  7667. var registry = {}, seen = {};
  7668. define = function(name, deps, callback) {
  7669. registry[name] = { deps: deps, callback: callback };
  7670. };
  7671. requirejs = require = requireModule = function(name) {
  7672. requirejs._eak_seen = registry;
  7673. if (seen[name]) { return seen[name]; }
  7674. seen[name] = {};
  7675. if (!registry[name]) {
  7676. throw new Error("Could not find module " + name);
  7677. }
  7678. var mod = registry[name],
  7679. deps = mod.deps,
  7680. callback = mod.callback,
  7681. reified = [],
  7682. exports;
  7683. for (var i=0, l=deps.length; i<l; i++) {
  7684. if (deps[i] === 'exports') {
  7685. reified.push(exports = {});
  7686. } else {
  7687. reified.push(requireModule(resolve(deps[i])));
  7688. }
  7689. }
  7690. var value = callback.apply(this, reified);
  7691. return seen[name] = exports || value;
  7692. function resolve(child) {
  7693. if (child.charAt(0) !== '.') { return child; }
  7694. var parts = child.split("/");
  7695. var parentBase = name.split("/").slice(0, -1);
  7696. for (var i=0, l=parts.length; i<l; i++) {
  7697. var part = parts[i];
  7698. if (part === '..') { parentBase.pop(); }
  7699. else if (part === '.') { continue; }
  7700. else { parentBase.push(part); }
  7701. }
  7702. return parentBase.join("/");
  7703. }
  7704. };
  7705. })();
  7706. define("promise/all",
  7707. ["./utils","exports"],
  7708. function(__dependency1__, __exports__) {
  7709. "use strict";
  7710. /* global toString */
  7711. var isArray = __dependency1__.isArray;
  7712. var isFunction = __dependency1__.isFunction;
  7713. /**
  7714. Returns a promise that is fulfilled when all the given promises have been
  7715. fulfilled, or rejected if any of them become rejected. The return promise
  7716. is fulfilled with an array that gives all the values in the order they were
  7717. passed in the `promises` array argument.
  7718. Example:
  7719. ```javascript
  7720. var promise1 = RSVP.resolve(1);
  7721. var promise2 = RSVP.resolve(2);
  7722. var promise3 = RSVP.resolve(3);
  7723. var promises = [ promise1, promise2, promise3 ];
  7724. RSVP.all(promises).then(function(array){
  7725. // The array here would be [ 1, 2, 3 ];
  7726. });
  7727. ```
  7728. If any of the `promises` given to `RSVP.all` are rejected, the first promise
  7729. that is rejected will be given as an argument to the returned promises's
  7730. rejection handler. For example:
  7731. Example:
  7732. ```javascript
  7733. var promise1 = RSVP.resolve(1);
  7734. var promise2 = RSVP.reject(new Error("2"));
  7735. var promise3 = RSVP.reject(new Error("3"));
  7736. var promises = [ promise1, promise2, promise3 ];
  7737. RSVP.all(promises).then(function(array){
  7738. // Code here never runs because there are rejected promises!
  7739. }, function(error) {
  7740. // error.message === "2"
  7741. });
  7742. ```
  7743. @method all
  7744. @for RSVP
  7745. @param {Array} promises
  7746. @param {String} label
  7747. @return {Promise} promise that is fulfilled when all `promises` have been
  7748. fulfilled, or rejected if any of them become rejected.
  7749. */
  7750. function all(promises) {
  7751. /*jshint validthis:true */
  7752. var Promise = this;
  7753. if (!isArray(promises)) {
  7754. throw new TypeError('You must pass an array to all.');
  7755. }
  7756. return new Promise(function(resolve, reject) {
  7757. var results = [], remaining = promises.length,
  7758. promise;
  7759. if (remaining === 0) {
  7760. resolve([]);
  7761. }
  7762. function resolver(index) {
  7763. return function(value) {
  7764. resolveAll(index, value);
  7765. };
  7766. }
  7767. function resolveAll(index, value) {
  7768. results[index] = value;
  7769. if (--remaining === 0) {
  7770. resolve(results);
  7771. }
  7772. }
  7773. for (var i = 0; i < promises.length; i++) {
  7774. promise = promises[i];
  7775. if (promise && isFunction(promise.then)) {
  7776. promise.then(resolver(i), reject);
  7777. } else {
  7778. resolveAll(i, promise);
  7779. }
  7780. }
  7781. });
  7782. }
  7783. __exports__.all = all;
  7784. });
  7785. define("promise/asap",
  7786. ["exports"],
  7787. function(__exports__) {
  7788. "use strict";
  7789. var browserGlobal = (typeof window !== 'undefined') ? window : {};
  7790. var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
  7791. var local = (typeof global !== 'undefined') ? global : (this === undefined? window:this);
  7792. // node
  7793. function useNextTick() {
  7794. return function() {
  7795. process.nextTick(flush);
  7796. };
  7797. }
  7798. function useMutationObserver() {
  7799. var iterations = 0;
  7800. var observer = new BrowserMutationObserver(flush);
  7801. var node = document.createTextNode('');
  7802. observer.observe(node, { characterData: true });
  7803. return function() {
  7804. node.data = (iterations = ++iterations % 2);
  7805. };
  7806. }
  7807. function useSetTimeout() {
  7808. return function() {
  7809. local.setTimeout(flush, 1);
  7810. };
  7811. }
  7812. var queue = [];
  7813. function flush() {
  7814. for (var i = 0; i < queue.length; i++) {
  7815. var tuple = queue[i];
  7816. var callback = tuple[0], arg = tuple[1];
  7817. callback(arg);
  7818. }
  7819. queue = [];
  7820. }
  7821. var scheduleFlush;
  7822. // Decide what async method to use to triggering processing of queued callbacks:
  7823. if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
  7824. scheduleFlush = useNextTick();
  7825. } else if (BrowserMutationObserver) {
  7826. scheduleFlush = useMutationObserver();
  7827. } else {
  7828. scheduleFlush = useSetTimeout();
  7829. }
  7830. function asap(callback, arg) {
  7831. var length = queue.push([callback, arg]);
  7832. if (length === 1) {
  7833. // If length is 1, that means that we need to schedule an async flush.
  7834. // If additional callbacks are queued before the queue is flushed, they
  7835. // will be processed by this flush that we are scheduling.
  7836. scheduleFlush();
  7837. }
  7838. }
  7839. __exports__.asap = asap;
  7840. });
  7841. define("promise/config",
  7842. ["exports"],
  7843. function(__exports__) {
  7844. "use strict";
  7845. var config = {
  7846. instrument: false
  7847. };
  7848. function configure(name, value) {
  7849. if (arguments.length === 2) {
  7850. config[name] = value;
  7851. } else {
  7852. return config[name];
  7853. }
  7854. }
  7855. __exports__.config = config;
  7856. __exports__.configure = configure;
  7857. });
  7858. define("promise/polyfill",
  7859. ["./promise","./utils","exports"],
  7860. function(__dependency1__, __dependency2__, __exports__) {
  7861. "use strict";
  7862. /*global self*/
  7863. var RSVPPromise = __dependency1__.Promise;
  7864. var isFunction = __dependency2__.isFunction;
  7865. function polyfill() {
  7866. var local;
  7867. if (typeof global !== 'undefined') {
  7868. local = global;
  7869. } else if (typeof window !== 'undefined' && window.document) {
  7870. local = window;
  7871. } else {
  7872. local = self;
  7873. }
  7874. var es6PromiseSupport =
  7875. "Promise" in local &&
  7876. // Some of these methods are missing from
  7877. // Firefox/Chrome experimental implementations
  7878. "resolve" in local.Promise &&
  7879. "reject" in local.Promise &&
  7880. "all" in local.Promise &&
  7881. "race" in local.Promise &&
  7882. // Older version of the spec had a resolver object
  7883. // as the arg rather than a function
  7884. (function() {
  7885. var resolve;
  7886. new local.Promise(function(r) { resolve = r; });
  7887. return isFunction(resolve);
  7888. }());
  7889. // !es6PromiseSupport || ~window.location.href.indexOf('rsvpromise')
  7890. if (true) {
  7891. local.Promise = RSVPPromise;
  7892. }
  7893. }
  7894. __exports__.polyfill = polyfill;
  7895. });
  7896. define("promise/promise",
  7897. ["./config","./utils","./all","./race","./resolve","./reject","./asap","exports"],
  7898. function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) {
  7899. "use strict";
  7900. var config = __dependency1__.config;
  7901. var configure = __dependency1__.configure;
  7902. var objectOrFunction = __dependency2__.objectOrFunction;
  7903. var isFunction = __dependency2__.isFunction;
  7904. var now = __dependency2__.now;
  7905. var all = __dependency3__.all;
  7906. var race = __dependency4__.race;
  7907. var staticResolve = __dependency5__.resolve;
  7908. var staticReject = __dependency6__.reject;
  7909. var asap = __dependency7__.asap;
  7910. var counter = 0;
  7911. config.async = asap; // default async is asap;
  7912. function Promise(resolver) {
  7913. if (!isFunction(resolver)) {
  7914. throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
  7915. }
  7916. if (!(this instanceof Promise)) {
  7917. throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
  7918. }
  7919. this._subscribers = [];
  7920. invokeResolver(resolver, this);
  7921. }
  7922. function invokeResolver(resolver, promise) {
  7923. function resolvePromise(value) {
  7924. resolve(promise, value);
  7925. }
  7926. function rejectPromise(reason) {
  7927. reject(promise, reason);
  7928. }
  7929. try {
  7930. resolver(resolvePromise, rejectPromise);
  7931. } catch(e) {
  7932. rejectPromise(e);
  7933. }
  7934. }
  7935. function invokeCallback(settled, promise, callback, detail) {
  7936. var hasCallback = isFunction(callback),
  7937. value, error, succeeded, failed;
  7938. if (hasCallback) {
  7939. try {
  7940. value = callback(detail);
  7941. succeeded = true;
  7942. } catch(e) {
  7943. failed = true;
  7944. error = e;
  7945. }
  7946. } else {
  7947. value = detail;
  7948. succeeded = true;
  7949. }
  7950. if (handleThenable(promise, value)) {
  7951. return;
  7952. } else if (hasCallback && succeeded) {
  7953. resolve(promise, value);
  7954. } else if (failed) {
  7955. reject(promise, error);
  7956. } else if (settled === FULFILLED) {
  7957. resolve(promise, value);
  7958. } else if (settled === REJECTED) {
  7959. reject(promise, value);
  7960. }
  7961. }
  7962. var PENDING = void 0;
  7963. var SEALED = 0;
  7964. var FULFILLED = 1;
  7965. var REJECTED = 2;
  7966. function subscribe(parent, child, onFulfillment, onRejection) {
  7967. var subscribers = parent._subscribers;
  7968. var length = subscribers.length;
  7969. subscribers[length] = child;
  7970. subscribers[length + FULFILLED] = onFulfillment;
  7971. subscribers[length + REJECTED] = onRejection;
  7972. }
  7973. function publish(promise, settled) {
  7974. var child, callback, subscribers = promise._subscribers, detail = promise._detail;
  7975. for (var i = 0; i < subscribers.length; i += 3) {
  7976. child = subscribers[i];
  7977. callback = subscribers[i + settled];
  7978. invokeCallback(settled, child, callback, detail);
  7979. }
  7980. promise._subscribers = null;
  7981. }
  7982. Promise.prototype = {
  7983. constructor: Promise,
  7984. _state: undefined,
  7985. _detail: undefined,
  7986. _subscribers: undefined,
  7987. then: function(onFulfillment, onRejection) {
  7988. var promise = this;
  7989. var thenPromise = new this.constructor(function() {});
  7990. if (this._state) {
  7991. var callbacks = arguments;
  7992. config.async(function invokePromiseCallback() {
  7993. invokeCallback(promise._state, thenPromise, callbacks[promise._state - 1], promise._detail);
  7994. });
  7995. } else {
  7996. subscribe(this, thenPromise, onFulfillment, onRejection);
  7997. }
  7998. return thenPromise;
  7999. },
  8000. 'catch': function(onRejection) {
  8001. return this.then(null, onRejection);
  8002. }
  8003. };
  8004. Promise.all = all;
  8005. Promise.race = race;
  8006. Promise.resolve = staticResolve;
  8007. Promise.reject = staticReject;
  8008. function handleThenable(promise, value) {
  8009. var then = null,
  8010. resolved;
  8011. try {
  8012. if (promise === value) {
  8013. throw new TypeError("A promises callback cannot return that same promise.");
  8014. }
  8015. if (objectOrFunction(value)) {
  8016. then = value.then;
  8017. if (isFunction(then)) {
  8018. then.call(value, function(val) {
  8019. if (resolved) { return true; }
  8020. resolved = true;
  8021. if (value !== val) {
  8022. resolve(promise, val);
  8023. } else {
  8024. fulfill(promise, val);
  8025. }
  8026. }, function(val) {
  8027. if (resolved) { return true; }
  8028. resolved = true;
  8029. reject(promise, val);
  8030. });
  8031. return true;
  8032. }
  8033. }
  8034. } catch (error) {
  8035. if (resolved) { return true; }
  8036. reject(promise, error);
  8037. return true;
  8038. }
  8039. return false;
  8040. }
  8041. function resolve(promise, value) {
  8042. if (promise === value) {
  8043. fulfill(promise, value);
  8044. } else if (!handleThenable(promise, value)) {
  8045. fulfill(promise, value);
  8046. }
  8047. }
  8048. function fulfill(promise, value) {
  8049. if (promise._state !== PENDING) { return; }
  8050. promise._state = SEALED;
  8051. promise._detail = value;
  8052. config.async(publishFulfillment, promise);
  8053. }
  8054. function reject(promise, reason) {
  8055. if (promise._state !== PENDING) { return; }
  8056. promise._state = SEALED;
  8057. promise._detail = reason;
  8058. config.async(publishRejection, promise);
  8059. }
  8060. function publishFulfillment(promise) {
  8061. publish(promise, promise._state = FULFILLED);
  8062. }
  8063. function publishRejection(promise) {
  8064. publish(promise, promise._state = REJECTED);
  8065. }
  8066. __exports__.Promise = Promise;
  8067. });
  8068. define("promise/race",
  8069. ["./utils","exports"],
  8070. function(__dependency1__, __exports__) {
  8071. "use strict";
  8072. /* global toString */
  8073. var isArray = __dependency1__.isArray;
  8074. /**
  8075. `RSVP.race` allows you to watch a series of promises and act as soon as the
  8076. first promise given to the `promises` argument fulfills or rejects.
  8077. Example:
  8078. ```javascript
  8079. var promise1 = new RSVP.Promise(function(resolve, reject){
  8080. setTimeout(function(){
  8081. resolve("promise 1");
  8082. }, 200);
  8083. });
  8084. var promise2 = new RSVP.Promise(function(resolve, reject){
  8085. setTimeout(function(){
  8086. resolve("promise 2");
  8087. }, 100);
  8088. });
  8089. RSVP.race([promise1, promise2]).then(function(result){
  8090. // result === "promise 2" because it was resolved before promise1
  8091. // was resolved.
  8092. });
  8093. ```
  8094. `RSVP.race` is deterministic in that only the state of the first completed
  8095. promise matters. For example, even if other promises given to the `promises`
  8096. array argument are resolved, but the first completed promise has become
  8097. rejected before the other promises became fulfilled, the returned promise
  8098. will become rejected:
  8099. ```javascript
  8100. var promise1 = new RSVP.Promise(function(resolve, reject){
  8101. setTimeout(function(){
  8102. resolve("promise 1");
  8103. }, 200);
  8104. });
  8105. var promise2 = new RSVP.Promise(function(resolve, reject){
  8106. setTimeout(function(){
  8107. reject(new Error("promise 2"));
  8108. }, 100);
  8109. });
  8110. RSVP.race([promise1, promise2]).then(function(result){
  8111. // Code here never runs because there are rejected promises!
  8112. }, function(reason){
  8113. // reason.message === "promise2" because promise 2 became rejected before
  8114. // promise 1 became fulfilled
  8115. });
  8116. ```
  8117. @method race
  8118. @for RSVP
  8119. @param {Array} promises array of promises to observe
  8120. @param {String} label optional string for describing the promise returned.
  8121. Useful for tooling.
  8122. @return {Promise} a promise that becomes fulfilled with the value the first
  8123. completed promises is resolved with if the first completed promise was
  8124. fulfilled, or rejected with the reason that the first completed promise
  8125. was rejected with.
  8126. */
  8127. function race(promises) {
  8128. /*jshint validthis:true */
  8129. var Promise = this;
  8130. if (!isArray(promises)) {
  8131. throw new TypeError('You must pass an array to race.');
  8132. }
  8133. return new Promise(function(resolve, reject) {
  8134. var results = [], promise;
  8135. for (var i = 0; i < promises.length; i++) {
  8136. promise = promises[i];
  8137. if (promise && typeof promise.then === 'function') {
  8138. promise.then(resolve, reject);
  8139. } else {
  8140. resolve(promise);
  8141. }
  8142. }
  8143. });
  8144. }
  8145. __exports__.race = race;
  8146. });
  8147. define("promise/reject",
  8148. ["exports"],
  8149. function(__exports__) {
  8150. "use strict";
  8151. /**
  8152. `RSVP.reject` returns a promise that will become rejected with the passed
  8153. `reason`. `RSVP.reject` is essentially shorthand for the following:
  8154. ```javascript
  8155. var promise = new RSVP.Promise(function(resolve, reject){
  8156. reject(new Error('WHOOPS'));
  8157. });
  8158. promise.then(function(value){
  8159. // Code here doesn't run because the promise is rejected!
  8160. }, function(reason){
  8161. // reason.message === 'WHOOPS'
  8162. });
  8163. ```
  8164. Instead of writing the above, your code now simply becomes the following:
  8165. ```javascript
  8166. var promise = RSVP.reject(new Error('WHOOPS'));
  8167. promise.then(function(value){
  8168. // Code here doesn't run because the promise is rejected!
  8169. }, function(reason){
  8170. // reason.message === 'WHOOPS'
  8171. });
  8172. ```
  8173. @method reject
  8174. @for RSVP
  8175. @param {Any} reason value that the returned promise will be rejected with.
  8176. @param {String} label optional string for identifying the returned promise.
  8177. Useful for tooling.
  8178. @return {Promise} a promise that will become rejected with the given
  8179. `reason`.
  8180. */
  8181. function reject(reason) {
  8182. /*jshint validthis:true */
  8183. var Promise = this;
  8184. return new Promise(function (resolve, reject) {
  8185. reject(reason);
  8186. });
  8187. }
  8188. __exports__.reject = reject;
  8189. });
  8190. define("promise/resolve",
  8191. ["exports"],
  8192. function(__exports__) {
  8193. "use strict";
  8194. function resolve(value) {
  8195. /*jshint validthis:true */
  8196. if (value && typeof value === 'object' && value.constructor === this) {
  8197. return value;
  8198. }
  8199. var Promise = this;
  8200. return new Promise(function(resolve) {
  8201. resolve(value);
  8202. });
  8203. }
  8204. __exports__.resolve = resolve;
  8205. });
  8206. define("promise/utils",
  8207. ["exports"],
  8208. function(__exports__) {
  8209. "use strict";
  8210. function objectOrFunction(x) {
  8211. return isFunction(x) || (typeof x === "object" && x !== null);
  8212. }
  8213. function isFunction(x) {
  8214. return typeof x === "function";
  8215. }
  8216. function isArray(x) {
  8217. return Object.prototype.toString.call(x) === "[object Array]";
  8218. }
  8219. // Date.now is not available in browsers < IE9
  8220. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now#Compatibility
  8221. var now = Date.now || function() { return new Date().getTime(); };
  8222. __exports__.objectOrFunction = objectOrFunction;
  8223. __exports__.isFunction = isFunction;
  8224. __exports__.isArray = isArray;
  8225. __exports__.now = now;
  8226. });
  8227. requireModule('promise/polyfill').polyfill();
  8228. }());
  8229. /*
  8230. ### jQuery XML to JSON Plugin v1.3 - 2013-02-18 ###
  8231. * http://www.fyneworks.com/ - diego@fyneworks.com
  8232. * Licensed under http://en.wikipedia.org/wiki/MIT_License
  8233. ###
  8234. Website: http://www.fyneworks.com/jquery/xml-to-json/
  8235. *//*
  8236. # INSPIRED BY: http://www.terracoder.com/
  8237. AND: http://www.thomasfrank.se/xml_to_json.html
  8238. AND: http://www.kawa.net/works/js/xml/objtree-e.html
  8239. *//*
  8240. This simple script converts XML (document of code) into a JSON object. It is the combination of 2
  8241. 'xml to json' great parsers (see below) which allows for both 'simple' and 'extended' parsing modes.
  8242. */
  8243. // Avoid collisions
  8244. ;if(window.jQuery) (function($){
  8245. // Add function to jQuery namespace
  8246. $.extend({
  8247. // converts xml documents and xml text to json object
  8248. xml2json: function(xml, extended) {
  8249. if(!xml) return {}; // quick fail
  8250. //### PARSER LIBRARY
  8251. // Core function
  8252. function parseXML(node, simple){
  8253. if(!node) return null;
  8254. var txt = '', obj = null, att = null;
  8255. var nt = node.nodeType, nn = jsVar(node.localName || node.nodeName);
  8256. var nv = node.text || node.nodeValue || '';
  8257. /*DBG*/ //if(window.console) console.log(['x2j',nn,nt,nv.length+' bytes']);
  8258. if(node.childNodes){
  8259. if(node.childNodes.length>0){
  8260. /*DBG*/ //if(window.console) console.log(['x2j',nn,'CHILDREN',node.childNodes]);
  8261. $.each(node.childNodes, function(n,cn){
  8262. var cnt = cn.nodeType, cnn = jsVar(cn.localName || cn.nodeName);
  8263. var cnv = cn.text || cn.nodeValue || '';
  8264. /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>a',cnn,cnt,cnv]);
  8265. if(cnt == 8){
  8266. /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>b',cnn,'COMMENT (ignore)']);
  8267. return; // ignore comment node
  8268. }
  8269. else if(cnt == 3 || cnt == 4 || !cnn){
  8270. // ignore white-space in between tags
  8271. if(cnv.match(/^\s+$/)){
  8272. /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>c',cnn,'WHITE-SPACE (ignore)']);
  8273. return;
  8274. };
  8275. /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>d',cnn,'TEXT']);
  8276. txt += cnv.replace(/^\s+/,'').replace(/\s+$/,'');
  8277. // make sure we ditch trailing spaces from markup
  8278. }
  8279. else{
  8280. /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>e',cnn,'OBJECT']);
  8281. obj = obj || {};
  8282. if(obj[cnn]){
  8283. /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>f',cnn,'ARRAY']);
  8284. // http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child
  8285. if(!obj[cnn].length) obj[cnn] = myArr(obj[cnn]);
  8286. obj[cnn] = myArr(obj[cnn]);
  8287. obj[cnn][ obj[cnn].length ] = parseXML(cn, true/* simple */);
  8288. obj[cnn].length = obj[cnn].length;
  8289. }
  8290. else{
  8291. /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>g',cnn,'dig deeper...']);
  8292. obj[cnn] = parseXML(cn);
  8293. };
  8294. };
  8295. });
  8296. };//node.childNodes.length>0
  8297. };//node.childNodes
  8298. if(node.attributes){
  8299. if(node.attributes.length>0){
  8300. /*DBG*/ //if(window.console) console.log(['x2j',nn,'ATTRIBUTES',node.attributes])
  8301. att = {}; obj = obj || {};
  8302. $.each(node.attributes, function(a,at){
  8303. var atn = jsVar(at.name), atv = at.value;
  8304. att[atn] = atv;
  8305. if(obj[atn]){
  8306. /*DBG*/ //if(window.console) console.log(['x2j',nn,'attr>',atn,'ARRAY']);
  8307. // http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child
  8308. //if(!obj[atn].length) obj[atn] = myArr(obj[atn]);//[ obj[ atn ] ];
  8309. obj[cnn] = myArr(obj[cnn]);
  8310. obj[atn][ obj[atn].length ] = atv;
  8311. obj[atn].length = obj[atn].length;
  8312. }
  8313. else{
  8314. /*DBG*/ //if(window.console) console.log(['x2j',nn,'attr>',atn,'TEXT']);
  8315. obj[atn] = atv;
  8316. };
  8317. });
  8318. //obj['attributes'] = att;
  8319. };//node.attributes.length>0
  8320. };//node.attributes
  8321. if(obj){
  8322. obj = $.extend( (txt!='' ? new String(txt) : {}),/* {text:txt},*/ obj || {}/*, att || {}*/);
  8323. //txt = (obj.text) ? (typeof(obj.text)=='object' ? obj.text : [obj.text || '']).concat([txt]) : txt;
  8324. txt = (obj.text) ? ([obj.text || '']).concat([txt]) : txt;
  8325. if(txt) obj.text = txt;
  8326. txt = '';
  8327. };
  8328. var out = obj || txt;
  8329. //console.log([extended, simple, out]);
  8330. if(extended){
  8331. if(txt) out = {};//new String(out);
  8332. txt = out.text || txt || '';
  8333. if(txt) out.text = txt;
  8334. if(!simple) out = myArr(out);
  8335. };
  8336. return out;
  8337. };// parseXML
  8338. // Core Function End
  8339. // Utility functions
  8340. var jsVar = function(s){ return String(s || '').replace(/-/g,"_"); };
  8341. // NEW isNum function: 01/09/2010
  8342. // Thanks to Emile Grau, GigaTecnologies S.L., www.gigatransfer.com, www.mygigamail.com
  8343. function isNum(s){
  8344. // based on utility function isNum from xml2json plugin (http://www.fyneworks.com/ - diego@fyneworks.com)
  8345. // few bugs corrected from original function :
  8346. // - syntax error : regexp.test(string) instead of string.test(reg)
  8347. // - regexp modified to accept comma as decimal mark (latin syntax : 25,24 )
  8348. // - regexp modified to reject if no number before decimal mark : ".7" is not accepted
  8349. // - string is "trimmed", allowing to accept space at the beginning and end of string
  8350. var regexp=/^((-)?([0-9]+)(([\.\,]{0,1})([0-9]+))?$)/
  8351. return (typeof s == "number") || regexp.test(String((s && typeof s == "string") ? jQuery.trim(s) : ''));
  8352. };
  8353. // OLD isNum function: (for reference only)
  8354. //var isNum = function(s){ return (typeof s == "number") || String((s && typeof s == "string") ? s : '').test(/^((-)?([0-9]*)((\.{0,1})([0-9]+))?$)/); };
  8355. var myArr = function(o){
  8356. // http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child
  8357. //if(!o.length) o = [ o ]; o.length=o.length;
  8358. if(!$.isArray(o)) o = [ o ]; o.length=o.length;
  8359. // here is where you can attach additional functionality, such as searching and sorting...
  8360. return o;
  8361. };
  8362. // Utility functions End
  8363. //### PARSER LIBRARY END
  8364. // Convert plain text to xml
  8365. if(typeof xml=='string') xml = $.text2xml(xml);
  8366. // Quick fail if not xml (or if this is a node)
  8367. if(!xml.nodeType) return;
  8368. if(xml.nodeType == 3 || xml.nodeType == 4) return xml.nodeValue;
  8369. // Find xml root node
  8370. var root = (xml.nodeType == 9) ? xml.documentElement : xml;
  8371. // Convert xml to json
  8372. var out = parseXML(root, true /* simple */);
  8373. // Clean-up memory
  8374. xml = null; root = null;
  8375. // Send output
  8376. return out;
  8377. },
  8378. // Convert text to XML DOM
  8379. text2xml: function(str) {
  8380. // NOTE: I'd like to use jQuery for this, but jQuery makes all tags uppercase
  8381. //return $(xml)[0];
  8382. /* prior to jquery 1.9 */
  8383. /*
  8384. var out;
  8385. try{
  8386. var xml = ((!$.support.opacity && !$.support.style))?new ActiveXObject("Microsoft.XMLDOM"):new DOMParser();
  8387. xml.async = false;
  8388. }catch(e){ throw new Error("XML Parser could not be instantiated") };
  8389. try{
  8390. if((!$.support.opacity && !$.support.style)) out = (xml.loadXML(str))?xml:false;
  8391. else out = xml.parseFromString(str, "text/xml");
  8392. }catch(e){ throw new Error("Error parsing XML string") };
  8393. return out;
  8394. */
  8395. /* jquery 1.9+ */
  8396. return $.parseXML(str);
  8397. }
  8398. }); // extend $
  8399. })(jQuery);
  8400. (function(t,e){if(typeof define==="function"&&define.amd){define(["jquery"],e)}else if(typeof exports==="object"){module.exports=e(require("jquery"))}else{e(t.jQuery)}})(this,function(t){t.transit={version:"0.9.12",propertyMap:{marginLeft:"margin",marginRight:"margin",marginBottom:"margin",marginTop:"margin",paddingLeft:"padding",paddingRight:"padding",paddingBottom:"padding",paddingTop:"padding"},enabled:true,useTransitionEnd:false};var e=document.createElement("div");var n={};function i(t){if(t in e.style)return t;var n=["Moz","Webkit","O","ms"];var i=t.charAt(0).toUpperCase()+t.substr(1);for(var r=0;r<n.length;++r){var s=n[r]+i;if(s in e.style){return s}}}function r(){e.style[n.transform]="";e.style[n.transform]="rotateY(90deg)";return e.style[n.transform]!==""}var s=navigator.userAgent.toLowerCase().indexOf("chrome")>-1;n.transition=i("transition");n.transitionDelay=i("transitionDelay");n.transform=i("transform");n.transformOrigin=i("transformOrigin");n.filter=i("Filter");n.transform3d=r();var a={transition:"transitionend",MozTransition:"transitionend",OTransition:"oTransitionEnd",WebkitTransition:"webkitTransitionEnd",msTransition:"MSTransitionEnd"};var o=n.transitionEnd=a[n.transition]||null;for(var u in n){if(n.hasOwnProperty(u)&&typeof t.support[u]==="undefined"){t.support[u]=n[u]}}e=null;t.cssEase={_default:"ease","in":"ease-in",out:"ease-out","in-out":"ease-in-out",snap:"cubic-bezier(0,1,.5,1)",easeInCubic:"cubic-bezier(.550,.055,.675,.190)",easeOutCubic:"cubic-bezier(.215,.61,.355,1)",easeInOutCubic:"cubic-bezier(.645,.045,.355,1)",easeInCirc:"cubic-bezier(.6,.04,.98,.335)",easeOutCirc:"cubic-bezier(.075,.82,.165,1)",easeInOutCirc:"cubic-bezier(.785,.135,.15,.86)",easeInExpo:"cubic-bezier(.95,.05,.795,.035)",easeOutExpo:"cubic-bezier(.19,1,.22,1)",easeInOutExpo:"cubic-bezier(1,0,0,1)",easeInQuad:"cubic-bezier(.55,.085,.68,.53)",easeOutQuad:"cubic-bezier(.25,.46,.45,.94)",easeInOutQuad:"cubic-bezier(.455,.03,.515,.955)",easeInQuart:"cubic-bezier(.895,.03,.685,.22)",easeOutQuart:"cubic-bezier(.165,.84,.44,1)",easeInOutQuart:"cubic-bezier(.77,0,.175,1)",easeInQuint:"cubic-bezier(.755,.05,.855,.06)",easeOutQuint:"cubic-bezier(.23,1,.32,1)",easeInOutQuint:"cubic-bezier(.86,0,.07,1)",easeInSine:"cubic-bezier(.47,0,.745,.715)",easeOutSine:"cubic-bezier(.39,.575,.565,1)",easeInOutSine:"cubic-bezier(.445,.05,.55,.95)",easeInBack:"cubic-bezier(.6,-.28,.735,.045)",easeOutBack:"cubic-bezier(.175, .885,.32,1.275)",easeInOutBack:"cubic-bezier(.68,-.55,.265,1.55)"};t.cssHooks["transit:transform"]={get:function(e){return t(e).data("transform")||new f},set:function(e,i){var r=i;if(!(r instanceof f)){r=new f(r)}if(n.transform==="WebkitTransform"&&!s){e.style[n.transform]=r.toString(true)}else{e.style[n.transform]=r.toString()}t(e).data("transform",r)}};t.cssHooks.transform={set:t.cssHooks["transit:transform"].set};t.cssHooks.filter={get:function(t){return t.style[n.filter]},set:function(t,e){t.style[n.filter]=e}};if(t.fn.jquery<"1.8"){t.cssHooks.transformOrigin={get:function(t){return t.style[n.transformOrigin]},set:function(t,e){t.style[n.transformOrigin]=e}};t.cssHooks.transition={get:function(t){return t.style[n.transition]},set:function(t,e){t.style[n.transition]=e}}}p("scale");p("scaleX");p("scaleY");p("translate");p("rotate");p("rotateX");p("rotateY");p("rotate3d");p("perspective");p("skewX");p("skewY");p("x",true);p("y",true);function f(t){if(typeof t==="string"){this.parse(t)}return this}f.prototype={setFromString:function(t,e){var n=typeof e==="string"?e.split(","):e.constructor===Array?e:[e];n.unshift(t);f.prototype.set.apply(this,n)},set:function(t){var e=Array.prototype.slice.apply(arguments,[1]);if(this.setter[t]){this.setter[t].apply(this,e)}else{this[t]=e.join(",")}},get:function(t){if(this.getter[t]){return this.getter[t].apply(this)}else{return this[t]||0}},setter:{rotate:function(t){this.rotate=b(t,"deg")},rotateX:function(t){this.rotateX=b(t,"deg")},rotateY:function(t){this.rotateY=b(t,"deg")},scale:function(t,e){if(e===undefined){e=t}this.scale=t+","+e},skewX:function(t){this.skewX=b(t,"deg")},skewY:function(t){this.skewY=b(t,"deg")},perspective:function(t){this.perspective=b(t,"px")},x:function(t){this.set("translate",t,null)},y:function(t){this.set("translate",null,t)},translate:function(t,e){if(this._translateX===undefined){this._translateX=0}if(this._translateY===undefined){this._translateY=0}if(t!==null&&t!==undefined){this._translateX=b(t,"px")}if(e!==null&&e!==undefined){this._translateY=b(e,"px")}this.translate=this._translateX+","+this._translateY}},getter:{x:function(){return this._translateX||0},y:function(){return this._translateY||0},scale:function(){var t=(this.scale||"1,1").split(",");if(t[0]){t[0]=parseFloat(t[0])}if(t[1]){t[1]=parseFloat(t[1])}return t[0]===t[1]?t[0]:t},rotate3d:function(){var t=(this.rotate3d||"0,0,0,0deg").split(",");for(var e=0;e<=3;++e){if(t[e]){t[e]=parseFloat(t[e])}}if(t[3]){t[3]=b(t[3],"deg")}return t}},parse:function(t){var e=this;t.replace(/([a-zA-Z0-9]+)\((.*?)\)/g,function(t,n,i){e.setFromString(n,i)})},toString:function(t){var e=[];for(var i in this){if(this.hasOwnProperty(i)){if(!n.transform3d&&(i==="rotateX"||i==="rotateY"||i==="perspective"||i==="transformOrigin")){continue}if(i[0]!=="_"){if(t&&i==="scale"){e.push(i+"3d("+this[i]+",1)")}else if(t&&i==="translate"){e.push(i+"3d("+this[i]+",0)")}else{e.push(i+"("+this[i]+")")}}}}return e.join(" ")}};function c(t,e,n){if(e===true){t.queue(n)}else if(e){t.queue(e,n)}else{t.each(function(){n.call(this)})}}function l(e){var i=[];t.each(e,function(e){e=t.camelCase(e);e=t.transit.propertyMap[e]||t.cssProps[e]||e;e=h(e);if(n[e])e=h(n[e]);if(t.inArray(e,i)===-1){i.push(e)}});return i}function d(e,n,i,r){var s=l(e);if(t.cssEase[i]){i=t.cssEase[i]}var a=""+y(n)+" "+i;if(parseInt(r,10)>0){a+=" "+y(r)}var o=[];t.each(s,function(t,e){o.push(e+" "+a)});return o.join(", ")}t.fn.transition=t.fn.transit=function(e,i,r,s){var a=this;var u=0;var f=true;var l=t.extend(true,{},e);if(typeof i==="function"){s=i;i=undefined}if(typeof i==="object"){r=i.easing;u=i.delay||0;f=typeof i.queue==="undefined"?true:i.queue;s=i.complete;i=i.duration}if(typeof r==="function"){s=r;r=undefined}if(typeof l.easing!=="undefined"){r=l.easing;delete l.easing}if(typeof l.duration!=="undefined"){i=l.duration;delete l.duration}if(typeof l.complete!=="undefined"){s=l.complete;delete l.complete}if(typeof l.queue!=="undefined"){f=l.queue;delete l.queue}if(typeof l.delay!=="undefined"){u=l.delay;delete l.delay}if(typeof i==="undefined"){i=t.fx.speeds._default}if(typeof r==="undefined"){r=t.cssEase._default}i=y(i);var p=d(l,i,r,u);var h=t.transit.enabled&&n.transition;var b=h?parseInt(i,10)+parseInt(u,10):0;if(b===0){var g=function(t){a.css(l);if(s){s.apply(a)}if(t){t()}};c(a,f,g);return a}var m={};var v=function(e){var i=false;var r=function(){if(i){a.unbind(o,r)}if(b>0){a.each(function(){this.style[n.transition]=m[this]||null})}if(typeof s==="function"){s.apply(a)}if(typeof e==="function"){e()}};if(b>0&&o&&t.transit.useTransitionEnd){i=true;a.bind(o,r)}else{window.setTimeout(r,b)}a.each(function(){if(b>0){this.style[n.transition]=p}t(this).css(l)})};var z=function(t){this.offsetWidth;v(t)};c(a,f,z);return this};function p(e,i){if(!i){t.cssNumber[e]=true}t.transit.propertyMap[e]=n.transform;t.cssHooks[e]={get:function(n){var i=t(n).css("transit:transform");return i.get(e)},set:function(n,i){var r=t(n).css("transit:transform");r.setFromString(e,i);t(n).css({"transit:transform":r})}}}function h(t){return t.replace(/([A-Z])/g,function(t){return"-"+t.toLowerCase()})}function b(t,e){if(typeof t==="string"&&!t.match(/^[\-0-9\.]+$/)){return t}else{return""+t+e}}function y(e){var n=e;if(typeof n==="string"&&!n.match(/^[\-0-9\.]+/)){n=t.fx.speeds[n]||t.fx.speeds._default}return b(n,"ms")}t.transit.getTransitionValue=d;return t});
  8401. var jhtmls="undefined"==typeof exports?jhtmls||{}:exports;void function(e){"use strict";function n(e){return String(e).replace(/["<>& ]/g,function(e){return"&"+u[e]+";"})}function t(e){var n=[];return n.push("with(this){"),n.push(e.replace(/<(script|style)[^>]*>[\s\S]*?<\/\1>/g,function(e){return['!#{unescape("',escape(e),'")}'].join("")}).replace(/[\r\n]+/g,"\n").replace(/^\n+|\s+$/gm,"").replace(/^([ \w\t_$]*([^&\^?|\n\w\/'"{}\[\]+\-():; \t=\.$_]|:\/\/).*$|^(?!\s*(else|do|try|finally|void|typeof\s[\w$_]*)\s*$)[^'":;{}()\n|=&\/^?]+$)\s?/gm,function(e){return e=e.replace(/&none;/g,"").replace(/["'\\]/g,"\\$&").replace(/\n/g,"\\n").replace(/(!?#)\{(.*?)\}|(!?\$)([a-z_]+\w*(?:\.[a-z_]+\w*)*)/g,function(e,n,t,r,u){if(r&&(n=r,t=u),!t)return"";t=t.replace(/\\n/g,"\n").replace(/\\([\\'"])/g,"$1");var o=/^[a-z$][\w+$]+$/i.test(t)&&!/^(true|false|NaN|null|this)$/.test(t);return["',",o?["typeof ",t,"==='undefined'?'':"].join(""):"","#"===n||"$"===n?"_encode_":"","(",t,"),'"].join("")}),e=["'",e,"'"].join("").replace(/^'',|,''$/g,""),e?["_output_.push(",e,");"].join(""):""})),n.push("}"),new Function("_output_","_encode_","helper","jhtmls",n.join(""))}function r(r,u,o){"function"==typeof r&&(r=String(r).replace(/^[^\{]*\{\s*\/\*!?[ \f\t\v]*\n?|[ \f\t\v]*\*\/[;|\s]*\}$/g,""));var i=t(r),s=function(t,r){r=r||e;var u=[];return i.call(t,u,n,r,e),u.join("")};return arguments.length<=1?s:s(u,o)}var u={'"':"quot","<":"lt",">":"gt","&":"amp"," ":"nbsp"};e.render=r}(jhtmls);
  8402. /*!
  8403. * ====================================================
  8404. * Flex UI - v1.0.0 - 2015-01-12
  8405. * https://github.com/fex-team/fui
  8406. * GitHub: https://github.com/fex-team/fui.git
  8407. * Copyright (c) 2015 Baidu Kity Group; Licensed MIT
  8408. * ====================================================
  8409. */
  8410. (function () {
  8411. var _p = {
  8412. r: function(index) {
  8413. if (_p[index].inited) {
  8414. return _p[index].value;
  8415. }
  8416. if (typeof _p[index].value === "function") {
  8417. var module = {
  8418. exports: {}
  8419. }, returnValue = _p[index].value(null, module.exports, module);
  8420. _p[index].inited = true;
  8421. _p[index].value = returnValue;
  8422. if (returnValue !== undefined) {
  8423. return returnValue;
  8424. } else {
  8425. for (var key in module.exports) {
  8426. if (module.exports.hasOwnProperty(key)) {
  8427. _p[index].inited = true;
  8428. _p[index].value = module.exports;
  8429. return module.exports;
  8430. }
  8431. }
  8432. }
  8433. } else {
  8434. _p[index].inited = true;
  8435. return _p[index].value;
  8436. }
  8437. }
  8438. };
  8439. //src/base/creator.js
  8440. /**
  8441. * UI构造工厂, 提供可通过参数配置项创建多个构件的机制.
  8442. */
  8443. _p[0] = {
  8444. value: function(require) {
  8445. var Creator = {}, $ = _p.r(4), FUI_NS = _p.r(11);
  8446. $.extend(Creator, {
  8447. parse: function(options) {
  8448. var pool = [];
  8449. if ($.isArray(options)) {
  8450. $.each(options, function(i, opt) {
  8451. pool.push(getInstance(opt));
  8452. });
  8453. return pool;
  8454. } else {
  8455. return getInstance(options);
  8456. }
  8457. }
  8458. });
  8459. function getInstance(option) {
  8460. var Constructor = FUI_NS[option.clazz];
  8461. if (!Constructor) {
  8462. return null;
  8463. }
  8464. return new Constructor(option);
  8465. }
  8466. return Creator;
  8467. }
  8468. };
  8469. //src/base/exports.js
  8470. /**
  8471. * 模块暴露
  8472. */
  8473. _p[1] = {
  8474. value: function(require) {
  8475. var FUI_NS = _p.r(11);
  8476. // 配置参数必须最先注册
  8477. FUI_NS.___register({
  8478. ALLOW_FOCUS: true
  8479. });
  8480. FUI_NS.___register({
  8481. Widget: _p.r(60),
  8482. Icon: _p.r(42),
  8483. Label: _p.r(48),
  8484. Button: _p.r(37),
  8485. ToggleButton: _p.r(59),
  8486. Buttonset: _p.r(36),
  8487. Separator: _p.r(56),
  8488. Item: _p.r(46),
  8489. Input: _p.r(45),
  8490. InputButton: _p.r(43),
  8491. Mask: _p.r(49),
  8492. ColorPicker: _p.r(38),
  8493. Tabs: _p.r(58),
  8494. SpinButton: _p.r(57),
  8495. Container: _p.r(39),
  8496. Panel: _p.r(51),
  8497. PPanel: _p.r(54),
  8498. LabelPanel: _p.r(47),
  8499. Menu: _p.r(50),
  8500. InputMenu: _p.r(44),
  8501. ButtonMenu: _p.r(34),
  8502. DropPanel: _p.r(41),
  8503. Popup: _p.r(53),
  8504. PopupMenu: _p.r(52),
  8505. SelectMenu: _p.r(55),
  8506. Dialog: _p.r(40),
  8507. Utils: _p.r(13),
  8508. Creator: _p.r(0)
  8509. });
  8510. FUI_NS.__export();
  8511. }
  8512. };
  8513. //src/base/extensions.js
  8514. /**
  8515. * 扩展模块暴露
  8516. */
  8517. _p[2] = {
  8518. value: function(require) {
  8519. var FUI_NS = _p.r(11);
  8520. FUI_NS.___register({
  8521. TablePicker: _p.r(17)
  8522. });
  8523. }
  8524. };
  8525. //src/base/jhtmls.js
  8526. /**
  8527. * jhtmls模板引擎
  8528. */
  8529. _p[3] = {
  8530. value: function() {
  8531. /* global jhtmls: true */
  8532. return jhtmls;
  8533. }
  8534. };
  8535. //src/base/jquery.js
  8536. /**
  8537. * jquery模块封装
  8538. */
  8539. _p[4] = {
  8540. value: function(require) {
  8541. return window.jQuery;
  8542. }
  8543. };
  8544. //src/base/kit/class.js
  8545. /**
  8546. * @description 创建一个类
  8547. * @param {String} fullClassName 类全名,包括命名空间。
  8548. * @param {Plain} defines 要创建的类的特性
  8549. * defines.constructor {Function} 类的构造函数,实例化的时候会被调用。
  8550. * defines.base {String} 基类的名称。名称要使用全名。(因为base是javascript未来保留字,所以不用base)
  8551. * defines.mixin {Array<String>} 要混合到新类的类集合
  8552. * defines.<method> {Function} 其他类方法
  8553. *
  8554. * TODO:
  8555. * Mixin 构造函数调用支持
  8556. */
  8557. _p[5] = {
  8558. value: function(require, exports) {
  8559. // just to bind context
  8560. Function.prototype.bind = Function.prototype.bind || function(thisObj) {
  8561. var args = Array.prototype.slice.call(arguments, 1);
  8562. return this.apply(thisObj, args);
  8563. };
  8564. // 所有类的基类
  8565. function Class() {}
  8566. Class.__KityClassName = "Class";
  8567. // 提供 base 调用支持
  8568. Class.prototype.base = function(name) {
  8569. var caller = arguments.callee.caller;
  8570. var method = caller.__KityMethodClass.__KityBaseClass.prototype[name];
  8571. return method.apply(this, Array.prototype.slice.call(arguments, 1));
  8572. };
  8573. // 直接调用 base 类的同名方法
  8574. Class.prototype.callBase = function() {
  8575. var caller = arguments.callee.caller;
  8576. var method = caller.__KityMethodClass.__KityBaseClass.prototype[caller.__KityMethodName];
  8577. return method.apply(this, arguments);
  8578. };
  8579. Class.prototype.mixin = function(name) {
  8580. var caller = arguments.callee.caller;
  8581. var mixins = caller.__KityMethodClass.__KityMixins;
  8582. if (!mixins) {
  8583. return this;
  8584. }
  8585. var method = mixins[name];
  8586. return method.apply(this, Array.prototype.slice.call(arguments, 1));
  8587. };
  8588. Class.prototype.callMixin = function() {
  8589. var caller = arguments.callee.caller;
  8590. var methodName = caller.__KityMethodName;
  8591. var mixins = caller.__KityMethodClass.__KityMixins;
  8592. if (!mixins) {
  8593. return this;
  8594. }
  8595. var method = mixins[methodName];
  8596. if (methodName == "constructor") {
  8597. for (var i = 0, l = method.length; i < l; i++) {
  8598. method[i].call(this);
  8599. }
  8600. return this;
  8601. } else {
  8602. return method.apply(this, arguments);
  8603. }
  8604. };
  8605. Class.prototype.pipe = function(fn) {
  8606. if (typeof fn == "function") {
  8607. fn.call(this, this);
  8608. }
  8609. return this;
  8610. };
  8611. Class.prototype.getType = function() {
  8612. return this.__KityClassName;
  8613. };
  8614. Class.prototype.getClass = function() {
  8615. return this.constructor;
  8616. };
  8617. // 检查基类是否调用了父类的构造函数
  8618. // 该检查是弱检查,假如调用的代码被注释了,同样能检查成功(这个特性可用于知道建议调用,但是出于某些原因不想调用的情况)
  8619. function checkBaseConstructorCall(targetClass, classname) {
  8620. var code = targetClass.toString();
  8621. if (!/this\.callBase/.test(code)) {
  8622. throw new Error(classname + " : 类构造函数没有调用父类的构造函数!为了安全,请调用父类的构造函数");
  8623. }
  8624. }
  8625. var KITY_INHERIT_FLAG = "__KITY_INHERIT_FLAG_" + +new Date();
  8626. function inherit(constructor, BaseClass, classname) {
  8627. var KityClass = eval("(function " + classname + "( __inherit__flag ) {" + "if( __inherit__flag != KITY_INHERIT_FLAG ) {" + "KityClass.__KityConstructor.apply(this, arguments);" + "}" + "this.__KityClassName = KityClass.__KityClassName;" + "})||0");
  8628. KityClass.__KityConstructor = constructor;
  8629. KityClass.prototype = new BaseClass(KITY_INHERIT_FLAG);
  8630. for (var methodName in BaseClass.prototype) {
  8631. if (BaseClass.prototype.hasOwnProperty(methodName) && methodName.indexOf("__Kity") !== 0) {
  8632. KityClass.prototype[methodName] = BaseClass.prototype[methodName];
  8633. }
  8634. }
  8635. KityClass.prototype.constructor = KityClass;
  8636. return KityClass;
  8637. }
  8638. function mixin(NewClass, mixins) {
  8639. if (false === mixins instanceof Array) {
  8640. return NewClass;
  8641. }
  8642. var i, length = mixins.length, proto, method;
  8643. NewClass.__KityMixins = {
  8644. constructor: []
  8645. };
  8646. for (i = 0; i < length; i++) {
  8647. proto = mixins[i].prototype;
  8648. for (method in proto) {
  8649. if (false === proto.hasOwnProperty(method) || method.indexOf("__Kity") === 0) {
  8650. continue;
  8651. }
  8652. if (method === "constructor") {
  8653. // constructor 特殊处理
  8654. NewClass.__KityMixins.constructor.push(proto[method]);
  8655. } else {
  8656. NewClass.prototype[method] = NewClass.__KityMixins[method] = proto[method];
  8657. }
  8658. }
  8659. }
  8660. return NewClass;
  8661. }
  8662. function extend(BaseClass, extension) {
  8663. if (extension.__KityClassName) {
  8664. extension = extension.prototype;
  8665. }
  8666. for (var methodName in extension) {
  8667. if (extension.hasOwnProperty(methodName) && methodName.indexOf("__Kity") && methodName != "constructor") {
  8668. var method = BaseClass.prototype[methodName] = extension[methodName];
  8669. method.__KityMethodClass = BaseClass;
  8670. method.__KityMethodName = methodName;
  8671. }
  8672. }
  8673. return BaseClass;
  8674. }
  8675. Class.prototype._accessProperty = function() {
  8676. return this._propertyRawData || (this._propertyRawData = {});
  8677. };
  8678. exports.createClass = function(classname, defines) {
  8679. var constructor, NewClass, BaseClass;
  8680. if (arguments.length === 1) {
  8681. defines = arguments[0];
  8682. classname = "AnonymousClass";
  8683. }
  8684. BaseClass = defines.base || Class;
  8685. if (defines.hasOwnProperty("constructor")) {
  8686. constructor = defines.constructor;
  8687. if (BaseClass != Class) {
  8688. checkBaseConstructorCall(constructor, classname);
  8689. }
  8690. } else {
  8691. constructor = function() {
  8692. this.callBase.apply(this, arguments);
  8693. this.callMixin.apply(this, arguments);
  8694. };
  8695. }
  8696. NewClass = inherit(constructor, BaseClass, classname);
  8697. NewClass = mixin(NewClass, defines.mixins);
  8698. NewClass.__KityClassName = constructor.__KityClassName = classname;
  8699. NewClass.__KityBaseClass = constructor.__KityBaseClass = BaseClass;
  8700. NewClass.__KityMethodName = constructor.__KityMethodName = "constructor";
  8701. NewClass.__KityMethodClass = constructor.__KityMethodClass = NewClass;
  8702. // 下面这些不需要拷贝到原型链上
  8703. delete defines.mixins;
  8704. delete defines.constructor;
  8705. delete defines.base;
  8706. NewClass = extend(NewClass, defines);
  8707. return NewClass;
  8708. };
  8709. exports.extendClass = extend;
  8710. }
  8711. };
  8712. //src/base/kit/common.js
  8713. /**
  8714. * 通用工具包
  8715. */
  8716. _p[6] = {
  8717. value: function(require) {
  8718. var $ = _p.r(4), __marker = "__fui__marker__" + +new Date();
  8719. return {
  8720. isElement: function(target) {
  8721. return target.nodeType === 1;
  8722. },
  8723. getMarker: function() {
  8724. return __marker;
  8725. },
  8726. getRect: function(node) {
  8727. var rect = node.getBoundingClientRect();
  8728. return {
  8729. width: rect.width,
  8730. height: rect.height,
  8731. top: rect.top,
  8732. bottom: rect.bottom,
  8733. left: rect.left,
  8734. right: rect.right
  8735. };
  8736. },
  8737. getBound: function(node) {
  8738. var w = 0, h = 0;
  8739. if (node.tagName.toLowerCase() === "body") {
  8740. h = $(this.getView(node));
  8741. w = h.width();
  8742. h = h.height();
  8743. return {
  8744. top: 0,
  8745. left: 0,
  8746. bottom: h,
  8747. right: w,
  8748. width: w,
  8749. height: h
  8750. };
  8751. } else {
  8752. return this.getRect(node);
  8753. }
  8754. },
  8755. getView: function(node) {
  8756. return node.ownerDocument.defaultView || node.ownerDocument.parentWindow;
  8757. }
  8758. };
  8759. }
  8760. };
  8761. //src/base/kit/compile.js
  8762. /**
  8763. * 模板编译器
  8764. */
  8765. _p[7] = {
  8766. value: function(require) {
  8767. var jhtmls = _p.r(3), $ = _p.r(4);
  8768. var Helper = {
  8769. forEach: function(arras, cb) {
  8770. $.each(arras, function(i, item) {
  8771. cb.call(null, i, item);
  8772. });
  8773. }
  8774. };
  8775. return {
  8776. compile: function(tpl, data) {
  8777. tpl = $.trim(tpl);
  8778. if (tpl.length === 0) {
  8779. return "";
  8780. }
  8781. return jhtmls.render(tpl, data, Helper);
  8782. }
  8783. };
  8784. }
  8785. };
  8786. //src/base/kit/draggable.js
  8787. /**
  8788. * Draggable Lib
  8789. */
  8790. _p[8] = {
  8791. value: function(require, exports) {
  8792. var $ = _p.r(4), common = _p.r(6), DEFAULT_OPTIONS = {
  8793. handler: null,
  8794. target: null,
  8795. axis: "all",
  8796. range: null
  8797. };
  8798. function Draggable(options) {
  8799. this.__options = $.extend({}, DEFAULT_OPTIONS, options);
  8800. this.__started = false;
  8801. this.__point = {
  8802. x: 0,
  8803. y: 0
  8804. };
  8805. this.__location = {
  8806. x: 0,
  8807. y: 0
  8808. };
  8809. this.__range = {
  8810. top: 0,
  8811. left: 0,
  8812. bottom: 0,
  8813. right: 0
  8814. };
  8815. }
  8816. $.extend(Draggable.prototype, {
  8817. bind: function(target) {
  8818. if (target) {
  8819. this.__options.target = target;
  8820. }
  8821. if (!this.__options.target) {
  8822. throw new Error("target unset");
  8823. }
  8824. this.__target = this.__options.target;
  8825. this.__handler = this.__options.handler;
  8826. this.__rangeNode = this.__options.range;
  8827. this.__initOptions();
  8828. this.__initEnv();
  8829. this.__initEvent();
  8830. },
  8831. __initEvent: function() {
  8832. var handler = this.__handler, _self = this;
  8833. $(handler).on("mousedown", function(e) {
  8834. if (e.which !== 1) {
  8835. return;
  8836. }
  8837. var location = common.getRect(handler);
  8838. e.preventDefault();
  8839. _self.__started = true;
  8840. _self.__point = {
  8841. x: e.clientX,
  8842. y: e.clientY
  8843. };
  8844. _self.__location = {
  8845. x: location.left,
  8846. y: location.top
  8847. };
  8848. _self.__range = _self.__getRange();
  8849. });
  8850. $(handler.ownerDocument).on("mousemove", function(e) {
  8851. if (!_self.__started) {
  8852. return;
  8853. }
  8854. var x = e.clientX, y = e.clientY;
  8855. if (_self.__allowAxisX) {
  8856. _self.__xMove(x);
  8857. }
  8858. if (_self.__allowAxisY) {
  8859. _self.__yMove(y);
  8860. }
  8861. }).on("mouseup", function(e) {
  8862. _self.__started = false;
  8863. });
  8864. },
  8865. __xMove: function(x) {
  8866. var diff = x - this.__point.x;
  8867. diff = this.__location.x + diff;
  8868. if (diff < this.__range.left) {
  8869. diff = this.__range.left;
  8870. } else if (diff > this.__range.right) {
  8871. diff = this.__range.right;
  8872. }
  8873. this.__target.style.left = diff + "px";
  8874. },
  8875. __yMove: function(y) {
  8876. var diff = y - this.__point.y;
  8877. diff = this.__location.y + diff;
  8878. if (diff < this.__range.top) {
  8879. diff = this.__range.top;
  8880. } else if (diff > this.__range.bottom) {
  8881. diff = this.__range.bottom;
  8882. }
  8883. this.__target.style.top = diff + "px";
  8884. },
  8885. __initEnv: function() {
  8886. var $handler = $(this.__handler);
  8887. $handler.css("cursor", "move");
  8888. },
  8889. __initOptions: function() {
  8890. if (!this.__handler) {
  8891. this.__handler = this.__target;
  8892. }
  8893. if (!this.__rangeNode) {
  8894. this.__rangeNode = this.__options.target.ownerDocument.body;
  8895. }
  8896. this.__allowAxisX = this.__options.axis !== "y";
  8897. this.__allowAxisY = this.__options.axis !== "x";
  8898. },
  8899. __getRange: function() {
  8900. var range = this.__rangeNode, targetRect = common.getRect(this.__target);
  8901. if (range.tagName.toLowerCase() === "body") {
  8902. range = $(this.__rangeNode.ownerDocument);
  8903. range = {
  8904. top: 0,
  8905. left: 0,
  8906. bottom: range.height(),
  8907. right: range.width()
  8908. };
  8909. } else {
  8910. range = common.getRect(range);
  8911. }
  8912. return {
  8913. top: range.top,
  8914. left: range.left,
  8915. bottom: range.bottom - targetRect.height,
  8916. right: range.right - targetRect.width
  8917. };
  8918. }
  8919. });
  8920. return function(options) {
  8921. return new Draggable(options);
  8922. };
  8923. }
  8924. };
  8925. //src/base/kit/extend.js
  8926. /**
  8927. * 弥补jQuery的extend在克隆对象和数组时存在的问题
  8928. */
  8929. _p[9] = {
  8930. value: function(require) {
  8931. var $ = _p.r(4);
  8932. function extend(target) {
  8933. var isPlainObject = false, isArray = false, sourceObj = null;
  8934. if (arguments.length === 1) {
  8935. return copy(target);
  8936. }
  8937. $.each([].slice.call(arguments, 1), function(i, source) {
  8938. for (var key in source) {
  8939. sourceObj = source[key];
  8940. if (!source.hasOwnProperty(key)) {
  8941. continue;
  8942. }
  8943. isPlainObject = $.isPlainObject(sourceObj);
  8944. isArray = $.isArray(sourceObj);
  8945. if (!isPlainObject && !isArray) {
  8946. target[key] = source[key];
  8947. } else if (isPlainObject) {
  8948. if (!$.isPlainObject(target[key])) {
  8949. target[key] = {};
  8950. }
  8951. target[key] = extend(target[key], sourceObj);
  8952. } else if (isArray) {
  8953. target[key] = extend(sourceObj);
  8954. }
  8955. }
  8956. });
  8957. return target;
  8958. }
  8959. function copy(target) {
  8960. var tmp = null;
  8961. if ($.isPlainObject(target)) {
  8962. return extend({}, target);
  8963. } else if ($.isArray(target)) {
  8964. tmp = [];
  8965. $.each(target, function(index, item) {
  8966. if ($.isPlainObject(item) || $.isArray(item)) {
  8967. tmp.push(copy(item));
  8968. } else {
  8969. tmp.push(item);
  8970. }
  8971. });
  8972. return tmp;
  8973. } else {
  8974. return target;
  8975. }
  8976. }
  8977. return extend;
  8978. }
  8979. };
  8980. //src/base/kit/widget.js
  8981. /**
  8982. * 构件相关工具方法
  8983. */
  8984. _p[10] = {
  8985. value: function(require) {
  8986. return {
  8987. isContainer: function(widget) {
  8988. return widget.__widgetType === "container";
  8989. }
  8990. };
  8991. }
  8992. };
  8993. //src/base/ns.js
  8994. /**
  8995. * FUI名称空间
  8996. */
  8997. _p[11] = {
  8998. value: function() {
  8999. // 容纳所有构件的实例池
  9000. var WIDGET_POOL = {};
  9001. return {
  9002. widgets: WIDGET_POOL,
  9003. /**
  9004. * 暴露命名空间本身
  9005. * @private
  9006. */
  9007. __export: function() {
  9008. window.FUI = this;
  9009. },
  9010. ___register: function(widgetName, widget) {
  9011. if (typeof widgetName === "string") {
  9012. this[widgetName] = widget;
  9013. } else {
  9014. widget = widgetName;
  9015. for (var key in widget) {
  9016. if (widget.hasOwnProperty(key)) {
  9017. this[key] = widget[key];
  9018. }
  9019. }
  9020. }
  9021. },
  9022. __registerInstance: function(widget) {
  9023. WIDGET_POOL[widget.getId()] = widget;
  9024. }
  9025. };
  9026. }
  9027. };
  9028. //src/base/sysconf.js
  9029. /**
  9030. * UI系统配置
  9031. */
  9032. _p[12] = {
  9033. value: function(require) {
  9034. var NS = _p.r(11);
  9035. return {
  9036. classPrefix: "fui-",
  9037. layout: {
  9038. TOP: "top",
  9039. LEFT: "left",
  9040. BOTTOM: "bottom",
  9041. RIGHT: "right",
  9042. CENTER: "center",
  9043. MIDDLE: "middle",
  9044. // 内部定位
  9045. LEFT_TOP: "left-top",
  9046. RIGHT_TOP: "right-top",
  9047. LEFT_BOTTOM: "left-bottom",
  9048. RIGHT_BOTTOM: "right-bottom"
  9049. },
  9050. allowFocus: !!NS.ALLOW_FOCUS,
  9051. control: {
  9052. input: 1,
  9053. textarea: 1,
  9054. button: 1,
  9055. select: 1,
  9056. option: 1,
  9057. object: 1,
  9058. embed: 1
  9059. }
  9060. };
  9061. }
  9062. };
  9063. //src/base/utils.js
  9064. /**
  9065. * utils类包, 提供常用操作的封装,补充jQuery的不足
  9066. */
  9067. _p[13] = {
  9068. value: function(require) {
  9069. var $ = _p.r(4), Utils = {
  9070. Tpl: _p.r(7),
  9071. Widget: _p.r(10),
  9072. createDraggable: _p.r(8)
  9073. };
  9074. return $.extend(Utils, _p.r(6), _p.r(5));
  9075. }
  9076. };
  9077. //src/ext/word/tpl/t-picker.js
  9078. _p[14] = {
  9079. value: function() {
  9080. return '<div unselectable="on" class="fui-t-picker"></div>\n';
  9081. }
  9082. };
  9083. //src/ext/word/tpl/table-picker.js
  9084. _p[15] = {
  9085. value: function() {
  9086. return '<div unselectable="on" class="fui-table-picker"></div>\n';
  9087. }
  9088. };
  9089. //src/ext/word/widget/t-picker.js
  9090. /**
  9091. * TPicker -- table 选择器
  9092. */
  9093. _p[16] = {
  9094. value: function(require) {
  9095. var $ = _p.r(4), CONF = _p.r(12), tpl = _p.r(14);
  9096. return _p.r(13).createClass("TPicker", {
  9097. base: _p.r(60),
  9098. constructor: function(options) {
  9099. var defaultOptions = {
  9100. // 10行 10列
  9101. row: 10,
  9102. col: 10
  9103. };
  9104. options = $.extend({}, defaultOptions, options);
  9105. this.callBase(options);
  9106. },
  9107. __initOptions: function() {
  9108. this.callBase();
  9109. this.widgetName = "TPicker";
  9110. this.__tpl = tpl;
  9111. // 背板
  9112. this.__backplane = null;
  9113. },
  9114. __render: function() {
  9115. this.callBase();
  9116. this.__backplane = this.__createBackplane();
  9117. this.__element.appendChild(this.__backplane);
  9118. },
  9119. __initEvent: function() {
  9120. var _self = this;
  9121. var info = {};
  9122. this.callBase();
  9123. $(this.__backplane).delegate("td", "mousemove", function(e) {
  9124. info = e.target.getAttribute("data-index").split(",");
  9125. info = {
  9126. row: parseInt(info[0], 10),
  9127. col: parseInt(info[1], 10)
  9128. };
  9129. _self.__update(info.row, info.col);
  9130. });
  9131. $(this.__backplane).on("click", function(e) {
  9132. _self.__select(info.row, info.col);
  9133. });
  9134. },
  9135. __select: function(row, col) {
  9136. this.trigger("pickerselect", {
  9137. row: row,
  9138. col: col
  9139. });
  9140. },
  9141. __update: function(row, col) {
  9142. var tr = null, rowCount = this.__options.row, colCount = this.__options.col, className = CONF.classPrefix + "table-picker-hoverin";
  9143. for (var i = 0; i < rowCount; i++) {
  9144. tr = this.__backplane.rows[i];
  9145. for (var j = 0; j < colCount; j++) {
  9146. if (i <= row && j <= col) {
  9147. tr.cells[j].className = className;
  9148. } else {
  9149. tr.cells[j].className = "";
  9150. }
  9151. }
  9152. }
  9153. this.trigger("pickerhover", {
  9154. row: row,
  9155. col: col
  9156. });
  9157. },
  9158. __createBackplane: function() {
  9159. var tpl = [], tmp = null;
  9160. for (var i = 0, len = this.__options.row; i < len; i++) {
  9161. tmp = [];
  9162. for (var j = 0, jlen = this.__options.col; j < jlen; j++) {
  9163. tmp.push('<td data-index="' + i + "," + j + '"></td>');
  9164. }
  9165. tpl.push("<tr>" + tmp.join("") + "</tr>");
  9166. }
  9167. tpl = $("<table><tbody>" + tpl.join("") + "</tbody></table>");
  9168. tpl.addClass(CONF.classPrefix + "t-picker-table");
  9169. return tpl[0];
  9170. }
  9171. });
  9172. }
  9173. };
  9174. //src/ext/word/widget/table-picker.js
  9175. /**
  9176. * Table选择器构件
  9177. */
  9178. _p[17] = {
  9179. value: function(require) {
  9180. var $ = _p.r(4), CONF = _p.r(12), tpl = _p.r(15), Label = _p.r(48), TPicker = _p.r(16), Button = _p.r(37), PPanel = _p.r(54), Mask = _p.r(49);
  9181. return _p.r(13).createClass("TablePicker", {
  9182. base: _p.r(60),
  9183. constructor: function(options) {
  9184. var defaultOptions = {
  9185. button: null,
  9186. row: 10,
  9187. col: 10
  9188. };
  9189. options = $.extend({}, defaultOptions, options);
  9190. this.callBase(options);
  9191. },
  9192. open: function() {
  9193. this.__panelWidget.show();
  9194. this.__maskWidget.show();
  9195. },
  9196. close: function() {
  9197. this.__panelWidget.hide();
  9198. this.__maskWidget.hide();
  9199. },
  9200. // Overload
  9201. appendTo: function(container) {
  9202. container.appendChild(this.__buttonWidget.getElement());
  9203. },
  9204. getButton: function() {
  9205. return this.__buttonWidget;
  9206. },
  9207. __initOptions: function() {
  9208. this.callBase();
  9209. this.widgetName = "TablePicker";
  9210. this.__tpl = tpl;
  9211. this.__pickerWidget = null;
  9212. this.__labelWidget = null;
  9213. this.__buttonWidget = null;
  9214. this.__panelWidget = null;
  9215. this.__maskWidget = null;
  9216. },
  9217. __render: function() {
  9218. this.callBase();
  9219. this.__pickerWidget = new TPicker(this.__options);
  9220. this.__labelWidget = new Label({
  9221. text: "插入表格"
  9222. });
  9223. this.__buttonWidget = new Button(this.__options.button);
  9224. this.__panelWidget = new PPanel({
  9225. className: CONF.classPrefix + "table-picker-panel",
  9226. column: true,
  9227. resize: "none"
  9228. });
  9229. this.__maskWidget = new Mask();
  9230. this.__panelWidget.appendWidget(this.__labelWidget);
  9231. this.__panelWidget.appendWidget(this.__pickerWidget);
  9232. this.__panelWidget.positionTo(this.__buttonWidget);
  9233. },
  9234. __initEvent: function() {
  9235. var _self = this;
  9236. this.callBase();
  9237. this.__buttonWidget.on("btnclick", function(e) {
  9238. _self.open();
  9239. });
  9240. this.__maskWidget.on("maskclick", function(e) {
  9241. _self.close();
  9242. });
  9243. this.__pickerWidget.on("pickerhover", function(e, info) {
  9244. var row = info.row + 1, col = info.col + 1;
  9245. _self.__labelWidget.setText(row + "x" + col + " 表格");
  9246. }).on("pickerselect", function(e, info) {
  9247. var row = info.row + 1, col = info.col + 1;
  9248. _self.close();
  9249. _self.trigger("pickerselect", {
  9250. row: row,
  9251. col: col
  9252. });
  9253. });
  9254. },
  9255. __createBackplane: function() {
  9256. var tpl = [], tmp = null;
  9257. for (var i = 0, len = this.__options.row; i < len; i++) {
  9258. tmp = [];
  9259. for (var j = 0, jlen = this.__options.col; j < jlen; j++) {
  9260. tmp.push('<td data-index="' + i + "," + j + '"></td>');
  9261. }
  9262. tpl.push("<tr>" + tmp.join("") + "</tr>");
  9263. }
  9264. tpl = $("<table><tbody>" + tpl.join("") + "</tbody></table>");
  9265. tpl.addClass(CONF.classPrefix + "t-picker-table");
  9266. return tpl[0];
  9267. }
  9268. });
  9269. }
  9270. };
  9271. //src/tpl/button-menu.js
  9272. _p[18] = {
  9273. value: function() {
  9274. return '<div unselectable="on" class="fui-button-menu"></div>\n';
  9275. }
  9276. };
  9277. //src/tpl/button.js
  9278. _p[19] = {
  9279. value: function() {
  9280. return '<div unselectable="on" class="fui-button"></div>\n';
  9281. }
  9282. };
  9283. //src/tpl/colorpicker.js
  9284. _p[20] = {
  9285. value: function() {
  9286. return '<div unselectable="on" class="fui-colorpicker-container">\n' + '<div unselectable="on" class="fui-colorpicker-toolbar">\n' + '<div unselectable="on" class="fui-colorpicker-preview"></div>\n' + '<div unselectable="on" class="fui-colorpicker-clear">$clearText</div>\n' + "</div>\n" + '<div unselectable="on" class="fui-colorpicker-title">$commonText</div>\n' + '<div unselectable="on" class="fui-colorpicker-commoncolor">\n' + "helper.forEach( commonColor, function ( index, colors ) {\n" + '<div unselectable="on" class="fui-colorpicker-colors fui-colorpicker-colors-line$index">\n' + "helper.forEach( colors, function( i, color ) {\n" + '<span unselectable="on" class="fui-colorpicker-item" style="background-color: $color; border-color: #{color.toLowerCase() == \'#ffffff\' ? \'#eeeeee\': color};" data-color="$color"></span>\n' + "});\n" + "</div>\n" + "} );\n" + "</div>\n" + '<div unselectable="on" class="fui-colorpicker-title">$standardText</div>\n' + '<div unselectable="on" class="fui-colorpicker-standardcolor fui-colorpicker-colors">\n' + "helper.forEach( standardColor, function ( i, color ) {\n" + '<span unselectable="on" class="fui-colorpicker-item" style="background-color: $color; border-color: $color;" data-color="$color"></span>\n' + "} );\n" + "</div>\n" + "</div>\n";
  9287. }
  9288. };
  9289. //src/tpl/dialog.js
  9290. _p[21] = {
  9291. value: function() {
  9292. return '<div unselectable="on" class="fui-dialog-wrap">\n' + '<div unselectable="on" class="fui-dialog-head">\n' + '<h1 unselectable="on" class="fui-dialog-caption">$caption</h1>\n' + "</div>\n" + '<div unselectable="on" class="fui-dialog-body"></div>\n' + '<div unselectable="on" class="fui-dialog-foot"></div>\n' + "</div>\n";
  9293. }
  9294. };
  9295. //src/tpl/drop-panel.js
  9296. _p[22] = {
  9297. value: function() {
  9298. return "<div unselectable=\"on\" class=\"fui-drop-panel\" #{ text ? 'title=\"' + m.text + '\"' : '' }></div>\n";
  9299. }
  9300. };
  9301. //src/tpl/icon.js
  9302. _p[23] = {
  9303. value: function() {
  9304. return '<div unselectable="on" class="fui-icon" >\n' + "if ( this.img ) {\n" + '<img unselectable="on" src="#{this.img}" >\n' + "}\n" + "</div>\n";
  9305. }
  9306. };
  9307. //src/tpl/input-button.js
  9308. _p[24] = {
  9309. value: function() {
  9310. return '<div unselectable="on" class="fui-input-button"></div>\n';
  9311. }
  9312. };
  9313. //src/tpl/input-menu.js
  9314. _p[25] = {
  9315. value: function() {
  9316. return '<div unselectable="on" class="fui-input-menu"></div>\n';
  9317. }
  9318. };
  9319. //src/tpl/input.js
  9320. _p[26] = {
  9321. value: function() {
  9322. return '<input unselectable="on" class="fui-input" autocomplete="off" !#{ value ? \'value="\' + value + \'"\' : \'\'}>\n';
  9323. }
  9324. };
  9325. //src/tpl/item.js
  9326. _p[27] = {
  9327. value: function() {
  9328. return "<div unselectable=\"on\" class=\"fui-item!#{ selected ? ' fui-item-selected': '' }\" ></div>\n";
  9329. }
  9330. };
  9331. //src/tpl/label.js
  9332. _p[28] = {
  9333. value: function() {
  9334. return '<div unselectable="on" class="fui-label">$text</div>\n';
  9335. }
  9336. };
  9337. //src/tpl/mask.js
  9338. _p[29] = {
  9339. value: function() {
  9340. return '<div unselectable="on" class="fui-mask" style="background-color: $bgcolor; opacity: $opacity;"></div>\n';
  9341. }
  9342. };
  9343. //src/tpl/panel.js
  9344. _p[30] = {
  9345. value: function() {
  9346. return '<div unselectable="on" class="fui-panel"></div>\n';
  9347. }
  9348. };
  9349. //src/tpl/separator.js
  9350. _p[31] = {
  9351. value: function() {
  9352. return '<div unselectable="on" class="fui-separator"></div>\n';
  9353. }
  9354. };
  9355. //src/tpl/spin-button.js
  9356. _p[32] = {
  9357. value: function() {
  9358. return '<div unselectable="on" class="fui-spin-button"></div>\n';
  9359. }
  9360. };
  9361. //src/tpl/tabs.js
  9362. _p[33] = {
  9363. value: function() {
  9364. return '<div unselectable="on" class="fui-tabs">\n' + '<div unselectable="on" class="fui-tabs-button-wrap"></div>\n' + '<div unselectable="on" class="fui-tabs-panel-wrap"></div>\n' + "</div>\n";
  9365. }
  9366. };
  9367. //src/widget/button-menu.js
  9368. /**
  9369. * Button对象
  9370. * 通用按钮构件
  9371. */
  9372. _p[34] = {
  9373. value: function(require) {
  9374. var $ = _p.r(4), CONF = _p.r(12), tpl = _p.r(18), Button = _p.r(37), Menu = _p.r(50), Mask = _p.r(49), LAYOUT = CONF.layout;
  9375. return _p.r(13).createClass("ButtonMenu", {
  9376. base: _p.r(60),
  9377. constructor: function(options) {
  9378. var defaultOptions = {
  9379. // item选项
  9380. menu: null,
  9381. mask: null,
  9382. buttons: [],
  9383. selected: -1,
  9384. layout: LAYOUT.RIGHT
  9385. };
  9386. options = $.extend({}, defaultOptions, options);
  9387. this.callBase(options);
  9388. },
  9389. open: function() {
  9390. this.__openState = true;
  9391. this.__maskWidget.show();
  9392. this.__menuWidget.show();
  9393. this.addClass(CONF.classPrefix + "button-active");
  9394. },
  9395. close: function() {
  9396. this.__openState = false;
  9397. this.__maskWidget.hide();
  9398. this.__menuWidget.hide();
  9399. this.removeClass(CONF.classPrefix + "button-active");
  9400. },
  9401. isOpen: function() {
  9402. return !!this.__openState;
  9403. },
  9404. getSelected: function() {
  9405. return this.__menuWidget.getSelected();
  9406. },
  9407. getSelectedItem: function() {
  9408. return this.__menuWidget.getSelectedItem();
  9409. },
  9410. getValue: function() {
  9411. return this.getSelectedItem().getValue();
  9412. },
  9413. __render: function() {
  9414. this.callBase();
  9415. this.__initButtons();
  9416. this.__menuWidget = new Menu(this.__options.menu);
  9417. this.__maskWidget = new Mask(this.__options.mask);
  9418. this.__menuWidget.positionTo(this.__element);
  9419. this.__menuWidget.appendTo(this.__element.ownerDocument.body);
  9420. },
  9421. __initOptions: function() {
  9422. this.callBase();
  9423. this.widgetName = "ButtonMenu";
  9424. this.__tpl = tpl;
  9425. this.__buttonWidgets = null;
  9426. this.__menuWidget = null;
  9427. this.__maskWidget = null;
  9428. this.__openState = false;
  9429. if (this.__options.selected !== -1) {
  9430. this.__options.menu.selected = this.__options.selected;
  9431. }
  9432. },
  9433. __initButtons: function() {
  9434. var buttons = [], ele = this.__element, btn = null, lastIndex = this.__options.buttons.length - 1;
  9435. if (this.__options.layout === LAYOUT.TOP || this.__options.layout === LAYOUT.LEFT) {
  9436. btn = new Button(this.__options.buttons[lastIndex]);
  9437. btn.appendTo(ele);
  9438. } else {
  9439. lastIndex = -1;
  9440. }
  9441. $.each(this.__options.buttons, function(index, options) {
  9442. if (lastIndex !== index) {
  9443. var button = new Button(options);
  9444. button.appendTo(ele);
  9445. buttons.push(button);
  9446. } else {
  9447. buttons.push(btn);
  9448. }
  9449. });
  9450. this.addClass(CONF.classPrefix + "layout-" + this.__options.layout);
  9451. buttons[buttons.length - 1].addClass(CONF.classPrefix + "open-btn");
  9452. this.__buttonWidgets = buttons;
  9453. },
  9454. __initEvent: function() {
  9455. var lastBtn = this.__buttonWidgets[this.__buttonWidgets.length - 1], _self = this;
  9456. this.callBase();
  9457. lastBtn.on("click", function(e) {
  9458. _self.open();
  9459. });
  9460. this.__maskWidget.on("maskclick", function() {
  9461. _self.close();
  9462. });
  9463. this.__menuWidget.on("select", function(e, info) {
  9464. e.stopPropagation();
  9465. _self.close();
  9466. _self.trigger("select", info);
  9467. }).on("change", function(e, info) {
  9468. _self.trigger("change", info);
  9469. });
  9470. this.on("btnclick", function(e) {
  9471. e.stopPropagation();
  9472. var btnIndex = $.inArray(e.widget, this.__buttonWidgets);
  9473. if (btnIndex > -1 && btnIndex < this.__buttonWidgets.length - 1) {
  9474. this.trigger("buttonclick", {
  9475. button: this.__buttonWidgets[btnIndex]
  9476. });
  9477. }
  9478. });
  9479. }
  9480. });
  9481. }
  9482. };
  9483. //src/widget/button-set-menu.js
  9484. /**
  9485. * InputMenu构件
  9486. * 可接受输入的下拉菜单构件
  9487. */
  9488. _p[35] = {
  9489. value: function(require) {
  9490. var $ = _p.r(4), tpl = _p.r(25), InputButton = _p.r(43), Menu = _p.r(50), Mask = _p.r(49), Utils = _p.r(13);
  9491. return _p.r(13).createClass("InputMenu", {
  9492. base: _p.r(60),
  9493. constructor: function(options) {
  9494. var marker = Utils.getMarker();
  9495. this.callBase(marker);
  9496. var defaultOptions = {
  9497. input: null,
  9498. menu: null,
  9499. mask: null
  9500. };
  9501. this.__extendOptions(defaultOptions, options);
  9502. this.widgetName = "InputMenu";
  9503. this.__tpl = tpl;
  9504. // 最后输入时间
  9505. this.__lastTime = 0;
  9506. // 最后选中的记录
  9507. this.__lastSelect = null;
  9508. this.__inputWidget = null;
  9509. this.__menuWidget = null;
  9510. this.__maskWidget = null;
  9511. // menu状态, 记录是否已经append到dom树上
  9512. this.__menuState = false;
  9513. if (options !== marker) {
  9514. this.__render();
  9515. }
  9516. },
  9517. select: function(index) {
  9518. this.__menuWidget.select(index);
  9519. },
  9520. setValue: function(value) {
  9521. this.__inputWidget.setValue(value);
  9522. return this;
  9523. },
  9524. getValue: function() {
  9525. return this.__inputWidget.getValue();
  9526. },
  9527. __render: function() {
  9528. if (this.__rendered) {
  9529. return this;
  9530. }
  9531. this.__inputWidget = new InputButton(this.__options.input);
  9532. this.__menuWidget = new Menu(this.__options.menu);
  9533. this.__maskWidget = new Mask(this.__options.mask);
  9534. this.callBase();
  9535. this.__inputWidget.appendTo(this.__element);
  9536. this.__menuWidget.positionTo(this.__inputWidget);
  9537. this.__initInputMenuEvent();
  9538. },
  9539. open: function() {
  9540. this.__maskWidget.show();
  9541. this.__menuWidget.show();
  9542. },
  9543. close: function() {
  9544. this.__maskWidget.hide();
  9545. this.__menuWidget.hide();
  9546. },
  9547. __initInputMenuEvent: function() {
  9548. var _self = this;
  9549. this.on("buttonclick", function() {
  9550. if (!this.__menuState) {
  9551. this.__appendMenu();
  9552. this.__menuState = true;
  9553. }
  9554. this.__inputWidget.unfocus();
  9555. this.open();
  9556. });
  9557. this.on("keypress", function(e) {
  9558. this.__lastTime = new Date();
  9559. });
  9560. this.on("keyup", function(e) {
  9561. if (e.keyCode !== 8 && e.keyCode !== 13 && new Date() - this.__lastTime < 500) {
  9562. this.__update();
  9563. }
  9564. });
  9565. this.on("inputcomplete", function() {
  9566. this.__inputWidget.selectRange(99999999);
  9567. this.__inputComplete();
  9568. });
  9569. this.__menuWidget.on("select", function(e, info) {
  9570. e.stopPropagation();
  9571. _self.setValue(info.value);
  9572. _self.trigger("select", info);
  9573. _self.close();
  9574. });
  9575. this.__menuWidget.on("change", function(e, info) {
  9576. e.stopPropagation();
  9577. _self.trigger("change", info);
  9578. });
  9579. // 阻止input自身的select和change事件
  9580. this.__inputWidget.on("select change", function(e) {
  9581. e.stopPropagation();
  9582. });
  9583. // mask 点击关闭
  9584. this.__maskWidget.on("maskclick", function() {
  9585. _self.close();
  9586. });
  9587. // 记录最后选中的数据
  9588. this.on("select", function(e, info) {
  9589. this.__lastSelect = info;
  9590. });
  9591. },
  9592. // 更新输入框内容
  9593. __update: function() {
  9594. var inputValue = this.getValue(), lowerCaseValue = inputValue.toLowerCase(), values = this.__getItemValues(), targetValue = null;
  9595. if (!inputValue) {
  9596. return;
  9597. }
  9598. $.each(values, function(i, val) {
  9599. if (val.toLowerCase().indexOf(lowerCaseValue) === 0) {
  9600. targetValue = val;
  9601. return false;
  9602. }
  9603. });
  9604. if (targetValue) {
  9605. this.__inputWidget.setValue(targetValue);
  9606. this.__inputWidget.selectRange(inputValue.length);
  9607. }
  9608. },
  9609. // 获取所有item的值列表
  9610. __getItemValues: function() {
  9611. var vals = [];
  9612. $.each(this.__menuWidget.getWidgets(), function(index, item) {
  9613. vals.push(item.getValue());
  9614. });
  9615. return vals;
  9616. },
  9617. // 用户输入完成
  9618. __inputComplete: function() {
  9619. var values = this.__getItemValues(), targetIndex = -1, inputValue = this.getValue(), lastSelect = this.__lastSelect;
  9620. $.each(values, function(i, val) {
  9621. if (val === inputValue) {
  9622. targetIndex = i;
  9623. return false;
  9624. }
  9625. });
  9626. this.trigger("select", {
  9627. index: targetIndex,
  9628. value: inputValue
  9629. });
  9630. if (!lastSelect || lastSelect.value !== inputValue) {
  9631. this.trigger("change", {
  9632. from: lastSelect || {
  9633. index: -1,
  9634. value: null
  9635. },
  9636. to: {
  9637. index: targetIndex,
  9638. value: inputValue
  9639. }
  9640. });
  9641. }
  9642. },
  9643. __appendMenu: function() {
  9644. this.__menuWidget.appendTo(this.__inputWidget.getElement().ownerDocument.body);
  9645. }
  9646. });
  9647. }
  9648. };
  9649. //src/widget/button-set.js
  9650. /**
  9651. * Buttonset对象
  9652. * 通用按钮构件
  9653. */
  9654. _p[36] = {
  9655. value: function(require) {
  9656. var $ = _p.r(4), CONF = _p.r(12), ToggleButton = _p.r(59);
  9657. return _p.r(13).createClass("Buttonset", {
  9658. base: _p.r(51),
  9659. constructor: function(options) {
  9660. var defaultOptions = {
  9661. // 初始选中项, -1表示不选中任何项
  9662. selected: -1
  9663. };
  9664. options = $.extend({}, defaultOptions, options);
  9665. this.callBase(options);
  9666. },
  9667. getButtons: function() {
  9668. return this.getWidgets();
  9669. },
  9670. getButton: function(index) {
  9671. return this.getWidgets()[index] || null;
  9672. },
  9673. getValue: function() {
  9674. if (this.__currentIndex > -1) {
  9675. return this.__widgets[this.__currentIndex].getValue();
  9676. }
  9677. return null;
  9678. },
  9679. getSelectedIndex: function() {
  9680. return this.__currentIndex;
  9681. },
  9682. appendButton: function() {
  9683. return this.appendWidget.apply(this, arguments);
  9684. },
  9685. insertButton: function() {
  9686. return this.insertWidget.apply(this, arguments);
  9687. },
  9688. select: function(indexOrWidget) {
  9689. if (this.__options.disabled) {
  9690. return this;
  9691. }
  9692. if (indexOrWidget instanceof ToggleButton) {
  9693. indexOrWidget = $.inArray(indexOrWidget, this.__widgets);
  9694. }
  9695. if (indexOrWidget < 0) {
  9696. return this.clearSelect();
  9697. }
  9698. indexOrWidget = this.__widgets[indexOrWidget];
  9699. this.__pressButton(indexOrWidget);
  9700. return this;
  9701. },
  9702. selectByValue: function(value) {
  9703. var values = this.__widgets.map(function(button) {
  9704. return button.getValue();
  9705. });
  9706. return this.select(values.indexOf(value));
  9707. },
  9708. clearSelect: function() {
  9709. this.__pressButton(null);
  9710. return this;
  9711. },
  9712. removeButton: function() {
  9713. return this.removeWidget.apply(this, arguments);
  9714. },
  9715. insertWidget: function(index, widget) {
  9716. var returnValue = this.callBase(index, widget);
  9717. if (returnValue === null) {
  9718. return returnValue;
  9719. }
  9720. if (index <= this.__currentIndex) {
  9721. this.__currentIndex++;
  9722. }
  9723. if (index <= this.__prevIndex) {
  9724. this.__prevIndex++;
  9725. }
  9726. return returnValue;
  9727. },
  9728. removeWidget: function(widget) {
  9729. var index = widget;
  9730. if (typeof index !== "number") {
  9731. index = this.indexOf(widget);
  9732. }
  9733. widget = this.callBase(widget);
  9734. if (index === this.__currentIndex) {
  9735. this.__currentIndex = -1;
  9736. } else if (index < this.__currentIndex) {
  9737. this.__currentIndex--;
  9738. }
  9739. if (index === this.__prevIndex) {
  9740. this.__prevIndex = -1;
  9741. } else if (index < this.__prevIndex) {
  9742. this.__prevIndex--;
  9743. }
  9744. return widget;
  9745. },
  9746. __initOptions: function() {
  9747. this.callBase();
  9748. this.widgetName = "Buttonset";
  9749. // 当前选中项
  9750. this.__currentIndex = this.__options.selected;
  9751. // 前一次选中项
  9752. this.__prevIndex = -1;
  9753. },
  9754. __render: function() {
  9755. this.callBase();
  9756. $(this.__element).addClass(CONF.classPrefix + "buttonset");
  9757. this.__initButtons();
  9758. return this;
  9759. },
  9760. __initButtons: function() {
  9761. var _self = this, buttonWidget = null;
  9762. $.each(this.__options.buttons, function(index, buttonOption) {
  9763. buttonWidget = new ToggleButton($.extend({}, buttonOption, {
  9764. pressed: index === _self.__options.selected,
  9765. preventDefault: true
  9766. }));
  9767. // 切换
  9768. buttonWidget.__on("click", function(e) {
  9769. if (!_self.isDisabled()) {
  9770. _self.__pressButton(this);
  9771. }
  9772. });
  9773. buttonWidget.__on("change", function(e) {
  9774. // 阻止buton本身的事件向上冒泡
  9775. e.stopPropagation();
  9776. });
  9777. _self.appendButton(buttonWidget);
  9778. });
  9779. },
  9780. /**
  9781. * 按下指定按钮, 该方法会更新其他按钮的状态和整个button-set的状态
  9782. * @param button
  9783. * @private
  9784. */
  9785. __pressButton: function(button) {
  9786. this.__prevIndex = this.__currentIndex;
  9787. this.__currentIndex = this.indexOf(button);
  9788. if (this.__currentIndex === this.__prevIndex) {
  9789. return;
  9790. }
  9791. if (button) {
  9792. button.press();
  9793. }
  9794. // 弹起其他按钮
  9795. $.each(this.__widgets, function(i, otherButton) {
  9796. if (otherButton !== button) {
  9797. otherButton.bounce();
  9798. }
  9799. });
  9800. this.trigger("change", {
  9801. currentIndex: this.__currentIndex,
  9802. prevIndex: this.__prevIndex
  9803. });
  9804. },
  9805. __valid: function(ele) {
  9806. return ele instanceof ToggleButton;
  9807. }
  9808. });
  9809. }
  9810. };
  9811. //src/widget/button.js
  9812. /**
  9813. * Button对象
  9814. * 通用按钮构件
  9815. */
  9816. _p[37] = {
  9817. value: function(require) {
  9818. var $ = _p.r(4), CONF = _p.r(12), buttonTpl = _p.r(19), Icon = _p.r(42), Label = _p.r(48);
  9819. return _p.r(13).createClass("Button", {
  9820. base: _p.r(60),
  9821. constructor: function(options) {
  9822. var defaultOptions = {
  9823. label: null,
  9824. text: null,
  9825. icon: null,
  9826. // label相对icon的位置
  9827. layout: "right"
  9828. };
  9829. options = $.extend({}, defaultOptions, options);
  9830. this.callBase(options);
  9831. },
  9832. getLabel: function() {
  9833. return this.__labelWidget.getText();
  9834. },
  9835. setLabel: function(text) {
  9836. return this.__labelWidget.setText(text);
  9837. },
  9838. getLabelWidget: function() {
  9839. return this.__labelWidget;
  9840. },
  9841. getIconWidget: function() {
  9842. return this.__iconWidget;
  9843. },
  9844. __render: function() {
  9845. this.callBase();
  9846. this.__iconWidget = new Icon(this.__options.icon);
  9847. this.__labelWidget = new Label(this.__options.label);
  9848. // layout
  9849. switch (this.__options.layout) {
  9850. case "left":
  9851. /* falls through */
  9852. case "top":
  9853. this.__element.appendChild(this.__labelWidget.getElement());
  9854. this.__element.appendChild(this.__iconWidget.getElement());
  9855. break;
  9856. case "right":
  9857. /* falls through */
  9858. case "bottom":
  9859. /* falls through */
  9860. default:
  9861. this.__element.appendChild(this.__iconWidget.getElement());
  9862. this.__element.appendChild(this.__labelWidget.getElement());
  9863. break;
  9864. }
  9865. $(this.__element).addClass(CONF.classPrefix + "button-layout-" + this.__options.layout);
  9866. },
  9867. __initOptions: function() {
  9868. this.callBase();
  9869. this.widgetName = "Button";
  9870. this.__tpl = buttonTpl;
  9871. this.__iconWidget = null;
  9872. this.__labelWidget = null;
  9873. if (typeof this.__options.label !== "object") {
  9874. this.__options.label = {
  9875. text: this.__options.label
  9876. };
  9877. }
  9878. if (typeof this.__options.icon !== "object") {
  9879. this.__options.icon = {
  9880. img: this.__options.icon
  9881. };
  9882. }
  9883. },
  9884. __initEvent: function() {
  9885. this.callBase();
  9886. this.on("click", function() {
  9887. this.__trigger("btnclick");
  9888. });
  9889. }
  9890. });
  9891. }
  9892. };
  9893. //src/widget/colorpicker.js
  9894. /**
  9895. * 容器类: PPanel = Positioning Panel
  9896. */
  9897. _p[38] = {
  9898. value: function(require) {
  9899. var Utils = _p.r(13), CONF = _p.r(12), Mask = _p.r(49), tpl = _p.r(20), $ = _p.r(4);
  9900. return Utils.createClass("ColorPicker", {
  9901. base: _p.r(54),
  9902. constructor: function(options) {
  9903. var defaultOptions = {
  9904. clearText: "",
  9905. commonText: "",
  9906. commonColor: [ [ "#ffffff", "#000000", "#eeece1", "#1f497d", "#4f81bd", "#c0504d", "#9bbb59", "#8064a2", "#4bacc6", "#f79646" ], [ "#f2f2f2", "#808080", "#ddd8c2", "#c6d9f1", "#dbe5f1", "#f2dbdb", "#eaf1dd", "#e5dfec", "#daeef3", "#fde9d9" ], [ "#d9d9d9", "#595959", "#c4bc96", "#8db3e2", "#b8cce4", "#e5b8b7", "#d6e3bc", "#ccc0d9", "#b6dde8", "#fbd4b4" ], [ "#bfbfbf", "#404040", "#938953", "#548dd4", "#95b3d7", "#d99594", "#c2d69b", "#b2a1c7", "#92cddc", "#fabf8f" ], [ "#a6a6a6", "#262626", "#4a442a", "#17365d", "#365f91", "#943634", "#76923c", "#5f497a", "#31849b", "#e36c0a" ], [ "#7f7f7f", "#0d0d0d", "#1c1a10", "#0f243e", "#243f60", "#622423", "#4e6128", "#3f3151", "#205867", "#974706" ] ],
  9907. standardText: "",
  9908. standardColor: [ "#c00000", "#ff0000", "#ffc000", "#ffff00", "#92d050", "#00b050", "#00b0f0", "#0070c0", "#002060", "#7030a0" ]
  9909. };
  9910. options = $.extend({}, defaultOptions, options);
  9911. this.callBase(options);
  9912. },
  9913. show: function() {
  9914. if (!this.__inDoc) {
  9915. this.__inDoc = true;
  9916. this.appendTo(this.__element.ownerDocument.body);
  9917. }
  9918. this.__maskWidget.show();
  9919. this.callBase();
  9920. return this;
  9921. },
  9922. hide: function() {
  9923. this.callBase();
  9924. this.__maskWidget.hide();
  9925. return this;
  9926. },
  9927. attachTo: function($obj) {
  9928. var _self = this;
  9929. $obj.on("click", function() {
  9930. _self.appendTo($obj.getElement().ownerDocument.body);
  9931. _self.positionTo($obj);
  9932. _self.show();
  9933. });
  9934. },
  9935. __initOptions: function() {
  9936. this.callBase();
  9937. this.widgetName = "ColorPicker";
  9938. this.__contentElement = null;
  9939. this.__maskWidget = null;
  9940. this.__inDoc = false;
  9941. },
  9942. __render: function() {
  9943. this.callBase();
  9944. $(this.__element).addClass(CONF.classPrefix + "colorpicker");
  9945. var contentHtml = Utils.Tpl.compile(tpl, this.__options);
  9946. this.__contentElement.appendChild($(contentHtml)[0]);
  9947. this.__previewElement = $(this.__contentElement).find("." + CONF.classPrefix + "colorpicker-preview");
  9948. this.__clearElement = $(this.__contentElement).find("." + CONF.classPrefix + "colorpicker-clear");
  9949. this.__maskWidget = new Mask(this.__options.mask);
  9950. },
  9951. // 初始化点击事件
  9952. __initEvent: function() {
  9953. var _self = this;
  9954. this.callBase();
  9955. this.on("click", function(e) {
  9956. var color, $target = $(e.target);
  9957. if ($target.hasClass(CONF.classPrefix + "colorpicker-item")) {
  9958. color = $target.attr("data-color");
  9959. _self.trigger("selectcolor", color);
  9960. _self.hide();
  9961. } else if ($target.hasClass(CONF.classPrefix + "colorpicker-clear")) {
  9962. _self.trigger("selectcolor", "");
  9963. _self.hide();
  9964. }
  9965. });
  9966. this.on("mouseover", function(e) {
  9967. var color, $target = $(e.target);
  9968. if ($target.hasClass(CONF.classPrefix + "colorpicker-item")) {
  9969. color = $target.attr("data-color");
  9970. $(_self.__element).find("." + CONF.classPrefix + "colorpicker-preview").css({
  9971. "background-color": color,
  9972. "border-color": color
  9973. });
  9974. }
  9975. });
  9976. this.__maskWidget.on("click", function() {
  9977. _self.hide();
  9978. });
  9979. }
  9980. });
  9981. }
  9982. };
  9983. //src/widget/container.js
  9984. /**
  9985. * Container类, 所有容器类的父类`
  9986. * @abstract
  9987. */
  9988. _p[39] = {
  9989. value: function(require) {
  9990. var Utils = _p.r(13), CONF = _p.r(12), Widget = _p.r(60), Creator = _p.r(0), $ = _p.r(4);
  9991. return Utils.createClass("Container", {
  9992. base: Widget,
  9993. constructor: function(options) {
  9994. var defaultOptions = {
  9995. column: false,
  9996. widgets: null
  9997. };
  9998. options = $.extend({}, defaultOptions, options);
  9999. this.callBase(options);
  10000. },
  10001. indexOf: function(widget) {
  10002. return $.inArray(widget, this.__widgets);
  10003. },
  10004. disable: function() {
  10005. this.callBase();
  10006. $.each(this.__widgets, function(index, widget) {
  10007. widget.disable();
  10008. });
  10009. },
  10010. enable: function() {
  10011. this.callBase();
  10012. $.each(this.__widgets, function(index, widget) {
  10013. widget.enable();
  10014. });
  10015. },
  10016. getWidgets: function() {
  10017. return this.__widgets;
  10018. },
  10019. getWidget: function(index) {
  10020. return this.__widgets[index] || null;
  10021. },
  10022. getWidgetByValue: function(value) {
  10023. var widget = null;
  10024. $.each(this.__widgets, function(i, wgt) {
  10025. if (wgt.getValue() === value) {
  10026. widget = wgt;
  10027. return false;
  10028. }
  10029. });
  10030. return widget;
  10031. },
  10032. appendWidget: function(widget) {
  10033. if (!this.__valid(widget)) {
  10034. return null;
  10035. }
  10036. if (this.__options.disabled) {
  10037. widget.disable();
  10038. }
  10039. this.__widgets.push(widget);
  10040. widget.appendTo(this.__contentElement);
  10041. if (!this.__options.column) {
  10042. return widget;
  10043. }
  10044. if (this.__widgets.length > 0 && this.__widgets.length % this.__options.column === 0) {
  10045. this.__contentElement.appendChild($('<span class="fui-column"></span>')[0]);
  10046. }
  10047. $(widget.getElement()).addClass(CONF.classPrefix + "panel-column-widget");
  10048. return widget;
  10049. },
  10050. appendWidgets: function(widgetArray) {
  10051. var _self = this, widgets = widgetArray;
  10052. if (!$.isArray(widgetArray)) {
  10053. widgets = arguments;
  10054. }
  10055. $.each(widgets, function(i, widget) {
  10056. _self.appendWidget(widget);
  10057. });
  10058. return this;
  10059. },
  10060. // TODO insertWidget时, 如果columnu为指定的数字,那么该插入需要调整换行符,现在还未对这个逻辑做处理。
  10061. insertWidget: function(index, widget) {
  10062. var oldElement = null;
  10063. if (this.__widgets.length === 0) {
  10064. return this.appendWidget(widget);
  10065. }
  10066. if (!this.__valid(widget)) {
  10067. return null;
  10068. }
  10069. if (this.__options.disabled) {
  10070. widget.disable();
  10071. }
  10072. oldElement = this.__widgets[index];
  10073. this.__widgets.splice(index, 0, widget);
  10074. this.__contentElement.insertBefore(widget.getElement(), oldElement.getElement());
  10075. if (this.__options.column === false) {
  10076. return widget;
  10077. }
  10078. this.__contentElement.insertBefore($('<span class="fui-column"></span>')[0], oldElement.getElement());
  10079. $(widget.getElement()).addClass(CONF.classPrefix + "panel-column-widget");
  10080. return widget;
  10081. },
  10082. insertWidgets: function(index, widgetArray) {
  10083. var _self = this, widgets = widgetArray;
  10084. if (!$.isArray(widgetArray)) {
  10085. widgets = [].slice.call(arguments, 1);
  10086. }
  10087. $.each(widgets, function(i, widget) {
  10088. _self.insertWidget(index, widget);
  10089. index++;
  10090. });
  10091. return this;
  10092. },
  10093. getContentElement: function() {
  10094. return this.__contentElement;
  10095. },
  10096. removeWidget: function(widget) {
  10097. if (typeof widget === "number") {
  10098. widget = this.__widgets.splice(widget, 1)[0];
  10099. } else {
  10100. this.__widgets.splice(this.indexOf(widget), 1);
  10101. }
  10102. this.__contentElement.removeChild(widget.getElement());
  10103. $(widget.getElement()).removeClass(CONF.classPrefix + "panel-column-widget");
  10104. return widget;
  10105. },
  10106. __initOptions: function() {
  10107. this.widgetName = "Container";
  10108. this.__widgets = [];
  10109. this.__contentElement = null;
  10110. this.__options.column -= 0;
  10111. },
  10112. __render: function() {
  10113. this.callBase();
  10114. this.__contentElement = this.__element;
  10115. $(this.__element).addClass(CONF.classPrefix + "container");
  10116. if (this.__options.column) {
  10117. $(this.__element).addClass(CONF.classPrefix + "container-column");
  10118. }
  10119. return this;
  10120. },
  10121. // Override
  10122. __appendChild: function(childWidget) {
  10123. return this.appendWidget(childWidget);
  10124. },
  10125. __initWidgets: function() {
  10126. if (!this.__options.widgets) {
  10127. return;
  10128. }
  10129. var widgets = Creator.parse(this.__options.widgets), _self = this;
  10130. if (!$.isArray(widgets)) {
  10131. widgets = [ widgets ];
  10132. }
  10133. $.each(widgets, function(i, widget) {
  10134. _self.appendWidget(widget);
  10135. });
  10136. },
  10137. /**
  10138. * 验证元素给定元素是否可以插入当前容器中
  10139. * @param ele 需要验证的元素
  10140. * @returns {boolean} 允许插入返回true, 否则返回false
  10141. * @private
  10142. */
  10143. __valid: function(ele) {
  10144. return ele instanceof Widget;
  10145. }
  10146. });
  10147. }
  10148. };
  10149. //src/widget/dialog.js
  10150. /**
  10151. * 容器类: PPanel = Positioning Panel
  10152. */
  10153. _p[40] = {
  10154. value: function(require) {
  10155. var Utils = _p.r(13), CONF = _p.r(12), Widget = _p.r(60), Mask = _p.r(49), tpl = _p.r(21), Button = _p.r(37), LAYOUT = CONF.layout, $ = _p.r(4), ACTION = {
  10156. CANCEL: "cancel",
  10157. OK: "ok"
  10158. };
  10159. return Utils.createClass("Dialog", {
  10160. base: _p.r(54),
  10161. constructor: function(options) {
  10162. var defaultOptions = {
  10163. layout: LAYOUT.CENTER,
  10164. caption: null,
  10165. resize: "height",
  10166. draggable: true,
  10167. // 是否包含close button
  10168. closeButton: true,
  10169. mask: {
  10170. color: "#000",
  10171. opacity: .2
  10172. },
  10173. prompt: false,
  10174. // 底部按钮
  10175. buttons: [ {
  10176. className: CONF.classPrefix + "xdialog-ok-btn",
  10177. action: "ok",
  10178. label: "确定"
  10179. }, {
  10180. className: CONF.classPrefix + "xdialog-cancel-btn",
  10181. action: "cancel",
  10182. label: "取消"
  10183. } ]
  10184. };
  10185. options = $.extend({}, defaultOptions, options);
  10186. this.callBase(options);
  10187. },
  10188. open: function() {
  10189. this.__fire("open", function() {
  10190. this.show();
  10191. });
  10192. return this;
  10193. },
  10194. close: function() {
  10195. this.__fire("close", function() {
  10196. this.hide();
  10197. });
  10198. return this;
  10199. },
  10200. getButtons: function() {
  10201. return this.__buttons;
  10202. },
  10203. getButton: function(index) {
  10204. return this.__buttons[index];
  10205. },
  10206. appendTo: function(container) {
  10207. this.callBase(container);
  10208. this.__maskWidget.appendTo(container);
  10209. this.__inDoc = true;
  10210. return this;
  10211. },
  10212. show: function() {
  10213. if (!this.__target) {
  10214. this.__target = this.__element.ownerDocument.body;
  10215. }
  10216. if (!this.__inDoc) {
  10217. this.appendTo(this.__element.ownerDocument.body);
  10218. }
  10219. this.__maskWidget.show();
  10220. this.callBase();
  10221. this.__openState = true;
  10222. return this;
  10223. },
  10224. hide: function() {
  10225. this.callBase();
  10226. this.__maskWidget.hide();
  10227. this.__openState = false;
  10228. return this;
  10229. },
  10230. toggle: function() {
  10231. this.isOpen() ? this.close() : this.open();
  10232. return this;
  10233. },
  10234. isOpen: function() {
  10235. return this.__openState;
  10236. },
  10237. getHeadElement: function() {
  10238. return this.__headElement;
  10239. },
  10240. getBodyElement: function() {
  10241. return this.getContentElement();
  10242. },
  10243. getFootElement: function() {
  10244. return this.__footElement;
  10245. },
  10246. __initOptions: function() {
  10247. this.callBase();
  10248. this.widgetName = "Dialog";
  10249. this.__target = this.__options.target;
  10250. this.__layout = this.__options.layout;
  10251. this.__inDoc = false;
  10252. this.__hinting = false;
  10253. this.__openState = false;
  10254. this.__headElement = null;
  10255. this.__bodyElement = null;
  10256. this.__footElement = null;
  10257. this.__maskWidget = null;
  10258. this.__buttons = [];
  10259. if (this.__target instanceof Widget) {
  10260. this.__target = this.__target.getElement();
  10261. }
  10262. },
  10263. __render: function() {
  10264. this.callBase();
  10265. this.__innerTpl = Utils.Tpl.compile(tpl, this.__options);
  10266. this.__contentElement.appendChild($(this.__innerTpl)[0]);
  10267. $(this.__element).addClass(CONF.classPrefix + "dialog");
  10268. this.__headElement = $(".fui-dialog-head", this.__contentElement)[0];
  10269. this.__bodyElement = $(".fui-dialog-body", this.__contentElement)[0];
  10270. this.__footElement = $(".fui-dialog-foot", this.__contentElement)[0];
  10271. this.__maskWidget = new Mask(this.__options.mask);
  10272. this.__contentElement = this.__bodyElement;
  10273. if (this.__options.draggable) {
  10274. this.__initDraggable();
  10275. }
  10276. if (this.__options.closeButton) {
  10277. this.__initCloseButton();
  10278. }
  10279. this.__initButtons();
  10280. this.__initMaskLint();
  10281. },
  10282. __action: function(type, btn) {
  10283. switch (type) {
  10284. case ACTION.OK:
  10285. if (this.__triggerHandler(type) !== false) {
  10286. this.close();
  10287. }
  10288. break;
  10289. case ACTION.CANCEL:
  10290. this.__triggerHandler(type);
  10291. this.close();
  10292. break;
  10293. }
  10294. },
  10295. __initButtons: function() {
  10296. var _self = this, button = null, foot = this.__footElement;
  10297. $.each(this.__options.buttons, function(index, buttonOption) {
  10298. button = new Button(buttonOption);
  10299. button.appendTo(foot);
  10300. _self.__buttons.push(button);
  10301. });
  10302. },
  10303. __initEvent: function() {
  10304. var _self = this;
  10305. this.callBase();
  10306. $([ this.__footElement, this.__headElement ]).on("btnclick", function(e, btn) {
  10307. _self.__action(btn.getOptions().action, btn);
  10308. });
  10309. if (this.__options.prompt) {
  10310. $(this.__element).on("keydown", function(e) {
  10311. switch (e.keyCode) {
  10312. case 13:
  10313. _self.__action(ACTION.OK);
  10314. break;
  10315. case 27:
  10316. _self.__action(ACTION.CANCEL);
  10317. break;
  10318. }
  10319. });
  10320. }
  10321. },
  10322. __initDraggable: function() {
  10323. Utils.createDraggable({
  10324. handler: this.__headElement,
  10325. target: this.__element
  10326. }).bind();
  10327. },
  10328. __initCloseButton: function() {
  10329. var closeButton = new Button({
  10330. className: "fui-close-button",
  10331. action: "cancel",
  10332. icon: {
  10333. className: "fui-close-button-icon"
  10334. }
  10335. });
  10336. closeButton.appendTo(this.__headElement);
  10337. },
  10338. __initMaskLint: function() {
  10339. var _self = this;
  10340. this.__maskWidget.on("click", function() {
  10341. _self.__hint();
  10342. });
  10343. },
  10344. __hint: function() {
  10345. if (this.__hinting) {
  10346. return;
  10347. }
  10348. this.__hinting = true;
  10349. var $ele = $(this.__element), _self = this, classNmae = [ CONF.classPrefix + "mask-hint", CONF.classPrefix + "mask-animate" ];
  10350. $ele.addClass(classNmae.join(" "));
  10351. window.setTimeout(function() {
  10352. $ele.removeClass(classNmae[0]);
  10353. window.setTimeout(function() {
  10354. $ele.removeClass(classNmae[1]);
  10355. _self.__hinting = false;
  10356. }, 200);
  10357. }, 200);
  10358. }
  10359. });
  10360. }
  10361. };
  10362. //src/widget/drop-panel.js
  10363. /**
  10364. * DropPanel对象
  10365. * 可接受输入的按钮构件
  10366. */
  10367. _p[41] = {
  10368. value: function(require) {
  10369. var $ = _p.r(4), CONF = _p.r(12), tpl = _p.r(22), Button = _p.r(37), Panel = _p.r(51), PPanel = _p.r(54), Mask = _p.r(49);
  10370. return _p.r(13).createClass("DropPanel", {
  10371. base: _p.r(60),
  10372. constructor: function(options) {
  10373. var defaultOptions = {
  10374. button: null,
  10375. panel: null,
  10376. width: null,
  10377. height: null
  10378. };
  10379. options = $.extend({}, defaultOptions, options);
  10380. this.callBase(options);
  10381. },
  10382. disable: function() {
  10383. this.callBase();
  10384. },
  10385. enable: function() {
  10386. this.callBase();
  10387. },
  10388. open: function() {
  10389. this.__popupWidget.appendWidget(this.__panelWidget);
  10390. this.__maskWidget.show();
  10391. this.__popupWidget.show();
  10392. var $popup = $(this.__popupWidget.getElement());
  10393. $popup.css("top", parseInt($popup.css("top")) - $(this.__element).outerHeight());
  10394. $popup.css("min-width", $(this.__element).outerWidth());
  10395. $popup.css("min-height", $(this.__element).height());
  10396. },
  10397. close: function() {
  10398. this.__maskWidget.hide();
  10399. this.__popupWidget.hide();
  10400. this.__panelWidget.appendTo(this.__contentElement);
  10401. },
  10402. getPanelElement: function() {
  10403. return this.__panelWidget.getElement();
  10404. },
  10405. appendWidget: function(widget) {
  10406. this.__panelWidget.appendWidget(widget);
  10407. },
  10408. getWidgets: function() {
  10409. return this.__panelWidget.getWidgets();
  10410. },
  10411. getWidget: function(index) {
  10412. return this.__panelWidget.getWidget(index);
  10413. },
  10414. appendWidgets: function(widgets) {
  10415. this.__panelWidget.appendWidgets.apply(this, arguments);
  10416. return this;
  10417. },
  10418. insertWidget: function(index, widget) {
  10419. this.__panelWidget.insertWidget(index, widget);
  10420. },
  10421. insertWidgets: function(index, widgets) {
  10422. this.__panelWidget.insertWidgets.apply(this, arguments);
  10423. return this;
  10424. },
  10425. removeWidget: function(widget) {
  10426. return this.__panelWidget.removeWidget(widget);
  10427. },
  10428. __render: function() {
  10429. this.__initOptions();
  10430. this.__buttonWidget = new Button(this.__options.button);
  10431. this.__panelWidget = new Panel(this.__options.content);
  10432. this.__popupWidget = new PPanel();
  10433. this.__maskWidget = new Mask(this.__options.mask);
  10434. this.callBase();
  10435. this.__popupWidget.positionTo(this.__element);
  10436. $(this.__popupWidget.getElement()).addClass(CONF.classPrefix + "drop-panel-popup");
  10437. // 初始化content
  10438. var $content = $('<div class="' + CONF.classPrefix + 'drop-panel-content"></div>').append(this.__panelWidget.getElement());
  10439. this.__contentElement = $content[0];
  10440. // 插入按钮到element
  10441. $(this.__element).append($content).append(this.__buttonWidget.getElement());
  10442. this.__initDropPanelEvent();
  10443. },
  10444. __initOptions: function() {
  10445. this.widgetName = "DropPanel";
  10446. this.__tpl = tpl;
  10447. this.__buttonWidget = null;
  10448. this.__popupWidget = null;
  10449. this.__panelWidget = null;
  10450. this.__contentElement = null;
  10451. this.__maskWidget = null;
  10452. this.__popupState = false;
  10453. if (typeof this.__options.button !== "object") {
  10454. this.__options.input = {
  10455. icon: this.__options.button
  10456. };
  10457. }
  10458. },
  10459. __initDropPanelEvent: function() {
  10460. var _self = this;
  10461. this.__buttonWidget.on("click", function() {
  10462. if (!_self.__popupState) {
  10463. _self.__appendPopup();
  10464. _self.__popupState = true;
  10465. }
  10466. _self.trigger("buttonclick");
  10467. _self.open();
  10468. });
  10469. this.__panelWidget.on("click", function() {
  10470. _self.trigger("panelclick");
  10471. });
  10472. // mask 点击关闭
  10473. this.__maskWidget.on("maskclick", function() {
  10474. _self.close();
  10475. });
  10476. },
  10477. __appendPopup: function() {
  10478. this.__popupWidget.appendTo(this.__element.ownerDocument.body);
  10479. }
  10480. });
  10481. }
  10482. };
  10483. //src/widget/icon.js
  10484. /**
  10485. * icon widget
  10486. * 封装多种icon方式
  10487. */
  10488. _p[42] = {
  10489. value: function(require) {
  10490. var $ = _p.r(4), iconTpl = _p.r(23);
  10491. return _p.r(13).createClass("Icon", {
  10492. base: _p.r(60),
  10493. constructor: function(options) {
  10494. var defaultOptions = {
  10495. img: null
  10496. };
  10497. options = $.extend({}, defaultOptions, options);
  10498. this.callBase(options);
  10499. },
  10500. getValue: function() {
  10501. return this.__options.value || this.__options.img;
  10502. },
  10503. setImage: function(imageSrc) {
  10504. if (this.__options.img === imageSrc) {
  10505. return this;
  10506. }
  10507. if (this.__image) {
  10508. this.__image.src = imageSrc;
  10509. }
  10510. this.trigger("iconchange", {
  10511. prevImage: this.__prevIcon,
  10512. currentImage: this.__currentIcon
  10513. });
  10514. },
  10515. getImage: function() {
  10516. return this.__currentIcon;
  10517. },
  10518. __initOptions: function() {
  10519. this.callBase();
  10520. this.widgetName = "Icon";
  10521. this.__tpl = iconTpl;
  10522. this.__prevIcon = null;
  10523. this.__currentIcon = this.__options.img;
  10524. this.__image = null;
  10525. },
  10526. __render: function() {
  10527. this.__options.__width = this.__options.width;
  10528. this.__options.__height = this.__options.height;
  10529. this.__options.width = null;
  10530. this.__options.height = null;
  10531. this.callBase();
  10532. if (!this.__options.img) {
  10533. return;
  10534. }
  10535. this.__image = $("img", this.__element)[0];
  10536. if (this.__options.__width !== null) {
  10537. this.__image.width = this.__options.__width;
  10538. }
  10539. if (this.__options.__height !== null) {
  10540. this.__image.height = this.__options.__height;
  10541. }
  10542. }
  10543. });
  10544. }
  10545. };
  10546. //src/widget/input-button.js
  10547. /**
  10548. * InputButton对象
  10549. * 可接受输入的按钮构件
  10550. */
  10551. _p[43] = {
  10552. value: function(require) {
  10553. var $ = _p.r(4), CONF = _p.r(12), tpl = _p.r(24), Button = _p.r(37), Input = _p.r(45);
  10554. return _p.r(13).createClass("InputButton", {
  10555. base: _p.r(60),
  10556. constructor: function(options) {
  10557. var defaultOptions = {
  10558. button: null,
  10559. input: null,
  10560. placeholder: null,
  10561. // label相对icon的位置
  10562. layout: "right"
  10563. };
  10564. options = $.extend({}, defaultOptions, options);
  10565. this.callBase(options);
  10566. },
  10567. getValue: function() {
  10568. return this.__inputWidget.getValue();
  10569. },
  10570. setValue: function(value) {
  10571. this.__inputWidget.setValue(value);
  10572. return this;
  10573. },
  10574. reset: function() {
  10575. this.__inputWidget.reset();
  10576. },
  10577. selectAll: function() {
  10578. this.__inputWidget.selectAll();
  10579. return this;
  10580. },
  10581. selectRange: function(start, end) {
  10582. this.__inputWidget.selectRange(start, end);
  10583. return this;
  10584. },
  10585. focus: function() {
  10586. this.__inputWidget.focus();
  10587. return this;
  10588. },
  10589. unfocus: function() {
  10590. this.__inputWidget.unfocus();
  10591. return this;
  10592. },
  10593. __initOptions: function() {
  10594. this.callBase();
  10595. this.widgetName = "InputButton";
  10596. this.__tpl = tpl;
  10597. this.__inputWidget = null;
  10598. this.__buttonWidget = null;
  10599. if (typeof this.__options.input !== "object") {
  10600. this.__options.input = {
  10601. placeholder: this.__options.input
  10602. };
  10603. }
  10604. this.__options.input = $.extend({}, this.__options.input, {
  10605. placeholder: this.__options.placeholder
  10606. });
  10607. if (typeof this.__options.button !== "object") {
  10608. this.__options.button = {
  10609. icon: this.__options.button
  10610. };
  10611. }
  10612. },
  10613. __render: function() {
  10614. var _self = this;
  10615. this.callBase();
  10616. this.__buttonWidget = new Button(this.__options.button);
  10617. this.__inputWidget = new Input(this.__options.input);
  10618. // layout
  10619. switch (this.__options.layout) {
  10620. case "left":
  10621. /* falls through */
  10622. case "top":
  10623. this.__buttonWidget.appendTo(this.__element);
  10624. this.__inputWidget.appendTo(this.__element);
  10625. break;
  10626. case "right":
  10627. /* falls through */
  10628. case "bottom":
  10629. /* falls through */
  10630. default:
  10631. this.__inputWidget.appendTo(this.__element);
  10632. this.__buttonWidget.appendTo(this.__element);
  10633. break;
  10634. }
  10635. $(this.__element).addClass(CONF.classPrefix + "layout-" + this.__options.layout);
  10636. this.__buttonWidget.on("click", function() {
  10637. _self.trigger("buttonclick");
  10638. });
  10639. }
  10640. });
  10641. }
  10642. };
  10643. //src/widget/input-menu.js
  10644. /**
  10645. * InputMenu构件
  10646. * 可接受输入的下拉菜单构件
  10647. */
  10648. _p[44] = {
  10649. value: function(require) {
  10650. var $ = _p.r(4), tpl = _p.r(25), InputButton = _p.r(43), Menu = _p.r(50), Mask = _p.r(49);
  10651. return _p.r(13).createClass("InputMenu", {
  10652. base: _p.r(60),
  10653. constructor: function(options) {
  10654. var defaultOptions = {
  10655. input: null,
  10656. menu: null,
  10657. mask: null,
  10658. selected: -1
  10659. };
  10660. options = $.extend({}, defaultOptions, options);
  10661. this.callBase(options);
  10662. },
  10663. select: function(index) {
  10664. this.__menuWidget.select(index);
  10665. },
  10666. selectByValue: function(value) {
  10667. return this.__selectBy("values", value);
  10668. },
  10669. selectByLabel: function(value) {
  10670. return this.__selectBy("labels", value);
  10671. },
  10672. clearSelect: function() {
  10673. this.__lastSelect = -1;
  10674. this.__menuWidget.clearSelect();
  10675. this.__inputWidget.reset();
  10676. return this;
  10677. },
  10678. setValue: function(value) {
  10679. return this;
  10680. },
  10681. getValue: function() {
  10682. return this.__menuWidget.getSelectedItem().getValue();
  10683. },
  10684. open: function() {
  10685. this.__maskWidget.show();
  10686. this.__menuWidget.show();
  10687. },
  10688. close: function() {
  10689. this.__maskWidget.hide();
  10690. this.__menuWidget.hide();
  10691. },
  10692. __render: function() {
  10693. this.__inputWidget = new InputButton(this.__options.input);
  10694. this.__menuWidget = new Menu(this.__options.menu);
  10695. this.__maskWidget = new Mask(this.__options.mask);
  10696. this.callBase();
  10697. this.__inputWidget.appendTo(this.__element);
  10698. this.__menuWidget.positionTo(this.__inputWidget);
  10699. this.__initInputValue();
  10700. },
  10701. __selectBy: function(type, value) {
  10702. var values = this.__getItemValues()[type], index = -1;
  10703. $.each(values, function(i, val) {
  10704. if (value === val) {
  10705. index = i;
  10706. return false;
  10707. }
  10708. });
  10709. if (index !== -1) {
  10710. this.select(index);
  10711. return this.__menuWidget.getSelectedItem();
  10712. }
  10713. return null;
  10714. },
  10715. __initInputValue: function() {
  10716. var selectedItem = this.__menuWidget.getItem(this.__options.selected);
  10717. if (selectedItem) {
  10718. this.__inputWidget.setValue(selectedItem.getLabel());
  10719. }
  10720. },
  10721. __initEvent: function() {
  10722. var _self = this;
  10723. this.callBase();
  10724. this.on("buttonclick", function() {
  10725. if (!this.__menuState) {
  10726. this.__appendMenu();
  10727. this.__menuState = true;
  10728. }
  10729. this.__inputWidget.unfocus();
  10730. this.open();
  10731. });
  10732. this.on("keypress", function(e) {
  10733. this.__lastTime = new Date();
  10734. });
  10735. this.on("keyup", function(e) {
  10736. if (e.keyCode !== 8 && e.keyCode !== 13 && new Date() - this.__lastTime < 500) {
  10737. this.__update();
  10738. }
  10739. });
  10740. this.on("inputcomplete", function() {
  10741. this.__inputWidget.selectRange(99999999);
  10742. this.__inputComplete();
  10743. });
  10744. this.__menuWidget.on("select", function(e, info) {
  10745. e.stopPropagation();
  10746. _self.__inputWidget.setValue(info.label);
  10747. _self.trigger("select", info);
  10748. _self.close();
  10749. });
  10750. this.__menuWidget.on("menuitemclick", function(e, info) {
  10751. _self.trigger("itemclick", info);
  10752. });
  10753. this.__menuWidget.on("change", function(e, info) {
  10754. e.stopPropagation();
  10755. _self.trigger("change", info);
  10756. });
  10757. // 阻止input自身的select和change事件
  10758. this.__inputWidget.on("select change", function(e) {
  10759. e.stopPropagation();
  10760. });
  10761. // mask 点击关闭
  10762. this.__maskWidget.on("maskclick", function() {
  10763. _self.close();
  10764. });
  10765. // 记录最后选中的数据
  10766. this.on("select", function(e, info) {
  10767. this.__lastSelect = info;
  10768. });
  10769. },
  10770. // 更新输入框内容
  10771. __update: function() {
  10772. var inputValue = this.__inputWidget.getValue(), lowerCaseValue = inputValue.toLowerCase(), values = this.__getItemValues().labels, targetValue = null;
  10773. if (!inputValue) {
  10774. return;
  10775. }
  10776. $.each(values, function(i, val) {
  10777. if (val.toLowerCase().indexOf(lowerCaseValue) === 0) {
  10778. targetValue = val;
  10779. return false;
  10780. }
  10781. });
  10782. if (targetValue) {
  10783. this.__inputWidget.setValue(targetValue);
  10784. this.__inputWidget.selectRange(inputValue.length);
  10785. }
  10786. },
  10787. // 获取所有item的值列表
  10788. __getItemValues: function() {
  10789. var vals = [], labels = [];
  10790. $.each(this.__menuWidget.getWidgets(), function(index, item) {
  10791. labels.push(item.getLabel());
  10792. vals.push(item.getValue());
  10793. });
  10794. return {
  10795. labels: labels,
  10796. values: vals
  10797. };
  10798. },
  10799. // 用户输入完成
  10800. __inputComplete: function() {
  10801. var itemsInfo = this.__getItemValues(), labels = itemsInfo.labels, targetIndex = -1, inputValue = this.__inputWidget.getValue(), lastSelect = this.__lastSelect;
  10802. $.each(labels, function(i, label) {
  10803. if (label === inputValue) {
  10804. targetIndex = i;
  10805. return false;
  10806. }
  10807. });
  10808. this.trigger("select", {
  10809. index: targetIndex,
  10810. label: inputValue,
  10811. value: itemsInfo.values[targetIndex]
  10812. });
  10813. if (!lastSelect || lastSelect.value !== inputValue) {
  10814. this.trigger("change", {
  10815. from: lastSelect || {
  10816. index: -1,
  10817. label: null,
  10818. value: null
  10819. },
  10820. to: {
  10821. index: targetIndex,
  10822. label: inputValue,
  10823. value: itemsInfo.values[targetIndex]
  10824. }
  10825. });
  10826. }
  10827. },
  10828. __appendMenu: function() {
  10829. this.__menuWidget.appendTo(this.__inputWidget.getElement().ownerDocument.body);
  10830. },
  10831. __initOptions: function() {
  10832. this.callBase();
  10833. this.widgetName = "InputMenu";
  10834. this.__tpl = tpl;
  10835. // 最后输入时间
  10836. this.__lastTime = 0;
  10837. // 最后选中的记录
  10838. this.__lastSelect = null;
  10839. this.__inputWidget = null;
  10840. this.__menuWidget = null;
  10841. this.__maskWidget = null;
  10842. // menu状态, 记录是否已经append到dom树上
  10843. this.__menuState = false;
  10844. if (this.__options.selected !== -1) {
  10845. this.__options.menu.selected = this.__options.selected;
  10846. }
  10847. }
  10848. });
  10849. }
  10850. };
  10851. //src/widget/input.js
  10852. /*jshint camelcase:false*/
  10853. /**
  10854. * Input widget
  10855. */
  10856. _p[45] = {
  10857. value: function(require) {
  10858. var CONF = _p.r(12), $ = _p.r(4), tpl = _p.r(26);
  10859. return _p.r(13).createClass("Input", {
  10860. base: _p.r(60),
  10861. constructor: function(options) {
  10862. var defaultOptions = {
  10863. placeholder: null
  10864. };
  10865. options = $.extend({}, defaultOptions, options);
  10866. this.callBase(options);
  10867. },
  10868. getValue: function() {
  10869. return this.__element.value;
  10870. },
  10871. setValue: function(value) {
  10872. this.__element.value = value;
  10873. return this;
  10874. },
  10875. disable: function() {
  10876. this.callBase();
  10877. this.__element.disabled = true;
  10878. },
  10879. enable: function() {
  10880. this.__element.disabled = false;
  10881. this.callBase();
  10882. },
  10883. reset: function() {
  10884. this.__element.value = this.__options.value || "";
  10885. return this;
  10886. },
  10887. selectAll: function() {
  10888. this.__element.select();
  10889. },
  10890. selectRange: function(startIndex, endIndex) {
  10891. if (!startIndex) {
  10892. startIndex = 0;
  10893. }
  10894. if (!endIndex) {
  10895. endIndex = 1e9;
  10896. }
  10897. this.__element.setSelectionRange(startIndex, endIndex);
  10898. },
  10899. focus: function() {
  10900. this.__element.focus();
  10901. return this;
  10902. },
  10903. unfocus: function() {
  10904. this.__element.blur();
  10905. return this;
  10906. },
  10907. __initOptions: function() {
  10908. this.callBase();
  10909. this.widgetName = "Input";
  10910. this.__tpl = tpl;
  10911. // input构件允许获得焦点
  10912. this.__allow_focus = true;
  10913. },
  10914. __render: function() {
  10915. this.callBase();
  10916. this.__element.removeAttribute("unselectable");
  10917. if (this.__options.placeholder) {
  10918. this.__element.setAttribute("placeholder", this.__options.placeholder);
  10919. }
  10920. this.addClass(CONF.classPrefix + "selectable");
  10921. },
  10922. __initEvent: function() {
  10923. this.callBase();
  10924. this.on("keydown", function(e) {
  10925. if (e.keyCode === 13) {
  10926. this.trigger("inputcomplete", {
  10927. value: this.getValue()
  10928. });
  10929. }
  10930. });
  10931. }
  10932. });
  10933. }
  10934. };
  10935. //src/widget/item.js
  10936. /**
  10937. * Label Widget
  10938. */
  10939. _p[46] = {
  10940. value: function(require) {
  10941. var Utils = _p.r(13), itemTpl = _p.r(27), Icon = _p.r(42), Label = _p.r(48), CONF = _p.r(12), $ = _p.r(4);
  10942. return Utils.createClass("Item", {
  10943. base: _p.r(60),
  10944. constructor: function(options) {
  10945. var defaultOptions = {
  10946. label: "",
  10947. icon: null,
  10948. selected: false,
  10949. textAlign: "left"
  10950. };
  10951. options = $.extend({}, defaultOptions, options);
  10952. this.callBase(options);
  10953. },
  10954. getValue: function() {
  10955. return this.__options.value || this.__labelWidget.getValue() || this.__iconWidget.getValue() || null;
  10956. },
  10957. select: function() {
  10958. this.__update(true);
  10959. return this;
  10960. },
  10961. unselect: function() {
  10962. this.__update(false);
  10963. return this;
  10964. },
  10965. isSelected: function() {
  10966. return this.__selectState;
  10967. },
  10968. setLabel: function(text) {
  10969. this.__labelWidget.setText(text);
  10970. return this;
  10971. },
  10972. getLabel: function() {
  10973. return this.__labelWidget.getText();
  10974. },
  10975. setIcon: function(imageSrc) {
  10976. this.__iconWidget.setImage(imageSrc);
  10977. return this;
  10978. },
  10979. getIcon: function() {
  10980. return this.__iconWidget.getImage();
  10981. },
  10982. __render: function() {
  10983. this.callBase();
  10984. this.__iconWidget = new Icon(this.__options.icon);
  10985. this.__labelWidget = new Label(this.__options.label);
  10986. this.__iconWidget.appendTo(this.__element);
  10987. this.__labelWidget.appendTo(this.__element);
  10988. },
  10989. __update: function(state) {
  10990. var fn = state ? "addClass" : "removeClass";
  10991. state = !!state;
  10992. $(this.__element)[fn](CONF.classPrefix + "item-selected");
  10993. this.__selectState = state;
  10994. this.trigger(state ? "itemselect" : "itemunselect");
  10995. return this;
  10996. },
  10997. __initEvent: function() {
  10998. this.callBase();
  10999. this.on("click", function() {
  11000. this.trigger("itemclick");
  11001. });
  11002. },
  11003. /**
  11004. * 初始化模板所用的css值
  11005. * @private
  11006. */
  11007. __initOptions: function() {
  11008. this.callBase();
  11009. this.widgetName = "Item";
  11010. this.__tpl = itemTpl;
  11011. this.__iconWidget = null;
  11012. this.__labelWidget = null;
  11013. this.__selectState = this.__options.selected;
  11014. if (typeof this.__options.label !== "object") {
  11015. this.__options.label = {
  11016. text: this.__options.label
  11017. };
  11018. }
  11019. if (!this.__options.label.textAlign) {
  11020. this.__options.label.textAlign = this.__options.textAlign;
  11021. }
  11022. if (typeof this.__options.icon !== "object") {
  11023. this.__options.icon = {
  11024. img: this.__options.icon
  11025. };
  11026. }
  11027. }
  11028. });
  11029. }
  11030. };
  11031. //src/widget/label-panel.js
  11032. /**
  11033. * LabelPanel Widget
  11034. * 带标签的面板
  11035. */
  11036. _p[47] = {
  11037. value: function(require) {
  11038. var Utils = _p.r(13), CONF = _p.r(12), Label = _p.r(48), $ = _p.r(4);
  11039. return Utils.createClass("LabelPanel", {
  11040. base: _p.r(51),
  11041. constructor: function(options) {
  11042. var defaultOptions = {
  11043. layout: "bottom"
  11044. };
  11045. options = $.extend({}, defaultOptions, options);
  11046. this.callBase(options);
  11047. },
  11048. disable: function() {
  11049. this.callBase();
  11050. this.__labelWidget.disable();
  11051. },
  11052. enable: function() {
  11053. this.callBase();
  11054. this.__labelWidget.enable();
  11055. },
  11056. __render: function() {
  11057. var $contentElement = null, opts = this.__options, ele = this.__element, classPrefix = CONF.classPrefix, labelClass = "fui-label-panel-content", originEle = null;
  11058. this.__labelWidget = new Label(opts.label);
  11059. this.callBase();
  11060. originEle = this.__contentElement;
  11061. $(ele).addClass(classPrefix + "label-panel");
  11062. $(ele).addClass(classPrefix + "layout-" + opts.layout);
  11063. $contentElement = $('<div class="' + labelClass + '"></div>');
  11064. originEle.appendChild(this.__labelWidget.getElement());
  11065. originEle.appendChild($contentElement[0]);
  11066. // 更新contentElement
  11067. this.__contentElement = $contentElement[0];
  11068. return this;
  11069. },
  11070. __initOptions: function() {
  11071. var label = this.__options.label;
  11072. this.callBase();
  11073. this.widgetName = "LabelPanel";
  11074. this.__labelWidget = null;
  11075. if (typeof label !== "object") {
  11076. this.__options.label = {
  11077. text: label
  11078. };
  11079. }
  11080. if (!this.__options.label.className) {
  11081. this.__options.label.className = "";
  11082. }
  11083. this.__options.label.className += " fui-label-panel-label";
  11084. }
  11085. });
  11086. }
  11087. };
  11088. //src/widget/label.js
  11089. /**
  11090. * Label Widget
  11091. */
  11092. _p[48] = {
  11093. value: function(require) {
  11094. var Utils = _p.r(13), labelTpl = _p.r(28), $ = _p.r(4);
  11095. return Utils.createClass("Label", {
  11096. base: _p.r(60),
  11097. constructor: function(options) {
  11098. var defaultOptions = {
  11099. text: "",
  11100. textAlign: "center"
  11101. };
  11102. options = $.extend({}, defaultOptions, options);
  11103. this.callBase(options);
  11104. },
  11105. getValue: function() {
  11106. return this.__options.text;
  11107. },
  11108. setText: function(text) {
  11109. var oldtext = this.__options.text;
  11110. this.__options.text = text;
  11111. $(this.__element).text(text);
  11112. this.trigger("labelchange", {
  11113. currentText: text,
  11114. prevText: oldtext
  11115. });
  11116. return this;
  11117. },
  11118. getText: function() {
  11119. return this.__options.text;
  11120. },
  11121. // label 禁用title显示
  11122. __allowShowTitle: function() {
  11123. return false;
  11124. },
  11125. /**
  11126. * 初始化模板所用的css值
  11127. * @private
  11128. */
  11129. __initOptions: function() {
  11130. this.callBase();
  11131. this.widgetName = "Label";
  11132. this.__tpl = labelTpl;
  11133. this.__options.text = this.__options.text.toString();
  11134. }
  11135. });
  11136. }
  11137. };
  11138. //src/widget/mask.js
  11139. /*jshint camelcase:false*/
  11140. /**
  11141. * Mask Widget
  11142. */
  11143. _p[49] = {
  11144. value: function(require) {
  11145. var Utils = _p.r(13), tpl = _p.r(29), Widget = _p.r(60), $ = _p.r(4), __cache_inited = false, __MASK_CACHE = [];
  11146. return Utils.createClass("Mask", {
  11147. base: _p.r(60),
  11148. constructor: function(options) {
  11149. var defaultOptions = {
  11150. bgcolor: "#000",
  11151. opacity: 0,
  11152. inner: true,
  11153. target: null,
  11154. // 禁止mouse scroll事件
  11155. scroll: false,
  11156. hide: true
  11157. };
  11158. options = $.extend({}, defaultOptions, options);
  11159. this.callBase(options);
  11160. },
  11161. maskTo: function(target) {
  11162. if (target) {
  11163. this.__target = target;
  11164. }
  11165. return this;
  11166. },
  11167. show: function() {
  11168. var docNode = null;
  11169. if (!this.__target) {
  11170. this.__target = this.__element.ownerDocument.body;
  11171. }
  11172. docNode = this.__target.ownerDocument.documentElement;
  11173. // 如果节点未添加到dom树, 则自动添加到文档的body节点上
  11174. if (!$.contains(docNode, this.__element)) {
  11175. this.appendTo(this.__target.ownerDocument.body);
  11176. }
  11177. this.callBase();
  11178. this.__position();
  11179. this.__resize();
  11180. this.__hideState = false;
  11181. },
  11182. hide: function() {
  11183. this.callBase();
  11184. this.__hideState = true;
  11185. },
  11186. isHide: function() {
  11187. return this.__hideState;
  11188. },
  11189. __initOptions: function() {
  11190. this.callBase();
  11191. this.widgetName = "Mask";
  11192. this.__tpl = tpl;
  11193. this.__cacheId = __MASK_CACHE.length;
  11194. this.__hideState = true;
  11195. __MASK_CACHE.push(this);
  11196. this.__target = this.__options.target;
  11197. if (this.__target instanceof Widget) {
  11198. this.__target = this.__target.getElement();
  11199. }
  11200. },
  11201. __render: function() {
  11202. this.callBase();
  11203. this.__initMaskEvent();
  11204. if (!__cache_inited) {
  11205. __cache_inited = true;
  11206. __initCacheEvent();
  11207. }
  11208. },
  11209. __initMaskEvent: function() {
  11210. this.on("mousewheel", function(e) {
  11211. var evt = e.originalEvent;
  11212. e.preventDefault();
  11213. e.stopPropagation();
  11214. this.trigger("scroll", {
  11215. delta: evt.wheelDelta || evt.deltaY || evt.detail
  11216. });
  11217. });
  11218. this.on("click", function(e) {
  11219. e.stopPropagation();
  11220. if (e.target === this.__element) {
  11221. this.trigger("maskclick");
  11222. }
  11223. });
  11224. },
  11225. // 定位
  11226. __resize: function() {
  11227. var targetRect = null;
  11228. // body特殊处理
  11229. if (this.__targetIsBody()) {
  11230. targetRect = $(Utils.getView(this.__target));
  11231. targetRect = {
  11232. width: targetRect.width(),
  11233. height: targetRect.height()
  11234. };
  11235. } else {
  11236. targetRect = Utils.getRect(this.__target);
  11237. }
  11238. this.__element.style.width = targetRect.width + "px";
  11239. this.__element.style.height = targetRect.height + "px";
  11240. },
  11241. __position: function() {
  11242. var location = null, targetRect = null;
  11243. if (this.__targetIsBody()) {
  11244. location = {
  11245. top: 0,
  11246. left: 0
  11247. };
  11248. } else {
  11249. targetRect = Utils.getRect(this.__target);
  11250. location = {
  11251. top: targetRect.top,
  11252. left: targetRect.left
  11253. };
  11254. }
  11255. $(this.__element).css("top", location.top + "px").css("left", location.left + "px");
  11256. },
  11257. __targetIsBody: function() {
  11258. return this.__target.tagName.toLowerCase() === "body";
  11259. }
  11260. });
  11261. // 全局监听
  11262. function __initCacheEvent() {
  11263. $(window).on("resize", function() {
  11264. $.each(__MASK_CACHE, function(i, mask) {
  11265. if (mask && !mask.isHide()) {
  11266. mask.__resize();
  11267. }
  11268. });
  11269. });
  11270. }
  11271. }
  11272. };
  11273. //src/widget/menu.js
  11274. /**
  11275. * Menu Widget
  11276. */
  11277. _p[50] = {
  11278. value: function(require) {
  11279. var Utils = _p.r(13), Item = _p.r(46), CONF = _p.r(12), $ = _p.r(4);
  11280. return Utils.createClass("Menu", {
  11281. base: _p.r(54),
  11282. constructor: function(options) {
  11283. var defaultOptions = {
  11284. column: true,
  11285. selected: -1,
  11286. textAlign: "left",
  11287. items: []
  11288. };
  11289. options = $.extend({}, defaultOptions, options);
  11290. this.callBase(options);
  11291. },
  11292. select: function(index) {
  11293. var item = this.__widgets[index];
  11294. if (!item) {
  11295. return this;
  11296. }
  11297. this.__selectItem(item);
  11298. return this;
  11299. },
  11300. clearSelect: function() {
  11301. var selectedItem = this.getSelectedItem();
  11302. if (selectedItem) {
  11303. selectedItem.unselect();
  11304. }
  11305. this.__currentSelect = -1;
  11306. this.__prevSelect = -1;
  11307. },
  11308. getItems: function() {
  11309. return this.getWidgets.apply(this, arguments);
  11310. },
  11311. getItem: function() {
  11312. return this.getWidget.apply(this, arguments);
  11313. },
  11314. appendItem: function(item) {
  11315. return this.appendWidget.apply(this, arguments);
  11316. },
  11317. insertItem: function(item) {
  11318. return this.insertWidget.apply(this, arguments);
  11319. },
  11320. removeItem: function(item) {
  11321. return this.removeWidget.apply(this, arguments);
  11322. },
  11323. clearItems: function() {
  11324. while (this.getItems().length) {
  11325. this.removeItem(0);
  11326. }
  11327. return this;
  11328. },
  11329. getSelected: function() {
  11330. return this.__currentSelect;
  11331. },
  11332. getSelectedItem: function() {
  11333. return this.getItem(this.__currentSelect);
  11334. },
  11335. insertWidget: function(index, widget) {
  11336. var returnValue = this.callBase(index, widget);
  11337. if (returnValue === null) {
  11338. return returnValue;
  11339. }
  11340. if (index <= this.__currentSelect) {
  11341. this.__currentSelect++;
  11342. }
  11343. if (index <= this.__prevSelect) {
  11344. this.__prevSelect++;
  11345. }
  11346. return returnValue;
  11347. },
  11348. removeWidget: function(widget) {
  11349. var index = widget;
  11350. if (typeof index !== "number") {
  11351. index = this.indexOf(widget);
  11352. }
  11353. widget = this.callBase(widget);
  11354. if (index === this.__currentSelect) {
  11355. this.__currentSelect = -1;
  11356. } else if (index < this.__currentSelect) {
  11357. this.__currentSelect--;
  11358. }
  11359. if (index === this.__prevSelect) {
  11360. this.__prevSelect = -1;
  11361. } else if (index < this.__prevSelect) {
  11362. this.__prevSelect--;
  11363. }
  11364. return widget;
  11365. },
  11366. __initOptions: function() {
  11367. this.callBase();
  11368. this.__prevSelect = -1;
  11369. this.__currentSelect = this.__options.selected;
  11370. this.widgetName = "Menu";
  11371. },
  11372. __render: function() {
  11373. var _self = this, textAlign = this.__options.textAlign, selected = this.__options.selected;
  11374. this.callBase();
  11375. $(this.__element).addClass(CONF.classPrefix + "menu");
  11376. $.each(this.__options.items, function(index, itemOption) {
  11377. if (typeof itemOption !== "object") {
  11378. itemOption = {
  11379. label: itemOption
  11380. };
  11381. }
  11382. itemOption.selected = index === selected;
  11383. itemOption.textAlign = textAlign;
  11384. _self.appendItem(new Item(itemOption));
  11385. });
  11386. },
  11387. // 初始化点击事件
  11388. __initEvent: function() {
  11389. this.callBase();
  11390. this.on("itemclick", function(e) {
  11391. this.__selectItem(e.widget, true);
  11392. });
  11393. },
  11394. __selectItem: function(item, isUserTrigger) {
  11395. var info = null;
  11396. if (this.__currentSelect > -1) {
  11397. this.__widgets[this.__currentSelect].unselect();
  11398. }
  11399. this.__prevSelect = this.__currentSelect;
  11400. this.__currentSelect = this.indexOf(item);
  11401. item.select();
  11402. info = {
  11403. index: this.__currentSelect,
  11404. label: item.getLabel(),
  11405. value: item.getValue()
  11406. };
  11407. if (isUserTrigger) {
  11408. this.trigger("menuitemclick", info);
  11409. }
  11410. this.trigger("select", info);
  11411. if (this.__prevSelect !== this.__currentSelect) {
  11412. var fromItem = this.__widgets[this.__prevSelect] || null;
  11413. this.trigger("change", {
  11414. from: {
  11415. index: this.__prevSelect,
  11416. label: fromItem && fromItem.getLabel(),
  11417. value: fromItem && fromItem.getValue()
  11418. },
  11419. to: {
  11420. index: this.__currentSelect,
  11421. label: item.getLabel(),
  11422. value: item.getValue()
  11423. }
  11424. });
  11425. }
  11426. },
  11427. __valid: function(target) {
  11428. return target instanceof Item;
  11429. }
  11430. });
  11431. }
  11432. };
  11433. //src/widget/panel.js
  11434. /**
  11435. * 容器类: Panel
  11436. */
  11437. _p[51] = {
  11438. value: function(require) {
  11439. var Utils = _p.r(13), panelTpl = _p.r(30), $ = _p.r(4);
  11440. return Utils.createClass("Panel", {
  11441. base: _p.r(39),
  11442. constructor: function(options) {
  11443. var defaultOptions = {};
  11444. options = $.extend({}, defaultOptions, options);
  11445. this.callBase(options);
  11446. },
  11447. __render: function() {
  11448. var $content = null;
  11449. this.callBase();
  11450. $content = $('<div class="fui-panel-content"></div>');
  11451. this.__contentElement.appendChild($content[0]);
  11452. this.__contentElement = $content[0];
  11453. },
  11454. __initOptions: function() {
  11455. this.callBase();
  11456. this.widgetName = "Panel";
  11457. this.__tpl = panelTpl;
  11458. }
  11459. });
  11460. }
  11461. };
  11462. //src/widget/popup-menu.js
  11463. _p[52] = {
  11464. value: function(require) {
  11465. var Utils = _p.r(13), CONF = _p.r(12), $ = _p.r(4), Menu = _p.r(50);
  11466. return Utils.createClass("PopupMenu", {
  11467. base: _p.r(53),
  11468. constructor: function(options) {
  11469. this.callBase($.extend({
  11470. menu: {}
  11471. }, options));
  11472. },
  11473. getMenuWidget: function() {
  11474. return this.__menuWidget;
  11475. },
  11476. __initOptions: function() {
  11477. this.callBase();
  11478. this.widgetName = "PopupMenu";
  11479. },
  11480. __render: function() {
  11481. this.callBase();
  11482. this.__menuWidget = new Menu();
  11483. this.appendWidget(this.__menuWidget);
  11484. $(this.__element).addClass(CONF.classPrefix + "popup-menu");
  11485. }
  11486. });
  11487. }
  11488. };
  11489. //src/widget/popup.js
  11490. /**
  11491. * 容器类: PPanel = Positioning Panel
  11492. */
  11493. _p[53] = {
  11494. value: function(require) {
  11495. var Utils = _p.r(13), CONF = _p.r(12), Widget = _p.r(60), Mask = _p.r(49), $ = _p.r(4);
  11496. return Utils.createClass("Popup", {
  11497. base: _p.r(54),
  11498. constructor: function(options) {
  11499. var defaultOptions = {
  11500. mask: {}
  11501. };
  11502. options = $.extend({}, defaultOptions, options);
  11503. this.callBase(options);
  11504. },
  11505. open: function() {
  11506. this.__fire("open", function() {
  11507. this.show();
  11508. });
  11509. return this;
  11510. },
  11511. close: function() {
  11512. this.__fire("close", function() {
  11513. this.hide();
  11514. });
  11515. return this;
  11516. },
  11517. show: function() {
  11518. if (!this.__target) {
  11519. this.__target = this.__element.ownerDocument.body;
  11520. }
  11521. if (!this.__inDoc) {
  11522. this.__inDoc = true;
  11523. this.appendTo(this.__element.ownerDocument.body);
  11524. }
  11525. this.__maskWidget.show();
  11526. this.callBase();
  11527. this.__openState = true;
  11528. return this;
  11529. },
  11530. hide: function() {
  11531. this.callBase();
  11532. this.__maskWidget.hide();
  11533. this.__openState = false;
  11534. return this;
  11535. },
  11536. toggle: function() {
  11537. this.isOpen() ? this.close() : this.open();
  11538. return this;
  11539. },
  11540. isOpen: function() {
  11541. return this.__openState;
  11542. },
  11543. __initOptions: function() {
  11544. this.callBase();
  11545. this.widgetName = "Popup";
  11546. this.__target = this.__options.target;
  11547. this.__layout = this.__options.layout;
  11548. this.__inDoc = false;
  11549. this.__openState = false;
  11550. this.__maskWidget = null;
  11551. if (this.__target instanceof Widget) {
  11552. this.__target = this.__target.getElement();
  11553. }
  11554. },
  11555. __render: function() {
  11556. this.callBase();
  11557. $(this.__element).addClass(CONF.classPrefix + "popup");
  11558. this.__maskWidget = new Mask(this.__options.mask);
  11559. if (this.__options.draggable) {
  11560. this.__initDraggable();
  11561. }
  11562. this.__initMaskEvent();
  11563. },
  11564. __initMaskEvent: function() {
  11565. var _self = this;
  11566. this.__maskWidget.on("click", function() {
  11567. _self.close();
  11568. });
  11569. }
  11570. });
  11571. }
  11572. };
  11573. //src/widget/ppanel.js
  11574. /*jshint camelcase:false*/
  11575. /**
  11576. * 容器类: PPanel = Positioning Panel
  11577. */
  11578. _p[54] = {
  11579. value: function(require) {
  11580. var Utils = _p.r(13), CONF = _p.r(12), Widget = _p.r(60), LAYOUT = CONF.layout, $ = _p.r(4);
  11581. return Utils.createClass("PPanel", {
  11582. base: _p.r(51),
  11583. constructor: function(options) {
  11584. var defaultOptions = {
  11585. layout: LAYOUT.BOTTOM,
  11586. target: null,
  11587. // 边界容器
  11588. bound: null,
  11589. // 和边界之间的最小距离
  11590. diff: 10,
  11591. hide: true,
  11592. resize: "all",
  11593. iframe: false
  11594. };
  11595. options = $.extend({}, defaultOptions, options);
  11596. this.callBase(options);
  11597. },
  11598. positionTo: function(target, layout) {
  11599. if (target instanceof Widget) {
  11600. target = target.getElement();
  11601. }
  11602. this.__target = target;
  11603. if (layout) {
  11604. this.__layout = layout;
  11605. }
  11606. return this;
  11607. },
  11608. show: function() {
  11609. var docNode = null;
  11610. if (!this.__target) {
  11611. return this.callBase();
  11612. }
  11613. if (!this.__options.bound) {
  11614. this.__options.bound = this.__target.ownerDocument.body;
  11615. }
  11616. docNode = this.__target.ownerDocument.documentElement;
  11617. if (!$.contains(docNode, this.__element)) {
  11618. this.__target.ownerDocument.body.appendChild(this.__element);
  11619. }
  11620. if ($.contains(docNode, this.__target)) {
  11621. this.callBase(Utils.getMarker());
  11622. this.__position();
  11623. this.__resize();
  11624. }
  11625. return this;
  11626. },
  11627. __initOptions: function() {
  11628. this.callBase();
  11629. this.widgetName = "PPanel";
  11630. this.__target = this.__options.target;
  11631. this.__layout = this.__options.layout;
  11632. // 记录是否已调整过高度
  11633. this.__height_resized = false;
  11634. },
  11635. __render: function() {
  11636. this.callBase();
  11637. if (this.__options.iframe) {
  11638. $('<iframe class="fui-ppanel-cover" frameborder="0"></iframe>').appendTo(this.__element);
  11639. }
  11640. $(this.__element).addClass(CONF.classPrefix + "ppanel");
  11641. },
  11642. // 执行定位
  11643. __position: function() {
  11644. var location = null, className = CONF.classPrefix + "ppanel-position";
  11645. $(this.__element).addClass(className);
  11646. location = this.__getLocation();
  11647. $(this.__element).css("top", location.top + "px").css("left", location.left + "px");
  11648. },
  11649. __resize: function() {
  11650. var targetRect = Utils.getBound(this.__target);
  11651. switch (this.__options.resize) {
  11652. case "all":
  11653. this.__resizeWidth(targetRect);
  11654. this.__resizeHeight();
  11655. break;
  11656. case "width":
  11657. this.__resizeWidth(targetRect);
  11658. break;
  11659. case "height":
  11660. this.__resizeHeight();
  11661. break;
  11662. }
  11663. },
  11664. /**
  11665. * 在未指定宽度的情况下,执行自动宽度适配。
  11666. * 如果构件未被指定宽度, 则添加一个最小宽度, 该最小宽度等于给定目标的宽度
  11667. * @param targetRect 传递该参数,是出于整体性能上的考虑。
  11668. * @private
  11669. */
  11670. __resizeWidth: function(targetRect) {
  11671. if (!this.__target) {
  11672. return;
  11673. }
  11674. var $ele = $(this.__element), w = $ele.outerWidth(), h = $ele.outerHeight(), minWidth = targetRect.width - w - h;
  11675. this.__element.style.minWidth = minWidth + "px";
  11676. },
  11677. /**
  11678. * 调整panel高度,使其不超过边界范围,如果已设置高度, 则不进行调整
  11679. * @private
  11680. */
  11681. __resizeHeight: function() {
  11682. var boundRect = null, panelRect = null, diff = 0;
  11683. panelRect = Utils.getRect(this.__element);
  11684. panelRect.height = this.__element.scrollHeight;
  11685. panelRect.bottom = panelRect.top + panelRect.height;
  11686. boundRect = this.__getBoundRect();
  11687. diff = panelRect.bottom - boundRect.bottom;
  11688. if (diff > 0) {
  11689. this.__height_resized = true;
  11690. diff = panelRect.height - diff - this.__options.diff;
  11691. $(this.__element).css("height", diff + "px");
  11692. } else if (this.__height_resized) {
  11693. this.__element.style.height = null;
  11694. }
  11695. },
  11696. __getLocation: function() {
  11697. var targetRect = Utils.getBound(this.__target);
  11698. switch (this.__layout) {
  11699. case LAYOUT.CENTER:
  11700. case LAYOUT.MIDDLE:
  11701. return this.__getCenterLayout(targetRect);
  11702. case LAYOUT.LEFT:
  11703. case LAYOUT.RIGHT:
  11704. case LAYOUT.BOTTOM:
  11705. case LAYOUT.TOP:
  11706. return this.__getOuterLayout(targetRect);
  11707. default:
  11708. return this.__getInnerLayout(targetRect);
  11709. }
  11710. return location;
  11711. },
  11712. /**
  11713. * 居中定位的位置属性
  11714. * @private
  11715. */
  11716. __getCenterLayout: function(targetRect) {
  11717. var location = {
  11718. top: 0,
  11719. left: 0
  11720. }, panelRect = Utils.getRect(this.__element), diff = 0;
  11721. diff = targetRect.height - panelRect.height;
  11722. if (diff > 0) {
  11723. location.top = targetRect.top + diff / 2;
  11724. }
  11725. diff = targetRect.width - panelRect.width;
  11726. if (diff > 0) {
  11727. location.left = targetRect.left + diff / 2;
  11728. }
  11729. return location;
  11730. },
  11731. /**
  11732. * 获取外部布局定位属性
  11733. * @returns {{top: number, left: number}}
  11734. * @private
  11735. */
  11736. __getOuterLayout: function(targetRect) {
  11737. var location = {
  11738. top: 0,
  11739. left: 0
  11740. }, panelRect = Utils.getRect(this.__element);
  11741. switch (this.__layout) {
  11742. case LAYOUT.TOP:
  11743. location.left = targetRect.left;
  11744. location.top = targetRect.top - panelRect.height;
  11745. break;
  11746. case LAYOUT.LEFT:
  11747. location.top = targetRect.top;
  11748. location.left = targetRect.left - panelRect.width;
  11749. break;
  11750. case LAYOUT.RIGHT:
  11751. location.top = targetRect.top;
  11752. location.left = targetRect.right;
  11753. break;
  11754. case LAYOUT.BOTTOM:
  11755. /* falls through */
  11756. default:
  11757. location.left = targetRect.left;
  11758. location.top = targetRect.bottom;
  11759. break;
  11760. }
  11761. return location;
  11762. },
  11763. /**
  11764. * 获取内部布局定位属性,并且,内部布局还拥有根据水平空间的大小,自动进行更新定位的功能
  11765. * @private
  11766. */
  11767. __getInnerLayout: function(targetRect) {
  11768. var location = {
  11769. top: 0,
  11770. left: 0
  11771. }, rect = targetRect, panelRect = Utils.getRect(this.__element);
  11772. switch (this.__layout) {
  11773. case LAYOUT.LEFT_TOP:
  11774. location.top = rect.top;
  11775. location.left = rect.left;
  11776. break;
  11777. case LAYOUT.RIGHT_TOP:
  11778. location.top = rect.top;
  11779. location.left = rect.left + rect.width - panelRect.width;
  11780. break;
  11781. case LAYOUT.LEFT_BOTTOM:
  11782. location.top = rect.top + rect.height - panelRect.height;
  11783. location.left = rect.left;
  11784. break;
  11785. case LAYOUT.RIGHT_BOTTOM:
  11786. location.top = rect.top + rect.height - panelRect.height;
  11787. location.left = rect.left + rect.width - panelRect.width;
  11788. break;
  11789. }
  11790. return this.__correctionLocation(location);
  11791. },
  11792. __getBoundRect: function() {
  11793. var width = -1, height = -1, view = null;
  11794. if (this.__options.bound.tagName.toLowerCase() === "body") {
  11795. view = Utils.getView(this.__options.bound);
  11796. width = $(view).width();
  11797. height = $(view).height();
  11798. return {
  11799. top: 0,
  11800. left: 0,
  11801. right: width,
  11802. bottom: height,
  11803. width: width,
  11804. height: height
  11805. };
  11806. } else {
  11807. return Utils.getRect(this.__options.bound);
  11808. }
  11809. },
  11810. // 如果发生“溢出”,则修正定位
  11811. __correctionLocation: function(location) {
  11812. var panelRect = Utils.getRect(this.__element), targetRect = Utils.getRect(this.__target), boundRect = this.__getBoundRect();
  11813. switch (this.__layout) {
  11814. case LAYOUT.LEFT_TOP:
  11815. case LAYOUT.LEFT_BOTTOM:
  11816. if (location.left + panelRect.width > boundRect.right) {
  11817. location.left += targetRect.width - panelRect.width;
  11818. }
  11819. break;
  11820. case LAYOUT.RIGHT_TOP:
  11821. case LAYOUT.RIGHT_BOTTOM:
  11822. if (location.left < boundRect.left) {
  11823. location.left = targetRect.left;
  11824. }
  11825. break;
  11826. }
  11827. return location;
  11828. }
  11829. });
  11830. }
  11831. };
  11832. //src/widget/select-menu.js
  11833. /**
  11834. * SelectMenu构件
  11835. * 提供从下拉菜单中选中某一项的功能构件
  11836. */
  11837. _p[55] = {
  11838. value: function(require) {
  11839. var $ = _p.r(4), CONF = _p.r(12), Panel = _p.r(51), PPanel = _p.r(54), Button = _p.r(37), Creator = _p.r(0), Mask = _p.r(49);
  11840. return _p.r(13).createClass("SelectMenu", {
  11841. base: Panel,
  11842. constructor: function(options) {
  11843. var defaultOptions = {
  11844. // bed 是Panel的实例
  11845. bed: {
  11846. className: "fui-select-menu-bed"
  11847. },
  11848. button: {
  11849. className: "fui-select-menu-btn"
  11850. },
  11851. events: [ "btnclick" ],
  11852. selected: -1
  11853. };
  11854. options = $.extend({}, defaultOptions, options);
  11855. this.callBase(options);
  11856. },
  11857. show: function() {
  11858. this.__widgetMenu.show();
  11859. this.__mask.show();
  11860. },
  11861. hide: function() {
  11862. this.__widgetMenu.hide();
  11863. this.__mask.hide();
  11864. },
  11865. getValue: function() {
  11866. var selectedWidet = this.__widgets[this.__selected];
  11867. return selectedWidet ? selectedWidet.getValue() : null;
  11868. },
  11869. getSelected: function() {
  11870. return this.__widgets[this.__selected];
  11871. },
  11872. select: function(index) {
  11873. var widget = this.__widgets[index], className = "fui-select-menu-selected", oldIndex = this.__selected, oldSelected = this.__widgets[this.__selected], bedElement = this.__bed.getElement();
  11874. if (!widget) {
  11875. return this;
  11876. }
  11877. if (oldSelected) {
  11878. oldSelected.removeClass(className);
  11879. }
  11880. bedElement.innerHTML = "";
  11881. bedElement.appendChild(widget.cloneElement());
  11882. widget.addClass(className);
  11883. this.__selected = index;
  11884. this.trigger("select", {
  11885. index: index,
  11886. widget: widget
  11887. });
  11888. if (this.__selected !== oldIndex) {
  11889. this.trigger("change", {
  11890. from: {
  11891. index: oldIndex,
  11892. widget: oldSelected
  11893. },
  11894. to: {
  11895. index: index,
  11896. widget: widget
  11897. }
  11898. });
  11899. }
  11900. return this;
  11901. },
  11902. selectByWidget: function(widget) {
  11903. return this.select(this.indexOf(widget));
  11904. },
  11905. selectByValue: function(value) {
  11906. var index = -1;
  11907. $.each(this.__widgets, function(i, widget) {
  11908. if (widget.getValue() === value) {
  11909. index = i;
  11910. return false;
  11911. }
  11912. });
  11913. return this.select(index);
  11914. },
  11915. __render: function() {
  11916. this.__bed = new Panel(this.__options.bed);
  11917. this.__dropBtn = new Button(this.__options.button);
  11918. this.__widgetMenu = new PPanel({
  11919. className: "fui-select-menu-container",
  11920. layout: CONF.layout.LEFT_TOP,
  11921. column: this.__column
  11922. });
  11923. this.__mask = new Mask();
  11924. var widgets = this.__initWidgets();
  11925. this.callBase();
  11926. $(this.__element).addClass(CONF.classPrefix + "select-menu");
  11927. this.appendWidgets([ this.__bed, this.__dropBtn, this.__mask, this.__widgetMenu ]);
  11928. this.__widgets = [];
  11929. this.__oldContentElement = this.__contentElement;
  11930. this.__contentElement = this.__widgetMenu;
  11931. this.appendWidgets(widgets);
  11932. this.__widgetMenu.positionTo(this.getElement());
  11933. if (!$.isNumeric(this.__options.selected)) {
  11934. this.__bed.appendWidget(Creator.parse(this.__options.selected));
  11935. } else if (this.__options.selected != -1) {
  11936. this.select(this.__options.selected);
  11937. }
  11938. },
  11939. __initWidgets: function() {
  11940. var widgets = [];
  11941. if (!this.__options.widgets) {
  11942. return;
  11943. }
  11944. $.each(this.__options.widgets, function(index, widget) {
  11945. widgets.push(Creator.parse(widget));
  11946. });
  11947. return widgets;
  11948. },
  11949. __initEvent: function() {
  11950. this.callBase();
  11951. var _self = this;
  11952. this.__dropBtn.on("btnclick", function() {
  11953. _self.show();
  11954. });
  11955. this.__mask.on("click", function() {
  11956. _self.hide();
  11957. });
  11958. this.__widgetMenu.on(this.__options.events.join(" "), function(e) {
  11959. var target = e.target;
  11960. if (target === _self.__oldContentElement || target === _self.getElement) {
  11961. return;
  11962. }
  11963. e.stopPropagation();
  11964. _self.selectByWidget(e.widget);
  11965. _self.hide();
  11966. return false;
  11967. });
  11968. },
  11969. __initOptions: function() {
  11970. this.callBase();
  11971. this.widgetName = "SelectMenu";
  11972. // 被选中的元素
  11973. this.__bed = null;
  11974. // 下拉按钮
  11975. this.__dropBtn = null;
  11976. this.__widgetMenu = null;
  11977. this.__mask = null;
  11978. this.__widgets = [];
  11979. this.__selected = -1;
  11980. this.__oldContentElement = null;
  11981. this.__column = this.__options.column;
  11982. delete this.__options.column;
  11983. }
  11984. });
  11985. }
  11986. };
  11987. //src/widget/separator.js
  11988. /**
  11989. * Separator(分隔符) Widget
  11990. */
  11991. _p[56] = {
  11992. value: function(require) {
  11993. var Utils = _p.r(13), separatorTpl = _p.r(31), $ = _p.r(4);
  11994. return Utils.createClass("Separator", {
  11995. base: _p.r(60),
  11996. constructor: function(options) {
  11997. var defaultOptions = {
  11998. width: 1,
  11999. height: "100%",
  12000. bgcolor: "#e1e1e1"
  12001. };
  12002. options = $.extend({}, defaultOptions, options);
  12003. this.callBase(options);
  12004. },
  12005. __initOptions: function() {
  12006. this.callBase();
  12007. this.widgetName = "Separator";
  12008. this.__tpl = separatorTpl;
  12009. }
  12010. });
  12011. }
  12012. };
  12013. //src/widget/spin-button.js
  12014. /**
  12015. * SpinButton对象
  12016. * 数值按钮构件
  12017. */
  12018. _p[57] = {
  12019. value: function(require) {
  12020. var $ = _p.r(4), CONF = _p.r(12), tpl = _p.r(32), Button = _p.r(37), Input = _p.r(45), Panel = _p.r(51);
  12021. return _p.r(13).createClass("SpinButton", {
  12022. base: _p.r(60),
  12023. constructor: function(options) {
  12024. var defaultOptions = {
  12025. suffix: null,
  12026. selected: -1,
  12027. items: []
  12028. };
  12029. options = $.extend({}, defaultOptions, options);
  12030. this.callBase(options);
  12031. },
  12032. getValue: function() {
  12033. return this.__options.items[this.__currentSelected] || null;
  12034. },
  12035. // Overload
  12036. setValue: function(value) {},
  12037. select: function(index) {
  12038. this.__update(index);
  12039. },
  12040. // 根据值进行选择
  12041. selectByValue: function(value) {
  12042. value = value + "";
  12043. this.__update($.inArray(value, this.__options.items));
  12044. },
  12045. __render: function() {
  12046. this.callBase();
  12047. this.__buttons = [ new Button({
  12048. className: CONF.classPrefix + "spin-up-btn"
  12049. }), new Button({
  12050. className: CONF.classPrefix + "spin-down-btn"
  12051. }) ];
  12052. this.__inputWidget = new Input();
  12053. this.__panelWidget = new Panel({
  12054. column: true
  12055. });
  12056. this.__inputWidget.appendTo(this.__element);
  12057. this.__panelWidget.appendWidget(this.__buttons[0]);
  12058. this.__panelWidget.appendWidget(this.__buttons[1]);
  12059. this.__panelWidget.appendTo(this.__element);
  12060. this.__initSelected(this.__options.selected);
  12061. },
  12062. __initEvent: function() {
  12063. var _self = this;
  12064. this.callBase();
  12065. this.__buttons[0].on("btnclick", function() {
  12066. _self.__update(_self.__currentSelected - 1);
  12067. });
  12068. this.__buttons[1].on("btnclick", function() {
  12069. _self.__update(_self.__currentSelected + 1);
  12070. });
  12071. },
  12072. __initSelected: function(index) {
  12073. this.__update(index, false);
  12074. },
  12075. __update: function(index, isTrigger) {
  12076. var oldIndex = -1, value = null, toValue = null;
  12077. if (index < 0 || index >= this.__options.items.length) {
  12078. return;
  12079. }
  12080. oldIndex = this.__currentSelected;
  12081. this.__currentSelected = index;
  12082. toValue = this.__options.items[this.__currentSelected];
  12083. value = toValue + " " + (this.__options.suffix || "");
  12084. this.__inputWidget.setValue(value);
  12085. if (isTrigger !== false) {
  12086. this.trigger("change", {
  12087. from: this.__options.items[oldIndex] || null,
  12088. to: toValue
  12089. });
  12090. }
  12091. },
  12092. __initOptions: function() {
  12093. var items = this.__options.items;
  12094. this.callBase();
  12095. this.widgetName = "SpinButton";
  12096. this.__tpl = tpl;
  12097. this.__buttons = [];
  12098. this.__panelWidget = null;
  12099. this.__inputWidget = null;
  12100. this.__currentSelected = -1;
  12101. $.each(items, function(index, val) {
  12102. items[index] = val + "";
  12103. });
  12104. }
  12105. });
  12106. }
  12107. };
  12108. //src/widget/tabs.js
  12109. /**
  12110. * Tabs Widget
  12111. */
  12112. _p[58] = {
  12113. value: function(require) {
  12114. var $ = _p.r(4), CONF = _p.r(12), tpl = _p.r(33), Button = _p.r(37), Panel = _p.r(51);
  12115. return _p.r(13).createClass("Tabs", {
  12116. base: _p.r(60),
  12117. constructor: function(options) {
  12118. var defaultOptions = {
  12119. selected: 0,
  12120. buttons: [],
  12121. panels: []
  12122. };
  12123. options = $.extend({}, defaultOptions, options);
  12124. this.callBase(options);
  12125. },
  12126. getButtons: function() {
  12127. return this.__btns;
  12128. },
  12129. getButton: function(index) {
  12130. return this.getButtons()[index] || null;
  12131. },
  12132. getButtonByValue: function(value) {
  12133. var button = null;
  12134. $.each(this.__btns, function(i, btn) {
  12135. if (btn.getValue() === value) {
  12136. button = btn;
  12137. return false;
  12138. }
  12139. });
  12140. return button;
  12141. },
  12142. getPanels: function() {
  12143. return this.__panels;
  12144. },
  12145. getPanel: function(index) {
  12146. return this.getPanels()[index] || null;
  12147. },
  12148. getPanelByValue: function(value) {
  12149. var panel = null;
  12150. $.each(this.__panels, function(i, pan) {
  12151. if (pan.getValue() === value) {
  12152. panel = pan;
  12153. return false;
  12154. }
  12155. });
  12156. return panel;
  12157. },
  12158. getSelectedIndex: function() {
  12159. return this.__selected;
  12160. },
  12161. getSelected: function() {
  12162. var index = this.getSelectedIndex();
  12163. return {
  12164. button: this.getButton(index),
  12165. panel: this.getPanel(index)
  12166. };
  12167. },
  12168. appendTab: function(tabOpt) {
  12169. tabOpt.panels = tabOpt.panels || [];
  12170. return this.__renderByOptions(tabOpt);
  12171. },
  12172. removeTab: function(index) {
  12173. if (index < 0) {
  12174. return null;
  12175. }
  12176. var btn = this.__btns.splice(index, 1), panel = this.__panels.splice(index, 1);
  12177. if (!btn.length) {
  12178. return null;
  12179. }
  12180. btn = btn[0];
  12181. panel = panel[0];
  12182. btn.remove();
  12183. panel.remove();
  12184. return {
  12185. button: btn,
  12186. panel: panel
  12187. };
  12188. },
  12189. /**
  12190. * 选择接口
  12191. * @param index 需要选中的tab页索引
  12192. */
  12193. select: function(index) {
  12194. var toInfo = null;
  12195. if (!this.__selectItem(index)) {
  12196. return this;
  12197. }
  12198. toInfo = this.__getInfo(index);
  12199. this.trigger("tabsselect", toInfo);
  12200. if (this.__prevSelected !== this.__selected) {
  12201. this.trigger("tabschange", {
  12202. from: this.__getInfo(this.__prevSelected),
  12203. to: toInfo
  12204. });
  12205. }
  12206. return this;
  12207. },
  12208. getIndexByButton: function(btn) {
  12209. return $.inArray(btn, this.__btns);
  12210. },
  12211. /**
  12212. * 把所有button追加到其他容器中
  12213. */
  12214. appendButtonTo: function(container) {
  12215. $.each(this.__btns, function(index, btn) {
  12216. btn.appendTo(container);
  12217. });
  12218. },
  12219. appendPanelTo: function(container) {
  12220. $.each(this.__panels, function(index, panel) {
  12221. panel.appendTo(container);
  12222. });
  12223. },
  12224. __render: function() {
  12225. this.callBase();
  12226. this.__btnWrap = $(".fui-tabs-button-wrap", this.__element)[0];
  12227. this.__panelWrap = $(".fui-tabs-panel-wrap", this.__element)[0];
  12228. this.__renderByOptions(this.__options);
  12229. this.__selectItem(this.__options.selected);
  12230. },
  12231. __renderByOptions: function(options) {
  12232. var _self = this, mapping = [], btns = this.__btns, panels = this.__panels, btnWrap = this.__btnWrap, panelWrap = this.__panelWrap;
  12233. $.each(options.buttons, function(index, opt) {
  12234. var btn = null, panel = null;
  12235. if (typeof opt !== "object") {
  12236. opt = {
  12237. label: opt
  12238. };
  12239. }
  12240. btn = new Button(opt);
  12241. btn.on("click", function() {
  12242. _self.select(_self.getIndexByButton(this));
  12243. });
  12244. opt = options.panels[index] || {};
  12245. opt.hide = true;
  12246. panel = new Panel(opt);
  12247. btns.push(btn);
  12248. panels.push(panel);
  12249. mapping.push({
  12250. button: btn,
  12251. panel: panel
  12252. });
  12253. btn.appendTo(btnWrap);
  12254. panel.appendTo(panelWrap);
  12255. });
  12256. return mapping;
  12257. },
  12258. __initOptions: function() {
  12259. this.callBase();
  12260. this.widgetName = "Tabs";
  12261. this.__tpl = tpl;
  12262. this.__btns = [];
  12263. this.__panels = [];
  12264. this.__prevSelected = -1;
  12265. this.__selected = -1;
  12266. this.__btnWrap = null;
  12267. this.__panelWrap = null;
  12268. // panels不设置的情况下, 将根据button创建
  12269. if (this.__options.panels === null) {
  12270. this.__options.panels = [];
  12271. this.__options.panels.length = this.__options.buttons.length;
  12272. }
  12273. },
  12274. __selectItem: function(index) {
  12275. var btn = this.getButton(index), prevBtn = this.getButton(this.__selected), className = CONF.classPrefix + "selected";
  12276. if (!btn) {
  12277. return false;
  12278. }
  12279. if (prevBtn) {
  12280. prevBtn.removeClass(className);
  12281. this.getPanel(this.__selected).hide();
  12282. }
  12283. btn.addClass(className);
  12284. this.getPanel(index).show();
  12285. this.__prevSelected = this.__selected;
  12286. this.__selected = index;
  12287. return true;
  12288. },
  12289. // 根据给定的tab索引获取先关的信息, 这些信息将用于事件携带的参数
  12290. __getInfo: function(index) {
  12291. return {
  12292. index: index,
  12293. button: this.getButton(index),
  12294. panel: this.getPanel(index)
  12295. };
  12296. }
  12297. });
  12298. }
  12299. };
  12300. //src/widget/toggle-button.js
  12301. /**
  12302. * ToggleButton对象
  12303. * 可切换按钮构件
  12304. */
  12305. _p[59] = {
  12306. value: function(require) {
  12307. var $ = _p.r(4), CONF = _p.r(12);
  12308. return _p.r(13).createClass("ToggleButton", {
  12309. base: _p.r(37),
  12310. constructor: function(options) {
  12311. var defaultOptions = {
  12312. // 按钮初始时是否按下
  12313. pressed: false
  12314. };
  12315. options = $.extend({}, defaultOptions, options);
  12316. this.callBase(options);
  12317. },
  12318. /**
  12319. * 当前按钮是否已按下
  12320. */
  12321. isPressed: function() {
  12322. return this.__state;
  12323. },
  12324. /**
  12325. * 按下按钮
  12326. */
  12327. press: function() {
  12328. var className = CONF.classPrefix + "button-pressed";
  12329. $(this.__element).addClass(className);
  12330. this.__updateState(true);
  12331. },
  12332. /**
  12333. * 弹起按钮
  12334. */
  12335. bounce: function() {
  12336. var className = CONF.classPrefix + "button-pressed";
  12337. $(this.__element).removeClass(className);
  12338. this.__updateState(false);
  12339. },
  12340. toggle: function() {
  12341. if (this.__state) {
  12342. this.bounce();
  12343. } else {
  12344. this.press();
  12345. }
  12346. },
  12347. __initOptions: function() {
  12348. this.callBase();
  12349. this.widgetName = "ToggleButton";
  12350. // 按钮当前状态
  12351. this.__state = false;
  12352. },
  12353. __render: function() {
  12354. this.callBase();
  12355. $(this.__element).addClass(CONF.classPrefix + "toggle-button");
  12356. this.__initButtonState();
  12357. return this;
  12358. },
  12359. __initButtonState: function() {
  12360. if (!this.__options.pressed) {
  12361. return;
  12362. }
  12363. // 不直接调用press方法, 防止初始化时事件的触发
  12364. $(this.__element).addClass(CONF.classPrefix + "button-pressed");
  12365. this.__state = true;
  12366. },
  12367. /**
  12368. * 初始化事件监听, 控制状态的切换
  12369. * @private
  12370. */
  12371. __initEvent: function() {
  12372. this.callBase();
  12373. this.on("click", function() {
  12374. this.toggle();
  12375. });
  12376. },
  12377. __updateState: function(state) {
  12378. state = !!state;
  12379. this.__state = state;
  12380. this.trigger("change", state, !state);
  12381. }
  12382. });
  12383. }
  12384. };
  12385. //src/widget/widget.js
  12386. /*jshint camelcase:false*/
  12387. /**
  12388. * widget对象
  12389. * 所有的UI组件都是widget对象
  12390. */
  12391. _p[60] = {
  12392. value: function(require) {
  12393. var prefix = "_fui_", uid = 0, CONF = _p.r(12), FUI_NS = _p.r(11), $ = _p.r(4), Utils = _p.r(13);
  12394. var Widget = Utils.createClass("Widget", {
  12395. constructor: function(options) {
  12396. var defaultOptions = {
  12397. id: null,
  12398. className: "",
  12399. disabled: false,
  12400. preventDefault: false,
  12401. text: "",
  12402. value: null,
  12403. hide: false,
  12404. width: null,
  12405. height: null
  12406. };
  12407. this.__widgetType = "widget";
  12408. this.__tpl = "";
  12409. this.__compiledTpl = "";
  12410. this.__options = {};
  12411. this.__element = null;
  12412. // 禁止获取焦点
  12413. this.__allow_focus = !!CONF.allowFocus;
  12414. this.widgetName = "Widget";
  12415. this.__extendOptions(defaultOptions, options);
  12416. this.__initOptions();
  12417. this.__render();
  12418. this.__initEvent();
  12419. this.__initWidgets && this.__initWidgets();
  12420. },
  12421. getId: function() {
  12422. return this.id;
  12423. },
  12424. getValue: function() {
  12425. return this.__options.value;
  12426. },
  12427. getOptions: function() {
  12428. return this.__options;
  12429. },
  12430. setValue: function(value) {
  12431. this.__options.value = value;
  12432. return this;
  12433. },
  12434. show: function() {
  12435. this.__show();
  12436. return this;
  12437. },
  12438. hide: function() {
  12439. this.__hide();
  12440. return this;
  12441. },
  12442. addClass: function(className) {
  12443. $(this.__element).addClass(className);
  12444. return this;
  12445. },
  12446. removeClass: function(className) {
  12447. $(this.__element).removeClass(className);
  12448. return this;
  12449. },
  12450. setStyle: function() {
  12451. $.fn.css.apply($(this.__element), arguments);
  12452. return this;
  12453. },
  12454. getStyle: function() {
  12455. return $.fn.css.apply($(this.__element), arguments);
  12456. },
  12457. /**
  12458. * 当前构件是否是处于禁用状态
  12459. * @returns {boolean|disabled|jsl.$.disabled|id.disabled}
  12460. */
  12461. isDisabled: function() {
  12462. return this.__options.disabled;
  12463. },
  12464. /**
  12465. * 启用当前构件
  12466. * @returns {Widget}
  12467. */
  12468. enable: function() {
  12469. this.__options.disabled = false;
  12470. $(this.__element).removeClass(CONF.classPrefix + "disabled");
  12471. return this;
  12472. },
  12473. /**
  12474. * 禁用当前构件
  12475. * @returns {Widget}
  12476. */
  12477. disable: function() {
  12478. this.__options.disabled = true;
  12479. $(this.__element).addClass(CONF.classPrefix + "disabled");
  12480. return this;
  12481. },
  12482. cloneElement: function() {
  12483. return this.__element.cloneNode(true);
  12484. },
  12485. /**
  12486. * 获取
  12487. * @returns {null}
  12488. */
  12489. getElement: function() {
  12490. return this.__element;
  12491. },
  12492. appendTo: function(container) {
  12493. if (Utils.isElement(container)) {
  12494. container.appendChild(this.__element);
  12495. } else if (container instanceof Widget) {
  12496. container.__appendChild(this);
  12497. } else {
  12498. throw new Error("TypeError: Widget.appendTo()");
  12499. }
  12500. return this;
  12501. },
  12502. remove: function() {
  12503. var parent = this.__element.parentNode;
  12504. if (parent) {
  12505. parent.removeChild(this.__element);
  12506. }
  12507. return this;
  12508. },
  12509. off: function(type, cb) {
  12510. $(this.__element).off(cb && cb.__fui_listener);
  12511. return this;
  12512. },
  12513. on: function(type, cb) {
  12514. if (!this.__options.preventDefault) {
  12515. this.__on(type, cb);
  12516. }
  12517. return this;
  12518. },
  12519. __initOptions: function() {},
  12520. /**
  12521. * 根据模板渲染构件, 如果该构件已经渲染过, 则不会进行二次渲染
  12522. * @returns {Widget}
  12523. */
  12524. __render: function() {
  12525. var $ele = null, tpl = this.__tpl, opts = this.__options, className = null;
  12526. this.id = this.__id();
  12527. // 向NS注册自己
  12528. FUI_NS.__registerInstance(this);
  12529. this.__compiledTpl = Utils.Tpl.compile(tpl, opts);
  12530. this.__element = $(this.__compiledTpl)[0];
  12531. this.__element.setAttribute("id", this.id);
  12532. $ele = $(this.__element);
  12533. if (opts.disabled) {
  12534. $ele.addClass(CONF.classPrefix + "disabled");
  12535. }
  12536. $ele.addClass(CONF.classPrefix + "widget");
  12537. // add custom class-name
  12538. className = opts.className;
  12539. if (className.length > 0) {
  12540. if ($.isArray(className)) {
  12541. $ele.addClass(className.join(" "));
  12542. } else {
  12543. $ele.addClass(className);
  12544. }
  12545. }
  12546. this.__initBasicEnv();
  12547. if (opts.hide) {
  12548. this.__hide();
  12549. }
  12550. if (opts.style) {
  12551. this.setStyle(opts.style);
  12552. }
  12553. return this;
  12554. },
  12555. /**
  12556. * 该方法将被appendTo调用, 用于根据各组件自身的规则插入节点, 子类可根据需要覆盖该方法
  12557. * @param childWidget 将被追加的子构件对象
  12558. */
  12559. __appendChild: function(childWidget) {
  12560. return this.__element.appendChild(childWidget.getElement());
  12561. },
  12562. __initEvent: function() {
  12563. this.on("mousedown", function(e) {
  12564. var tagName = e.target.tagName.toLowerCase();
  12565. if (!CONF.control[tagName] && !this.__allowFocus()) {
  12566. e.preventDefault();
  12567. } else {
  12568. e.stopPropagation();
  12569. }
  12570. });
  12571. },
  12572. __on: function(type, cb) {
  12573. var _self = this;
  12574. cb.__fui_listener = function(e, widget) {
  12575. var params = [];
  12576. for (var i = 0, len = arguments.length; i < len; i++) {
  12577. if (i !== 1) {
  12578. params.push(arguments[i]);
  12579. }
  12580. }
  12581. e.widget = widget;
  12582. if (!_self.isDisabled()) {
  12583. return cb.apply(_self, params);
  12584. }
  12585. };
  12586. $(this.__element).on(type, cb.__fui_listener);
  12587. return this;
  12588. },
  12589. trigger: function(type, params) {
  12590. if (!this.__options.preventDefault) {
  12591. this.__trigger.apply(this, arguments);
  12592. }
  12593. return this;
  12594. },
  12595. __allowShowTitle: function() {
  12596. return true;
  12597. },
  12598. __allowFocus: function() {
  12599. return !!this.__allow_focus;
  12600. },
  12601. __trigger: function(type, params) {
  12602. var args = [].slice.call(arguments, 1);
  12603. $(this.__element).trigger(type, [ this ].concat(args));
  12604. return this;
  12605. },
  12606. __triggerHandler: function(type, params) {
  12607. var args = [ this ].concat([].slice.call(arguments, 1));
  12608. return $(this.__element).triggerHandler(type, args);
  12609. },
  12610. /**
  12611. * 同__trigger,都触发某事件,但是该方法触发的事件会主动触发before和after,
  12612. * 同时如果before事件返回false,则后续handler都不会执行,且后续事件也不会再触发。
  12613. * @param type 事件类型
  12614. * @param handler 该事件所需要执行的函数句柄, 且该函数的返回值将作为该事件的参数发送给事件监听器
  12615. * */
  12616. __fire: function(type, handler) {
  12617. var result = {
  12618. cancel: false
  12619. };
  12620. if (/^(before|after)/.test(type)) {
  12621. return this;
  12622. }
  12623. this.__trigger("before" + type, result);
  12624. if (result.cancel === true) {
  12625. return this;
  12626. }
  12627. result = handler.call(this, type);
  12628. this.__trigger(type);
  12629. this.__trigger("after" + type, result);
  12630. return this;
  12631. },
  12632. __extendOptions: function() {
  12633. var args = [ {}, this.__options ], params = [ true ];
  12634. args = args.concat([].slice.call(arguments, 0));
  12635. for (var i = 0, len = args.length; i < len; i++) {
  12636. if (typeof args[i] !== "string") {
  12637. params.push(args[i]);
  12638. }
  12639. }
  12640. this.__options = $.extend.apply($, params);
  12641. },
  12642. __hide: function() {
  12643. $(this.__element).addClass(CONF.classPrefix + "hide");
  12644. },
  12645. __show: function() {
  12646. $(this.__element).removeClass(CONF.classPrefix + "hide");
  12647. },
  12648. __initBasicEnv: function() {
  12649. if (this.__options.text && this.__allowShowTitle()) {
  12650. this.__element.setAttribute("title", this.__options.text);
  12651. }
  12652. if (this.__options.width) {
  12653. this.__element.style.width = this.__options.width + "px";
  12654. }
  12655. if (this.__options.height) {
  12656. this.__element.style.height = this.__options.height + "px";
  12657. }
  12658. if (this.widgetName) {
  12659. this.__element.setAttribute("rule", this.widgetName);
  12660. }
  12661. },
  12662. __id: function() {
  12663. return this.__options.id || generatorId();
  12664. }
  12665. });
  12666. // 为widget生成唯一id
  12667. function generatorId() {
  12668. return prefix + ++uid;
  12669. }
  12670. return Widget;
  12671. }
  12672. };
  12673. //dev-lib/exports.js
  12674. /**
  12675. * 模块暴露
  12676. */
  12677. _p[61] = {
  12678. value: function(require) {
  12679. _p.r(1);
  12680. _p.r(2);
  12681. }
  12682. };
  12683. var moduleMapping = {
  12684. "fui.export": 61
  12685. };
  12686. function use(name) {
  12687. _p.r([ moduleMapping[name] ]);
  12688. }
  12689. // 编译打包后的启动脚本
  12690. use( 'fui.export' );})();
  12691. /*!
  12692. * ====================================================
  12693. * kity - v2.0.0 - 2015-01-12
  12694. * https://github.com/fex-team/kity
  12695. * GitHub: https://github.com/fex-team/kity.git
  12696. * Copyright (c) 2015 Baidu FEX; Licensed BSD
  12697. * ====================================================
  12698. */
  12699. (function () {
  12700. var _p = {
  12701. r: function(index) {
  12702. if (_p[index].inited) {
  12703. return _p[index].value;
  12704. }
  12705. if (typeof _p[index].value === "function") {
  12706. var module = {
  12707. exports: {}
  12708. }, returnValue = _p[index].value(null, module.exports, module);
  12709. _p[index].inited = true;
  12710. _p[index].value = returnValue;
  12711. if (returnValue !== undefined) {
  12712. return returnValue;
  12713. } else {
  12714. for (var key in module.exports) {
  12715. if (module.exports.hasOwnProperty(key)) {
  12716. _p[index].inited = true;
  12717. _p[index].value = module.exports;
  12718. return module.exports;
  12719. }
  12720. }
  12721. }
  12722. } else {
  12723. _p[index].inited = true;
  12724. return _p[index].value;
  12725. }
  12726. }
  12727. };
  12728. //src/animate/animator.js
  12729. /**
  12730. * @fileOverview
  12731. *
  12732. * 提供基本的动画支持
  12733. */
  12734. _p[0] = {
  12735. value: function(require) {
  12736. function parseTime(str) {
  12737. var value = parseFloat(str, 10);
  12738. if (/ms/.test(str)) {
  12739. return value;
  12740. }
  12741. if (/s/.test(str)) {
  12742. return value * 1e3;
  12743. }
  12744. if (/min/.test(str)) {
  12745. return value * 60 * 1e3;
  12746. }
  12747. return value;
  12748. }
  12749. var Timeline = _p.r(8);
  12750. var easingTable = _p.r(1);
  12751. /**
  12752. * @class kity.Animator
  12753. * @catalog animate
  12754. * @description 表示一个动画启动器,可以作用于不同的对象进行动画
  12755. */
  12756. var Animator = _p.r(11).createClass("Animator", {
  12757. /**
  12758. * @constructor
  12759. * @for kity.Animator
  12760. * @catalog animate
  12761. *
  12762. * @grammar new kity.Animator(beginValue, finishValue, setter)
  12763. * @grammar new kity.Animator(option)
  12764. *
  12765. * @param {any} beginValue|opt.beginValue
  12766. * 动画的起始值,允许的类型有数字、数组、字面量、kity.Point、kity.Vector、kity.Box、kity.Matrix
  12767. *
  12768. * @param {any} finishValue|opt.beginValue
  12769. * 动画的结束值,类型应于起始值相同
  12770. *
  12771. * @param {Function} setter|opt.setter
  12772. * 值的使用函数,接受三个参数: function(target, value, timeline)
  12773. * target {object} 动画的目标
  12774. * value {any} 动画的当前值
  12775. * timeline {kity.Timeline} 动画当前的时间线对象
  12776. */
  12777. constructor: function(beginValue, finishValue, setter) {
  12778. if (arguments.length == 1) {
  12779. var opt = arguments[0];
  12780. this.beginValue = opt.beginValue;
  12781. this.finishValue = opt.finishValue;
  12782. this.setter = opt.setter;
  12783. } else {
  12784. this.beginValue = beginValue;
  12785. this.finishValue = finishValue;
  12786. this.setter = setter;
  12787. }
  12788. },
  12789. /**
  12790. * @method start()
  12791. * @for kity.Animator
  12792. * @description 使用当前的动画器启动在指定目标上启动动画
  12793. *
  12794. * @grammar start(target, duration, easing, delay, callback) => {kity.Timeline}
  12795. * @grammar start(target, option) => {kity.Timeline}
  12796. *
  12797. * @param {object} target
  12798. * 启动动画的目标
  12799. *
  12800. * @param {Number|String} duration|option.duration
  12801. * [Optional] 动画的持续时间,如 300、"300ms"、"1.5min"
  12802. *
  12803. * @param {String|Function} easing|option.easing
  12804. * [Optional] 动画使用的缓动函数,如 "ease"、"linear"、"swing"
  12805. *
  12806. * @param {Number|String} delay|option.delay
  12807. * [Optional] 动画的播放延迟时间
  12808. *
  12809. * @param {Function} callback|option.callback
  12810. * [Optional] 动画结束后的回调函数
  12811. *
  12812. * @example
  12813. *
  12814. * ```js
  12815. * var turnRed = new kity.Animator(
  12816. * new kity.Color('yellow'),
  12817. * new kity.Color('red'),
  12818. * function(target, value) {
  12819. * target.fill(value);
  12820. * });
  12821. *
  12822. * turnRed.start(rect, 300, 'ease', function() {
  12823. * console.log('I am red!');
  12824. * });
  12825. * ```
  12826. */
  12827. start: function(target, duration, easing, delay, callback) {
  12828. if (arguments.length === 2 && typeof duration == "object") {
  12829. easing = duration.easing;
  12830. delay = duration.delay;
  12831. callback = duration.callback;
  12832. duration = duration.duration;
  12833. }
  12834. if (arguments.length === 4 && typeof delay == "function") {
  12835. callback = delay;
  12836. delay = 0;
  12837. }
  12838. var timeline = this.create(target, duration, easing, callback);
  12839. delay = parseTime(delay);
  12840. if (delay > 0) {
  12841. setTimeout(function() {
  12842. timeline.play();
  12843. }, delay);
  12844. } else {
  12845. timeline.play();
  12846. }
  12847. return timeline;
  12848. },
  12849. /**
  12850. * @method create()
  12851. * @for kity.Animator
  12852. * @description 使用当前的动画器为指定目标创建时间线
  12853. *
  12854. * @grammar create(target, duration, easing, callback) => {kity.Timeline}
  12855. *
  12856. * @param {object} target 要创建的时间线的目标
  12857. * @param {Number|String} duration 要创建的时间线的长度,如 300、"5s"、"0.5min"
  12858. * @param {String|Function} easing 要创建的时间线的缓动函数,如 'ease'、'linear'、'swing'
  12859. * @param {Function} callback 时间线播放结束之后的回调函数
  12860. *
  12861. * @example
  12862. *
  12863. * ```js
  12864. * var expand = new kity.Animator({
  12865. * beginValue: function(target) {
  12866. * return target.getBox();
  12867. * },
  12868. * finishValue: function(target) {
  12869. * return target.getBox().expand(100, 100, 100, 100);
  12870. * },
  12871. * setter: function(target, value) {
  12872. * target.setBox(value)
  12873. * }
  12874. * });
  12875. *
  12876. * var timeline = expand.create(rect, 300);
  12877. * timeline.repeat(3).play();
  12878. * ```
  12879. */
  12880. create: function(target, duration, easing, callback) {
  12881. var timeline;
  12882. duration = duration && parseTime(duration) || Animator.DEFAULT_DURATION;
  12883. easing = easing || Animator.DEFAULT_EASING;
  12884. if (typeof easing == "string") {
  12885. easing = easingTable[easing];
  12886. }
  12887. timeline = new Timeline(this, target, duration, easing);
  12888. if (typeof callback == "function") {
  12889. timeline.on("finish", callback);
  12890. }
  12891. return timeline;
  12892. },
  12893. /**
  12894. * @method reverse()
  12895. * @for kity.Animator
  12896. * @grammar reverse() => {kity.Animator}
  12897. * @description 创建一个与当前动画器相反的动画器
  12898. *
  12899. * @example
  12900. *
  12901. * ```js
  12902. * var turnYellow = turnRed.reverse();
  12903. * ```
  12904. */
  12905. reverse: function() {
  12906. return new Animator(this.finishValue, this.beginValue, this.setter);
  12907. }
  12908. });
  12909. Animator.DEFAULT_DURATION = 300;
  12910. Animator.DEFAULT_EASING = "linear";
  12911. var Shape = _p.r(60);
  12912. _p.r(11).extendClass(Shape, {
  12913. /**
  12914. * @method animate()
  12915. * @for kity.Shape
  12916. * @description 在图形上播放使用指定的动画器播放动画,如果图形当前有动画正在播放,则会加入播放队列
  12917. *
  12918. * @grammar animate(animator, duration, easing, delay, callback)
  12919. *
  12920. * @param {object} animator 播放动画使用的动画器
  12921. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  12922. * @param {Number|String} delay 动画播放前的延时
  12923. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  12924. * @param {Function} callback 播放结束之后的回调函数
  12925. *
  12926. * @example
  12927. *
  12928. * ```js
  12929. * rect.animate(turnRed, 300); // turnRect 是一个动画器
  12930. * rect.animate(expand, 500); // turnRect 播放结束后播放 expand
  12931. * ```
  12932. */
  12933. animate: function(animator, duration, easing, delay, callback) {
  12934. var queue = this._KityAnimateQueue = this._KityAnimateQueue || [];
  12935. var timeline = animator.create(this, duration, easing, callback);
  12936. function dequeue() {
  12937. queue.shift();
  12938. if (queue.length) {
  12939. setTimeout(queue[0].t.play.bind(queue[0].t), queue[0].d);
  12940. }
  12941. }
  12942. timeline.on("finish", dequeue);
  12943. queue.push({
  12944. t: timeline,
  12945. d: delay
  12946. });
  12947. if (queue.length == 1) {
  12948. setTimeout(timeline.play.bind(timeline), delay);
  12949. }
  12950. return this;
  12951. },
  12952. /**
  12953. * @method timeline()
  12954. * @for kity.Shape
  12955. * @description 获得当前正在播放的动画的时间线
  12956. *
  12957. * @grammar timeline() => {kity.Timeline}
  12958. *
  12959. * @example
  12960. *
  12961. * ```js
  12962. * rect.timeline().repeat(2);
  12963. * ```
  12964. */
  12965. timeline: function() {
  12966. return this._KityAnimateQueue[0].t;
  12967. },
  12968. /**
  12969. * @method stop()
  12970. * @for kity.Shape
  12971. * @description 停止当前正在播放的动画
  12972. *
  12973. * @grammar stop() => {this}
  12974. *
  12975. * @example
  12976. *
  12977. * ```js
  12978. * rect.stop(); // 停止 rect 上的动画
  12979. * ```
  12980. */
  12981. stop: function() {
  12982. var queue = this._KityAnimateQueue;
  12983. if (queue) {
  12984. while (queue.length) {
  12985. queue.shift().t.stop();
  12986. }
  12987. }
  12988. return this;
  12989. }
  12990. });
  12991. return Animator;
  12992. }
  12993. };
  12994. //src/animate/easing.js
  12995. /**
  12996. * Kity Animate Easing modified from jQuery Easing
  12997. * Author: techird
  12998. * Changes:
  12999. * 1. make easing functions standalone
  13000. * 2. remove the 'x' parameter
  13001. */
  13002. /* ============================================================
  13003. * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
  13004. *
  13005. * Open source under the BSD License.
  13006. *
  13007. * Copyright © 2008 George McGinley Smith
  13008. * All rights reserved.
  13009. * https://raw.github.com/danro/jquery-easing/master/LICENSE
  13010. * ======================================================== */
  13011. _p[1] = {
  13012. value: function(require, exports, module) {
  13013. var easings = {
  13014. // t: current_time, b: begin_value, c: change_value, d: duration
  13015. linear: function(t, b, c, d) {
  13016. return c * (t / d) + b;
  13017. },
  13018. swing: function(t, b, c, d) {
  13019. return easings.easeOutQuad(t, b, c, d);
  13020. },
  13021. ease: function(t, b, c, d) {
  13022. return easings.easeInOutCubic(t, b, c, d);
  13023. },
  13024. easeInQuad: function(t, b, c, d) {
  13025. return c * (t /= d) * t + b;
  13026. },
  13027. easeOutQuad: function(t, b, c, d) {
  13028. return -c * (t /= d) * (t - 2) + b;
  13029. },
  13030. easeInOutQuad: function(t, b, c, d) {
  13031. if ((t /= d / 2) < 1) return c / 2 * t * t + b;
  13032. return -c / 2 * (--t * (t - 2) - 1) + b;
  13033. },
  13034. easeInCubic: function(t, b, c, d) {
  13035. return c * (t /= d) * t * t + b;
  13036. },
  13037. easeOutCubic: function(t, b, c, d) {
  13038. return c * ((t = t / d - 1) * t * t + 1) + b;
  13039. },
  13040. easeInOutCubic: function(t, b, c, d) {
  13041. if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
  13042. return c / 2 * ((t -= 2) * t * t + 2) + b;
  13043. },
  13044. easeInQuart: function(t, b, c, d) {
  13045. return c * (t /= d) * t * t * t + b;
  13046. },
  13047. easeOutQuart: function(t, b, c, d) {
  13048. return -c * ((t = t / d - 1) * t * t * t - 1) + b;
  13049. },
  13050. easeInOutQuart: function(t, b, c, d) {
  13051. if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
  13052. return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
  13053. },
  13054. easeInQuint: function(t, b, c, d) {
  13055. return c * (t /= d) * t * t * t * t + b;
  13056. },
  13057. easeOutQuint: function(t, b, c, d) {
  13058. return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
  13059. },
  13060. easeInOutQuint: function(t, b, c, d) {
  13061. if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
  13062. return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
  13063. },
  13064. easeInSine: function(t, b, c, d) {
  13065. return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
  13066. },
  13067. easeOutSine: function(t, b, c, d) {
  13068. return c * Math.sin(t / d * (Math.PI / 2)) + b;
  13069. },
  13070. easeInOutSine: function(t, b, c, d) {
  13071. return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
  13072. },
  13073. easeInExpo: function(t, b, c, d) {
  13074. return t === 0 ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
  13075. },
  13076. easeOutExpo: function(t, b, c, d) {
  13077. return t == d ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
  13078. },
  13079. easeInOutExpo: function(t, b, c, d) {
  13080. if (t === 0) return b;
  13081. if (t == d) return b + c;
  13082. if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
  13083. return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
  13084. },
  13085. easeInCirc: function(t, b, c, d) {
  13086. return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
  13087. },
  13088. easeOutCirc: function(t, b, c, d) {
  13089. return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
  13090. },
  13091. easeInOutCirc: function(t, b, c, d) {
  13092. if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
  13093. return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
  13094. },
  13095. easeInElastic: function(t, b, c, d) {
  13096. var s = 1.70158;
  13097. var p = 0;
  13098. var a = c;
  13099. if (t === 0) return b;
  13100. if ((t /= d) == 1) return b + c;
  13101. if (!p) p = d * .3;
  13102. if (a < Math.abs(c)) {
  13103. a = c;
  13104. s = p / 4;
  13105. } else s = p / (2 * Math.PI) * Math.asin(c / a);
  13106. return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
  13107. },
  13108. easeOutElastic: function(t, b, c, d) {
  13109. var s = 1.70158;
  13110. var p = 0;
  13111. var a = c;
  13112. if (t === 0) return b;
  13113. if ((t /= d) == 1) return b + c;
  13114. if (!p) p = d * .3;
  13115. if (a < Math.abs(c)) {
  13116. a = c;
  13117. s = p / 4;
  13118. } else s = p / (2 * Math.PI) * Math.asin(c / a);
  13119. return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
  13120. },
  13121. easeInOutElastic: function(t, b, c, d) {
  13122. var s = 1.70158;
  13123. var p = 0;
  13124. var a = c;
  13125. if (t === 0) return b;
  13126. if ((t /= d / 2) == 2) return b + c;
  13127. if (!p) p = d * (.3 * 1.5);
  13128. if (a < Math.abs(c)) {
  13129. a = c;
  13130. var s = p / 4;
  13131. } else var s = p / (2 * Math.PI) * Math.asin(c / a);
  13132. if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
  13133. return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
  13134. },
  13135. easeInBack: function(t, b, c, d, s) {
  13136. if (s == undefined) s = 1.70158;
  13137. return c * (t /= d) * t * ((s + 1) * t - s) + b;
  13138. },
  13139. easeOutBack: function(t, b, c, d, s) {
  13140. if (s == undefined) s = 1.70158;
  13141. return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
  13142. },
  13143. easeInOutBack: function(t, b, c, d, s) {
  13144. if (s == undefined) s = 1.70158;
  13145. if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= 1.525) + 1) * t - s)) + b;
  13146. return c / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b;
  13147. },
  13148. easeInBounce: function(t, b, c, d) {
  13149. return c - easings.easeOutBounce(d - t, 0, c, d) + b;
  13150. },
  13151. easeOutBounce: function(t, b, c, d) {
  13152. if ((t /= d) < 1 / 2.75) {
  13153. return c * (7.5625 * t * t) + b;
  13154. } else if (t < 2 / 2.75) {
  13155. return c * (7.5625 * (t -= 1.5 / 2.75) * t + .75) + b;
  13156. } else if (t < 2.5 / 2.75) {
  13157. return c * (7.5625 * (t -= 2.25 / 2.75) * t + .9375) + b;
  13158. } else {
  13159. return c * (7.5625 * (t -= 2.625 / 2.75) * t + .984375) + b;
  13160. }
  13161. },
  13162. easeInOutBounce: function(t, b, c, d) {
  13163. if (t < d / 2) return easings.easeInBounce(t * 2, 0, c, d) * .5 + b;
  13164. return easings.easeOutBounce(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
  13165. }
  13166. };
  13167. return easings;
  13168. }
  13169. };
  13170. /*
  13171. *
  13172. * TERMS OF USE - EASING EQUATIONS
  13173. *
  13174. * Open source under the BSD License.
  13175. *
  13176. * Copyright © 2001 Robert Penner
  13177. * All rights reserved.
  13178. *
  13179. * Redistribution and use in source and binary forms, with or without modification,
  13180. * are permitted provided that the following conditions are met:
  13181. *
  13182. * Redistributions of source code must retain the above copyright notice, this list of
  13183. * conditions and the following disclaimer.
  13184. * Redistributions in binary form must reproduce the above copyright notice, this list
  13185. * of conditions and the following disclaimer in the documentation and/or other materials
  13186. * provided with the distribution.
  13187. *
  13188. * Neither the name of the author nor the names of contributors may be used to endorse
  13189. * or promote products derived from this software without specific prior written permission.
  13190. *
  13191. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
  13192. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  13193. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13194. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  13195. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  13196. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  13197. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  13198. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  13199. * OF THE POSSIBILITY OF SUCH DAMAGE.
  13200. *
  13201. */
  13202. //src/animate/frame.js
  13203. /**
  13204. * @fileOverview
  13205. *
  13206. * 提供动画帧的基本支持
  13207. */
  13208. _p[2] = {
  13209. value: function(require, exports) {
  13210. // 原生动画帧方法 polyfill
  13211. var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function(fn) {
  13212. return setTimeout(fn, 1e3 / 60);
  13213. };
  13214. var cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame || window.clearTimeout;
  13215. // 上一个请求的原生动画帧 id
  13216. var frameRequestId;
  13217. // 等待执行的帧动作的集合,这些帧的方法将在下个原生动画帧同步执行
  13218. var pendingFrames = [];
  13219. /**
  13220. * 添加一个帧到等待集合中
  13221. *
  13222. * 如果添加的帧是序列的第一个,至少有一个帧需要被执行,则会请求一个原生动画帧来执行
  13223. */
  13224. function pushFrame(frame) {
  13225. if (pendingFrames.push(frame) === 1) {
  13226. frameRequestId = requestAnimationFrame(executePendingFrames);
  13227. }
  13228. }
  13229. /**
  13230. * 执行所有等待帧
  13231. */
  13232. function executePendingFrames() {
  13233. var frames = pendingFrames;
  13234. pendingFrames = [];
  13235. while (frames.length) {
  13236. executeFrame(frames.pop());
  13237. }
  13238. frameRequestId = 0;
  13239. }
  13240. /**
  13241. * @method kity.requestFrame
  13242. * @catalog animate
  13243. * @grammar kity.requestFrame(action) => {frame}
  13244. * @description 请求一个帧,执行指定的动作。动作回调提供一些有用的信息
  13245. *
  13246. * @param {Function} action
  13247. *
  13248. * 要执行的动作,该动作回调有一个参数 frame,其中:
  13249. *
  13250. * frame.time {Number}
  13251. * 动作执行时的时间戳(ms)
  13252. *
  13253. * frame.index {Number}
  13254. * 当前执行的帧的编号(首帧为 0)
  13255. *
  13256. * frame.dur {Number}
  13257. * 上一帧至当前帧经过的时间,单位 ms
  13258. *
  13259. * frame.elapsed {Number}
  13260. * 从首帧开始到当前帧经过的时间,单位 ms
  13261. *
  13262. * frame.action {Number}
  13263. * 指向当前的帧处理函数
  13264. *
  13265. * frame.next()
  13266. * 表示下一帧继续执行。如果不调用该方法,将不会执行下一帧。
  13267. *
  13268. * @example
  13269. *
  13270. * ```js
  13271. * kity.requestFrame(function(frame) {
  13272. * console.log('平均帧率:' + frame.elapsed / (frame.index + 1));
  13273. *
  13274. * // 更新或渲染动作
  13275. *
  13276. * frame.next(); //继续执行下一帧
  13277. * });
  13278. * ```
  13279. */
  13280. function requestFrame(action) {
  13281. var frame = initFrame(action);
  13282. pushFrame(frame);
  13283. return frame;
  13284. }
  13285. /**
  13286. * @method kity.releaseFrame
  13287. * @catalog animate
  13288. * @grammar kity.releaseFrame(frame)
  13289. * @description 释放一个已经请求过的帧,如果该帧在等待集合里,将移除,下个动画帧不会执行释放的帧
  13290. *
  13291. * @param {frame} frame 使用 kity.requestFrame() 返回的帧
  13292. *
  13293. * @example
  13294. *
  13295. * ```js
  13296. * var frame = kity.requestFrame(function() {....});
  13297. * kity.releaseFrame(frame);
  13298. * ```
  13299. */
  13300. function releaseFrame(frame) {
  13301. var index = pendingFrames.indexOf(frame);
  13302. if (~index) {
  13303. pendingFrames.splice(index, 1);
  13304. }
  13305. if (pendingFrames.length === 0) {
  13306. cancelAnimationFrame(frameRequestId);
  13307. }
  13308. }
  13309. /**
  13310. * 初始化一个帧,主要用于后续计算
  13311. */
  13312. function initFrame(action) {
  13313. var frame = {
  13314. index: 0,
  13315. time: +new Date(),
  13316. elapsed: 0,
  13317. action: action,
  13318. next: function() {
  13319. pushFrame(frame);
  13320. }
  13321. };
  13322. return frame;
  13323. }
  13324. /**
  13325. * 执行一个帧动作
  13326. */
  13327. function executeFrame(frame) {
  13328. // 当前帧时间错
  13329. var time = +new Date();
  13330. // 当上一帧到当前帧经过的时间
  13331. var dur = time - frame.time;
  13332. //
  13333. // http://stackoverflow.com/questions/13133434/requestanimationframe-detect-stop
  13334. // 浏览器最小化或切换标签,requestAnimationFrame 不会执行。
  13335. // 检测时间超过 200 ms(频率小于 5Hz ) 判定为计时器暂停,重置为一帧长度
  13336. //
  13337. if (dur > 200) {
  13338. dur = 1e3 / 60;
  13339. }
  13340. frame.dur = dur;
  13341. frame.elapsed += dur;
  13342. frame.time = time;
  13343. frame.action.call(null, frame);
  13344. frame.index++;
  13345. }
  13346. // 暴露
  13347. exports.requestFrame = requestFrame;
  13348. exports.releaseFrame = releaseFrame;
  13349. }
  13350. };
  13351. //src/animate/motionanimator.js
  13352. /**
  13353. * @fileOverview
  13354. *
  13355. * 路径动画器,可以让一个物体沿着某个轨迹运动
  13356. */
  13357. _p[3] = {
  13358. value: function(require) {
  13359. var Animator = _p.r(0);
  13360. var g = _p.r(34);
  13361. var Path = _p.r(46);
  13362. var Shape = _p.r(60);
  13363. /**
  13364. * @class kity.MotionAnimator
  13365. * @catalog animate
  13366. * @base kity.Animator
  13367. * @description 路径动画器,可以让一个物体沿着某个轨迹运动
  13368. *
  13369. * @example
  13370. *
  13371. * ```js
  13372. * var motionAnimator = new MotionAnimator('M0,0C100,0,100,0,100,100L200,200');
  13373. * motionAnimator.start(rect, 3000);
  13374. * ```
  13375. */
  13376. var MotionAnimator = _p.r(11).createClass("MotionAnimator", {
  13377. base: Animator,
  13378. /**
  13379. * @constructor
  13380. * @for kity.MotionAnimator
  13381. * @grammar new kity.MotionAnimator(path, doRotate)
  13382. * @param {kity.Path|String|PathSegment} path 运动的轨迹,或者是 kity.Path 对象
  13383. * @param {boolean} doRotate 是否让运动的目标沿着路径的切线方向旋转
  13384. */
  13385. constructor: function(path, doRotate) {
  13386. var me = this;
  13387. this.callBase({
  13388. beginValue: 0,
  13389. finishValue: 1,
  13390. setter: function(target, value) {
  13391. var path = me.motionPath instanceof Path ? me.motionPath.getPathData() : me.motionPath;
  13392. var point = g.pointAtPath(path, value);
  13393. target.setTranslate(point.x, point.y);
  13394. if (this.doRotate) target.setRotate(point.tan.getAngle());
  13395. }
  13396. });
  13397. /**
  13398. * @property doRotate
  13399. * @for kity.MotionAnimator
  13400. * @type {boolean}
  13401. * @description 是否让运动的目标沿着路径的切线方向旋转
  13402. *
  13403. * @example
  13404. *
  13405. * ```js
  13406. * motionAnimator.doRotate = true; // 目标沿着切线方向旋转
  13407. * ```
  13408. */
  13409. this.doRotate = doRotate;
  13410. /**
  13411. * @property motionPath
  13412. * @for kity.MotionAnimator
  13413. * @type {kity.Path|String|PathSegment}
  13414. * @description 运动沿着的路径,可以在动画过程中更新
  13415. */
  13416. this.motionPath = path;
  13417. }
  13418. });
  13419. _p.r(11).extendClass(Shape, {
  13420. /**
  13421. * @method motion()
  13422. * @catalog animate
  13423. * @for kity.Shape
  13424. * @description 让图形沿着指定的路径运动
  13425. *
  13426. * @grammar motion(path, duration, easing, delay, callback) => this
  13427. *
  13428. * @param {kity.Path|String|PathSegment} path 运动的轨迹,或者是 kity.Path 对象
  13429. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  13430. * @param {Number|String} delay 动画播放前的延时
  13431. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  13432. * @param {Function} callback 播放结束之后的回调函数
  13433. */
  13434. motion: function(path, duration, easing, delay, callback) {
  13435. return this.animate(new MotionAnimator(path), duration, easing, delay, callback);
  13436. }
  13437. });
  13438. return MotionAnimator;
  13439. }
  13440. };
  13441. //src/animate/opacityanimator.js
  13442. /**
  13443. * @fileOverview
  13444. *
  13445. * 透明度动画器,让图形动画过度到指定的透明度。
  13446. */
  13447. _p[4] = {
  13448. value: function(require) {
  13449. var Animator = _p.r(0);
  13450. /**
  13451. * @class kity.OpacityAnimator
  13452. * @catalog animate
  13453. * @base kity.Animator
  13454. * @description 透明度动画器,让图形动画过度到指定的透明度
  13455. */
  13456. var OpacityAnimator = _p.r(11).createClass("OpacityAnimator", {
  13457. base: Animator,
  13458. /**
  13459. * @constructor
  13460. * @for kity.OpacityAnimator
  13461. * @grammar new kity.OpacityAnimator(opacity)
  13462. *
  13463. * @param {Number} opacity 目标透明度,取值范围 0 - 1
  13464. */
  13465. constructor: function(opacity) {
  13466. this.callBase({
  13467. beginValue: function(target) {
  13468. return target.getOpacity();
  13469. },
  13470. finishValue: opacity,
  13471. setter: function(target, value) {
  13472. target.setOpacity(value);
  13473. }
  13474. });
  13475. }
  13476. });
  13477. var Shape = _p.r(60);
  13478. _p.r(11).extendClass(Shape, {
  13479. /**
  13480. * @method fxOpacity()
  13481. * @catalog animate
  13482. * @for kity.Shape
  13483. * @description 让图形的透明度以动画的形式过渡到指定的值
  13484. *
  13485. * @grammar fxOpacity(opacity, duration, easing, delay, callback) => {this}
  13486. *
  13487. * @param {Number} opacity 动画的目标透明度
  13488. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  13489. * @param {Number|String} delay 动画播放前的延时
  13490. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  13491. * @param {Function} callback 播放结束之后的回调函数
  13492. */
  13493. fxOpacity: function(opacity, duration, easing, delay, callback) {
  13494. return this.animate(new OpacityAnimator(opacity), duration, easing, delay, callback);
  13495. },
  13496. /**
  13497. * @method fadeTo()
  13498. * @catalog animate
  13499. * @for kity.Shape
  13500. * @description 让图形的透明度以动画的形式过渡到指定的值
  13501. *
  13502. * @grammar fadeTo(opacity, duration, easing, delay, callback) => {this}
  13503. *
  13504. * @param {Number} opacity 动画的目标透明度
  13505. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  13506. * @param {Number|String} delay 动画播放前的延时
  13507. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  13508. * @param {Function} callback 播放结束之后的回调函数
  13509. */
  13510. fadeTo: function() {
  13511. return this.fxOpacity.apply(this, arguments);
  13512. },
  13513. /**
  13514. * @method fadeIn()
  13515. * @catalog animate
  13516. * @for kity.Shape
  13517. * @description 让图形淡入
  13518. *
  13519. * @grammar fadeIn(duration, easing, delay, callback) => {this}
  13520. *
  13521. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  13522. * @param {Number|String} delay 动画播放前的延时
  13523. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  13524. * @param {Function} callback 播放结束之后的回调函数
  13525. */
  13526. fadeIn: function() {
  13527. return this.fxOpacity.apply(this, [ 1 ].concat([].slice.call(arguments)));
  13528. },
  13529. /**
  13530. * @method fadeOut()
  13531. * @catalog animate
  13532. * @for kity.Shape
  13533. * @description 让图形淡出
  13534. *
  13535. * @grammar fadeIn(duration, easing, delay, callback) => {this}
  13536. *
  13537. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  13538. * @param {Number|String} delay 动画播放前的延时
  13539. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  13540. * @param {Function} callback 播放结束之后的回调函数
  13541. */
  13542. fadeOut: function() {
  13543. return this.fxOpacity.apply(this, [ 0 ].concat([].slice.call(arguments)));
  13544. }
  13545. });
  13546. return OpacityAnimator;
  13547. }
  13548. };
  13549. //src/animate/pathanimator.js
  13550. /**
  13551. * @fileOverview
  13552. *
  13553. * 路径补间动画器,让图形从一个形状变为另一个形状
  13554. */
  13555. _p[5] = {
  13556. value: function(require) {
  13557. var Animator = _p.r(0);
  13558. var g = _p.r(34);
  13559. /**
  13560. * @catalog animate
  13561. *
  13562. * @class kity.PathAnimator
  13563. * @base kity.Animator
  13564. * @description 路径补间动画器,让图形从一个形状变为另一个形状
  13565. *
  13566. * @example
  13567. *
  13568. * ```js
  13569. * var path = new kity.Path('M0,0L0,100');
  13570. * var pa = new kity.PathAnimator('M0,0C100,0,100,0,100,100');
  13571. * pa.start(path, 300);
  13572. * ```
  13573. */
  13574. var PathAnimator = _p.r(11).createClass("OpacityAnimator", {
  13575. base: Animator,
  13576. /**
  13577. * @constructor
  13578. * @for kity.PathAnimator
  13579. *
  13580. * @grammar new kity.Path.Animator(path)
  13581. *
  13582. * @param {String|PathSegment} path 目标形状的路径数据
  13583. *
  13584. */
  13585. constructor: function(path) {
  13586. this.callBase({
  13587. beginValue: function(target) {
  13588. this.beginPath = target.getPathData();
  13589. return 0;
  13590. },
  13591. finishValue: 1,
  13592. setter: function(target, value) {
  13593. target.setPathData(g.pathTween(this.beginPath, path, value));
  13594. }
  13595. });
  13596. }
  13597. });
  13598. var Path = _p.r(46);
  13599. _p.r(11).extendClass(Path, {
  13600. /**
  13601. * @catalog animate
  13602. *
  13603. * @method fxPath()
  13604. * @for kity.Shape
  13605. * @description 以动画的形式把路径变换为新路径
  13606. *
  13607. * @grammar fxPath(path, duration, easing, delay, callback) => {this}
  13608. *
  13609. * @param {String|PathSegment} path 要变换新路径
  13610. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  13611. * @param {Number|String} delay 动画播放前的延时
  13612. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  13613. * @param {Function} callback 播放结束之后的回调函数
  13614. */
  13615. fxPath: function(path, duration, easing, delay, callback) {
  13616. return this.animate(new PathAnimator(path), duration, easing, delay, callback);
  13617. }
  13618. });
  13619. return PathAnimator;
  13620. }
  13621. };
  13622. //src/animate/rotateanimator.js
  13623. /**
  13624. * @fileOverview
  13625. *
  13626. * 提供支持目标旋转的动画器
  13627. */
  13628. _p[6] = {
  13629. value: function(require) {
  13630. var Animator = _p.r(0);
  13631. /**
  13632. * @class kity.RotateAnimator
  13633. * @base Animator
  13634. * @description 提供支持目标旋转的动画器
  13635. */
  13636. var RotateAnimator = _p.r(11).createClass("RotateAnimator", {
  13637. base: Animator,
  13638. /**
  13639. * @constructor
  13640. * @for kity.RotateAnimator
  13641. *
  13642. * @grammar new kity.RotateAnimator(deg, ax, ay)
  13643. *
  13644. * @param {Number} deg 要旋转的角度
  13645. */
  13646. constructor: function(deg) {
  13647. this.callBase({
  13648. beginValue: 0,
  13649. finishValue: deg,
  13650. setter: function(target, value, timeline) {
  13651. var delta = timeline.getDelta();
  13652. target.rotate(delta, ax, ay);
  13653. }
  13654. });
  13655. }
  13656. });
  13657. var Shape = _p.r(60);
  13658. _p.r(11).extendClass(Shape, {
  13659. /**
  13660. * @method fxRotate()
  13661. * @for kity.Shape
  13662. * @description 让目标以动画旋转指定的角度
  13663. *
  13664. * @grammar fxRotate(deg, duration, easing, delay) => {this}
  13665. *
  13666. * @param {Number} deg 要旋转的角度
  13667. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  13668. * @param {Number|String} delay 动画播放前的延时
  13669. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  13670. * @param {Function} callback 播放结束之后的回调函数
  13671. */
  13672. fxRotate: function(deg, duration, easing, delay, callback) {
  13673. return this.animate(new RotateAnimator(deg), duration, easing, delay, callback);
  13674. }
  13675. });
  13676. return RotateAnimator;
  13677. }
  13678. };
  13679. //src/animate/scaleanimator.js
  13680. /**
  13681. * @fileOverview
  13682. *
  13683. * 提供支持目标缩放的动画器
  13684. */
  13685. _p[7] = {
  13686. value: function(require) {
  13687. var Animator = _p.r(0);
  13688. /**
  13689. * @class kity.ScaleAnimator
  13690. * @base kity.Animator
  13691. * @description 提供支持目标缩放的动画器
  13692. */
  13693. var ScaleAnimator = _p.r(11).createClass("ScaleAnimator", {
  13694. base: Animator,
  13695. /**
  13696. * @constructor
  13697. * @for kity.ScaleAnimator
  13698. *
  13699. * @grammar new kity.ScaleAnimator(sx, sy)
  13700. * @param {Number} sx x 轴的缩放比例
  13701. * @param {Number} sy y 轴的缩放比例
  13702. */
  13703. constructor: function(sx, sy) {
  13704. this.callBase({
  13705. beginValue: 0,
  13706. finishValue: 1,
  13707. setter: function(target, value, timeline) {
  13708. var delta = timeline.getDelta();
  13709. var kx = Math.pow(sx, delta);
  13710. var ky = Math.pow(sy, delta);
  13711. target.scale(ky, kx);
  13712. }
  13713. });
  13714. }
  13715. });
  13716. var Shape = _p.r(60);
  13717. _p.r(11).extendClass(Shape, {
  13718. /**
  13719. * @method fxScale
  13720. * @for kity.Shape
  13721. * @description 动画缩放当前的图形
  13722. *
  13723. * @grammar fxScale(sx, sy, duration, easing, delay, callback) => {this}
  13724. *
  13725. * @param {Number} sx x 轴的缩放比例
  13726. * @param {Number} sy y 轴的缩放比例
  13727. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  13728. * @param {Number|String} delay 动画播放前的延时
  13729. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  13730. * @param {Function} callback 播放结束之后的回调函数
  13731. */
  13732. fxScale: function(sx, sy, duration, easing, delay, callback) {
  13733. return this.animate(new ScaleAnimator(sx, sy), duration, easing, delay, callback);
  13734. }
  13735. });
  13736. return ScaleAnimator;
  13737. }
  13738. };
  13739. //src/animate/timeline.js
  13740. /**
  13741. * @fileOverview
  13742. *
  13743. * 动画时间线的实现
  13744. */
  13745. _p[8] = {
  13746. value: function(require) {
  13747. var EventHandler = _p.r(33);
  13748. var utils = _p.r(12);
  13749. var frame = _p.r(2);
  13750. function getPercentValue(b, f, p) {
  13751. return utils.paralle(b, f, function(b, f) {
  13752. return b + (f - b) * p;
  13753. });
  13754. }
  13755. function getDelta(v1, v2) {
  13756. return utils.paralle(v1, v2, function(v1, v2) {
  13757. return v2 - v1;
  13758. });
  13759. }
  13760. function TimelineEvent(timeline, type, param) {
  13761. this.timeline = timeline;
  13762. this.target = timeline.target;
  13763. this.type = type;
  13764. for (var name in param) {
  13765. if (param.hasOwnProperty(name)) {
  13766. this[name] = param[name];
  13767. }
  13768. }
  13769. }
  13770. /**
  13771. * @class kity.Timeline
  13772. * @catalog animate
  13773. * @mixins EventHandler
  13774. * @description 动画时间线
  13775. */
  13776. var Timeline = _p.r(11).createClass("Timeline", {
  13777. mixins: [ EventHandler ],
  13778. /**
  13779. * @constructor
  13780. * @for kity.Timeline
  13781. * @private
  13782. * @description 时间线应该由动画器进行构造,不应手动创建
  13783. *
  13784. */
  13785. constructor: function(animator, target, duration, easing) {
  13786. this.callMixin();
  13787. this.target = target;
  13788. this.time = 0;
  13789. this.duration = duration;
  13790. this.easing = easing;
  13791. this.animator = animator;
  13792. this.beginValue = animator.beginValue;
  13793. this.finishValue = animator.finishValue;
  13794. this.setter = animator.setter;
  13795. this.status = "ready";
  13796. },
  13797. /**
  13798. * @private
  13799. *
  13800. * 让时间线进入下一帧
  13801. */
  13802. nextFrame: function(frame) {
  13803. if (this.status != "playing") {
  13804. return;
  13805. }
  13806. this.time += frame.dur;
  13807. this.setValue(this.getValue());
  13808. if (this.time >= this.duration) {
  13809. this.timeUp();
  13810. }
  13811. frame.next();
  13812. },
  13813. /**
  13814. * @method getPlayTime()
  13815. * @for kity.Timeline
  13816. * @grammar getPlayTime() => {Number}
  13817. * @description 获得当前播放的时间,取值区间为 [0, duration]
  13818. */
  13819. getPlayTime: function() {
  13820. return this.rollbacking ? this.duration - this.time : this.time;
  13821. },
  13822. /**
  13823. * @method getTimeProportion()
  13824. * @for kity.Timeline
  13825. * @grammar getTimeProportion() => {Number}
  13826. * @description 获得当前播放时间的比例,取值区间为 [0, 1]
  13827. */
  13828. getTimeProportion: function() {
  13829. return this.getPlayTime() / this.duration;
  13830. },
  13831. /**
  13832. * @method getValueProportion()
  13833. * @for kity.Timeline
  13834. * @grammar getValueProportion() => {Number}
  13835. * @description 获得当前播放时间对应值的比例,取值区间为 [0, 1];该值实际上是时间比例值经过缓动函数计算之后的值。
  13836. */
  13837. getValueProportion: function() {
  13838. return this.easing(this.getPlayTime(), 0, 1, this.duration);
  13839. },
  13840. /**
  13841. * @method getValue()
  13842. * @for kity.Timeline
  13843. * @grammar getValue() => {any}
  13844. * @description 返回当前播放时间对应的值。
  13845. */
  13846. getValue: function() {
  13847. var b = this.beginValue;
  13848. var f = this.finishValue;
  13849. var p = this.getValueProportion();
  13850. return getPercentValue(b, f, p);
  13851. },
  13852. /**
  13853. * @private
  13854. *
  13855. * 把值通过动画器的 setter 设置到目标上
  13856. */
  13857. setValue: function(value) {
  13858. this.lastValue = this.currentValue;
  13859. this.currentValue = value;
  13860. this.setter.call(this.target, this.target, value, this);
  13861. },
  13862. /**
  13863. * @method getDelta()
  13864. * @for kity.Timeline
  13865. * @grammar getDelta() => {any}
  13866. * @description 返回当前值和上一帧的值的差值
  13867. */
  13868. getDelta: function() {
  13869. this.lastValue = this.lastValue === undefined ? this.beginValue : this.lastValue;
  13870. return getDelta(this.lastValue, this.currentValue);
  13871. },
  13872. /**
  13873. * @method play()
  13874. * @for kity.Timeline
  13875. * @grammar play() => {this}
  13876. * @description 让时间线播放,如果时间线还没开始,或者已停止、已结束,则重头播放;如果是已暂停,从暂停的位置继续播放
  13877. */
  13878. play: function() {
  13879. var lastStatus = this.status;
  13880. this.status = "playing";
  13881. switch (lastStatus) {
  13882. case "ready":
  13883. if (utils.isFunction(this.beginValue)) {
  13884. this.beginValue = this.beginValue.call(this.target, this.target);
  13885. }
  13886. if (utils.isFunction(this.finishValue)) {
  13887. this.finishValue = this.finishValue.call(this.target, this.target);
  13888. }
  13889. this.time = 0;
  13890. this.setValue(this.beginValue);
  13891. this.frame = frame.requestFrame(this.nextFrame.bind(this));
  13892. break;
  13893. case "finished":
  13894. case "stoped":
  13895. this.time = 0;
  13896. this.frame = frame.requestFrame(this.nextFrame.bind(this));
  13897. break;
  13898. case "paused":
  13899. this.frame.next();
  13900. }
  13901. /**
  13902. * @event play
  13903. * @for kity.Timeline
  13904. * @description 在时间线播放后触发
  13905. *
  13906. * @param {String} event.lastStatus
  13907. * 表示播放前的上一个状态,可能取值为 'ready'、'finished'、'stoped'、'paused'
  13908. */
  13909. this.fire("play", new TimelineEvent(this, "play", {
  13910. lastStatus: lastStatus
  13911. }));
  13912. return this;
  13913. },
  13914. /**
  13915. * @method pause()
  13916. * @for kity.Timeline
  13917. * @description 暂停当前的时间线
  13918. *
  13919. * @grammar pause() => {this}
  13920. */
  13921. pause: function() {
  13922. this.status = "paused";
  13923. /**
  13924. * @event pause
  13925. * @for kity.Timeline
  13926. * @description 暂停事件,在时间线暂停时触发
  13927. */
  13928. this.fire("pause", new TimelineEvent(this, "pause"));
  13929. frame.releaseFrame(this.frame);
  13930. return this;
  13931. },
  13932. /**
  13933. * @method stop()
  13934. * @for kity.Timeline
  13935. * @description 停止当前时间线
  13936. *
  13937. * @grammar stop() => {this}
  13938. */
  13939. stop: function() {
  13940. this.status = "stoped";
  13941. this.setValue(this.finishValue);
  13942. this.rollbacking = false;
  13943. /**
  13944. * @event stop
  13945. * @for kity.Timeline
  13946. * @description 停止时间,在时间线停止时触发
  13947. */
  13948. this.fire("stop", new TimelineEvent(this, "stop"));
  13949. frame.releaseFrame(this.frame);
  13950. return this;
  13951. },
  13952. /**
  13953. * @private
  13954. *
  13955. * 播放结束之后的处理
  13956. */
  13957. timeUp: function() {
  13958. if (this.repeatOption) {
  13959. this.time = 0;
  13960. if (this.rollback) {
  13961. if (this.rollbacking) {
  13962. this.decreaseRepeat();
  13963. this.rollbacking = false;
  13964. } else {
  13965. this.rollbacking = true;
  13966. /**
  13967. * @event rollback
  13968. * @for kity.Timeline
  13969. * @description 回滚事件,在时间线回滚播放开始的时候触发
  13970. */
  13971. this.fire("rollback", new TimelineEvent(this, "rollback"));
  13972. }
  13973. } else {
  13974. this.decreaseRepeat();
  13975. }
  13976. if (!this.repeatOption) {
  13977. this.finish();
  13978. } else {
  13979. /**
  13980. * @event repeat
  13981. * @for kity.Timeline
  13982. * @description 循环事件,在时间线循环播放开始的时候触发
  13983. */
  13984. this.fire("repeat", new TimelineEvent(this, "repeat"));
  13985. }
  13986. } else {
  13987. this.finish();
  13988. }
  13989. },
  13990. /**
  13991. * @private
  13992. *
  13993. * 决定播放结束的处理
  13994. */
  13995. finish: function() {
  13996. this.setValue(this.finishValue);
  13997. this.status = "finished";
  13998. /**
  13999. * @event finish
  14000. * @for kity.Timeline
  14001. * @description 结束事件,在时间线播放结束后触发(包括重复和回滚都结束)
  14002. */
  14003. this.fire("finish", new TimelineEvent(this, "finish"));
  14004. frame.releaseFrame(this.frame);
  14005. },
  14006. /**
  14007. * @private
  14008. *
  14009. * 循环次数递减
  14010. */
  14011. decreaseRepeat: function() {
  14012. if (this.repeatOption !== true) {
  14013. this.repeatOption--;
  14014. }
  14015. },
  14016. /**
  14017. * @method repeat()
  14018. * @for kity.Timeline
  14019. * @description 设置时间线的重复选项
  14020. *
  14021. * @grammar repeat(repeat, rollback) => {this}
  14022. *
  14023. * @param {Number|Boolean} repeat
  14024. * 是否重复播放,设置为 true 无限循环播放,设置数值则循环指定的次数
  14025. * @param {Boolean} rollback
  14026. * 指示是否要回滚播放。
  14027. * 如果设置为真,一次事件到 duration 则一个来回算一次循环次数,否则播放完成一次算一次循环次数
  14028. *
  14029. */
  14030. repeat: function(repeat, rollback) {
  14031. this.repeatOption = repeat;
  14032. this.rollback = rollback;
  14033. return this;
  14034. }
  14035. });
  14036. Timeline.requestFrame = frame.requestFrame;
  14037. Timeline.releaseFrame = frame.releaseFrame;
  14038. return Timeline;
  14039. }
  14040. };
  14041. //src/animate/translateanimator.js
  14042. /**
  14043. * @fileOverview
  14044. *
  14045. * 提供让图形移动的动画器
  14046. */
  14047. _p[9] = {
  14048. value: function(require) {
  14049. var Animator = _p.r(0);
  14050. /**
  14051. * @class kity.TranslateAnimator
  14052. * @base kity.Animator
  14053. * @description 提供让图形移动的动画器
  14054. */
  14055. var TranslateAnimator = _p.r(11).createClass("TranslateAnimator", {
  14056. base: Animator,
  14057. /**
  14058. * @constructor
  14059. * @for kity.TranslateAnimator
  14060. * @grammar new kity.TranslateAnimator(x, y)
  14061. * @param {Number} x x 方向上需要移动的距离
  14062. * @param {Number} y y 方向上需要移动的距离
  14063. */
  14064. constructor: function(x, y) {
  14065. this.callBase({
  14066. x: 0,
  14067. y: 0
  14068. }, {
  14069. x: x,
  14070. y: y
  14071. }, function(target, value, timeline) {
  14072. var delta = timeline.getDelta();
  14073. target.translate(delta.x, delta.y);
  14074. });
  14075. }
  14076. });
  14077. var Shape = _p.r(60);
  14078. _p.r(11).extendClass(Shape, {
  14079. /**
  14080. * @method fxTranslate()
  14081. * @for kity.Shape
  14082. * @description 让目标以动画平移指定的距离
  14083. *
  14084. * @grammar fxTranslate(x, y, duration, easing, delay, callback) => {this}
  14085. *
  14086. * @param {Number} x x 方向上需要移动的距离
  14087. * @param {Number} y y 方向上需要移动的距离
  14088. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  14089. * @param {Number|String} delay 动画播放前的延时
  14090. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  14091. * @param {Function} callback 播放结束之后的回调函数
  14092. */
  14093. fxTranslate: function(x, y, duration, easing, delay, callback) {
  14094. return this.animate(new TranslateAnimator(x, y), duration, easing, delay, callback);
  14095. }
  14096. });
  14097. return TranslateAnimator;
  14098. }
  14099. };
  14100. //src/core/browser.js
  14101. /**
  14102. * @fileOverview
  14103. *
  14104. * 提供浏览器判断的一些字段
  14105. */
  14106. _p[10] = {
  14107. value: function() {
  14108. /**
  14109. * @class kity.Browser
  14110. * @catalog core
  14111. * @static
  14112. * @description 提供浏览器信息
  14113. */
  14114. var browser = function() {
  14115. var agent = navigator.userAgent.toLowerCase(), opera = window.opera, browser;
  14116. // 浏览器对象
  14117. browser = {
  14118. /**
  14119. * @property ie
  14120. * @for kity.Browser
  14121. * @description 判断是否为 IE 浏览器
  14122. * @type {boolean}
  14123. */
  14124. ie: /(msie\s|trident.*rv:)([\w.]+)/.test(agent),
  14125. /**
  14126. * @property opera
  14127. * @for kity.Browser
  14128. * @description 判断是否为 Opera 浏览器
  14129. * @type {boolean}
  14130. */
  14131. opera: !!opera && opera.version,
  14132. /**
  14133. * @property webkit
  14134. * @for kity.Browser
  14135. * @description 判断是否为 Webkit 内核的浏览器
  14136. * @type {boolean}
  14137. */
  14138. webkit: agent.indexOf(" applewebkit/") > -1,
  14139. /**
  14140. * @property mac
  14141. * @for kity.Browser
  14142. * @description 判断是否为 Mac 下的浏览器
  14143. * @type {boolean}
  14144. */
  14145. mac: agent.indexOf("macintosh") > -1
  14146. };
  14147. browser.gecko = navigator.product == "Gecko" && !browser.webkit && !browser.opera && !browser.ie;
  14148. var version = 0;
  14149. // Internet Explorer 6.0+
  14150. if (browser.ie) {
  14151. version = (agent.match(/(msie\s|trident.*rv:)([\w.]+)/)[2] || 0) * 1;
  14152. browser.ie11Compat = document.documentMode == 11;
  14153. browser.ie9Compat = document.documentMode == 9;
  14154. }
  14155. // Gecko.
  14156. if (browser.gecko) {
  14157. var geckoRelease = agent.match(/rv:([\d\.]+)/);
  14158. if (geckoRelease) {
  14159. geckoRelease = geckoRelease[1].split(".");
  14160. version = geckoRelease[0] * 1e4 + (geckoRelease[1] || 0) * 100 + (geckoRelease[2] || 0) * 1;
  14161. }
  14162. }
  14163. if (/chrome\/(\d+\.\d)/i.test(agent)) {
  14164. /**
  14165. * @property chrome
  14166. * @for kity.Browser
  14167. * @description 判断是否为 Chrome 浏览器
  14168. * @type {boolean}
  14169. */
  14170. browser.chrome = +RegExp["$1"];
  14171. }
  14172. if (/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(agent) && !/chrome/i.test(agent)) {
  14173. browser.safari = +(RegExp["$1"] || RegExp["$2"]);
  14174. }
  14175. // Opera 9.50+
  14176. if (browser.opera) version = parseFloat(opera.version());
  14177. // WebKit 522+ (Safari 3+)
  14178. if (browser.webkit) version = parseFloat(agent.match(/ applewebkit\/(\d+)/)[1]);
  14179. /**
  14180. * @property version
  14181. * @for kity.Browser
  14182. * @description 获取当前浏览器的版本
  14183. * @type {Number}
  14184. */
  14185. browser.version = version;
  14186. browser.isCompatible = !browser.mobile && (browser.ie && version >= 6 || browser.gecko && version >= 10801 || browser.opera && version >= 9.5 || browser.air && version >= 1 || browser.webkit && version >= 522 || false);
  14187. return browser;
  14188. }();
  14189. return browser;
  14190. }
  14191. };
  14192. //src/core/class.js
  14193. /**
  14194. * @fileOverview
  14195. *
  14196. * 提供 Kity 的 OOP 支持
  14197. */
  14198. _p[11] = {
  14199. value: function(require, exports) {
  14200. /**
  14201. * @class kity.Class
  14202. * @catalog core
  14203. * @description 所有 kity 类的基类
  14204. * @abstract
  14205. */
  14206. function Class() {}
  14207. exports.Class = Class;
  14208. Class.__KityClassName = "Class";
  14209. /**
  14210. * @method base()
  14211. * @for kity.Class
  14212. * @protected
  14213. * @grammar base(name, args...) => {any}
  14214. * @description 调用父类指定名称的函数
  14215. * @param {string} name 函数的名称
  14216. * @param {parameter} args... 传递给父类函数的参数
  14217. *
  14218. * @example
  14219. *
  14220. * ```js
  14221. * var Person = kity.createClass('Person', {
  14222. * toString: function() {
  14223. * return 'I am a person';
  14224. * }
  14225. * });
  14226. *
  14227. * var Male = kity.createClass('Male', {
  14228. * base: Person,
  14229. *
  14230. * toString: function() {
  14231. * return 'I am a man';
  14232. * },
  14233. *
  14234. * speak: function() {
  14235. * return this.base('toString') + ',' + this.toString();
  14236. * }
  14237. * })
  14238. * ```
  14239. */
  14240. Class.prototype.base = function(name) {
  14241. var caller = arguments.callee.caller;
  14242. var method = caller.__KityMethodClass.__KityBaseClass.prototype[name];
  14243. return method.apply(this, Array.prototype.slice.call(arguments, 1));
  14244. };
  14245. /**
  14246. * @method callBase()
  14247. * @for kity.Class
  14248. * @protected
  14249. * @grammar callBase(args...) => {any}
  14250. * @description 调用父类同名函数
  14251. * @param {parameter} args... 传递到父类同名函数的参数
  14252. *
  14253. * @example
  14254. *
  14255. * ```js
  14256. * var Animal = kity.createClass('Animal', {
  14257. * constructor: function(name) {
  14258. * this.name = name;
  14259. * },
  14260. * toString: function() {
  14261. * return 'I am an animal name ' + this.name;
  14262. * }
  14263. * });
  14264. *
  14265. * var Dog = kity.createClass('Dog', {
  14266. * constructor: function(name) {
  14267. * this.callBase(name);
  14268. * },
  14269. * toString: function() {
  14270. * return this.callBase() + ', a dog';
  14271. * }
  14272. * });
  14273. *
  14274. * var dog = new Dog('Dummy');
  14275. * console.log(dog.toString()); // "I am an animal name Dummy, a dog";
  14276. * ```
  14277. */
  14278. Class.prototype.callBase = function() {
  14279. var caller = arguments.callee.caller;
  14280. var method = caller.__KityMethodClass.__KityBaseClass.prototype[caller.__KityMethodName];
  14281. return method.apply(this, arguments);
  14282. };
  14283. Class.prototype.mixin = function(name) {
  14284. var caller = arguments.callee.caller;
  14285. var mixins = caller.__KityMethodClass.__KityMixins;
  14286. if (!mixins) {
  14287. return this;
  14288. }
  14289. var method = mixins[name];
  14290. return method.apply(this, Array.prototype.slice.call(arguments, 1));
  14291. };
  14292. Class.prototype.callMixin = function() {
  14293. var caller = arguments.callee.caller;
  14294. var methodName = caller.__KityMethodName;
  14295. var mixins = caller.__KityMethodClass.__KityMixins;
  14296. if (!mixins) {
  14297. return this;
  14298. }
  14299. var method = mixins[methodName];
  14300. if (methodName == "constructor") {
  14301. for (var i = 0, l = method.length; i < l; i++) {
  14302. method[i].call(this);
  14303. }
  14304. return this;
  14305. } else {
  14306. return method.apply(this, arguments);
  14307. }
  14308. };
  14309. /**
  14310. * @method pipe()
  14311. * @for kity.Class
  14312. * @grammar pipe() => {this}
  14313. * @description 以当前对象为上线文以及管道函数的第一个参数,执行一个管道函数
  14314. * @param {Function} fn 进行管道操作的函数
  14315. *
  14316. * @example
  14317. *
  14318. * ```js
  14319. * var rect = new kity.Rect().pipe(function() {
  14320. * this.setWidth(500);
  14321. * this.setHeight(300);
  14322. * });
  14323. * ```
  14324. */
  14325. Class.prototype.pipe = function(fn) {
  14326. if (typeof fn == "function") {
  14327. fn.call(this, this);
  14328. }
  14329. return this;
  14330. };
  14331. /**
  14332. * @method getType()
  14333. * @for kity.Class
  14334. * @grammar getType() => {string}
  14335. * @description 获得对象的类型
  14336. *
  14337. * @example
  14338. *
  14339. * ```js
  14340. * var rect = new kity.Rect();
  14341. * var circle = new kity.Circle();
  14342. *
  14343. * console.log(rect.getType()); // "Rect"
  14344. * console.log(rect.getType()); // "Circle"
  14345. * ```
  14346. */
  14347. Class.prototype.getType = function() {
  14348. return this.__KityClassName;
  14349. };
  14350. /**
  14351. * @method getClass()
  14352. * @for kity.Class
  14353. * @grammar getClass() => {Class}
  14354. * @description 获得对象的类
  14355. *
  14356. * @example
  14357. *
  14358. * ```js
  14359. * var rect = new kity.Rect();
  14360. *
  14361. * console.log(rect.getClass() === kity.Rect); // true
  14362. * console.log(rect instanceof kity.Rect); // true
  14363. * ```
  14364. */
  14365. Class.prototype.getClass = function() {
  14366. return this.constructor;
  14367. };
  14368. // 检查基类是否调用了父类的构造函数
  14369. // 该检查是弱检查,假如调用的代码被注释了,同样能检查成功(这个特性可用于知道建议调用,但是出于某些原因不想调用的情况)
  14370. function checkBaseConstructorCall(targetClass, classname) {
  14371. var code = targetClass.toString();
  14372. if (!/this\.callBase/.test(code)) {
  14373. throw new Error(classname + " : 类构造函数没有调用父类的构造函数!为了安全,请调用父类的构造函数");
  14374. }
  14375. }
  14376. var KITY_INHERIT_FLAG = "__KITY_INHERIT_FLAG_" + +new Date();
  14377. function inherit(constructor, BaseClass, classname) {
  14378. var KityClass = eval("(function " + classname + "( __inherit__flag ) {" + "if( __inherit__flag != KITY_INHERIT_FLAG ) {" + "KityClass.__KityConstructor.apply(this, arguments);" + "}" + "this.__KityClassName = KityClass.__KityClassName;" + "})");
  14379. KityClass.__KityConstructor = constructor;
  14380. KityClass.prototype = new BaseClass(KITY_INHERIT_FLAG);
  14381. for (var methodName in BaseClass.prototype) {
  14382. if (BaseClass.prototype.hasOwnProperty(methodName) && methodName.indexOf("__Kity") !== 0) {
  14383. KityClass.prototype[methodName] = BaseClass.prototype[methodName];
  14384. }
  14385. }
  14386. KityClass.prototype.constructor = KityClass;
  14387. return KityClass;
  14388. }
  14389. function mixin(NewClass, mixins) {
  14390. if (false === mixins instanceof Array) {
  14391. return NewClass;
  14392. }
  14393. var i, length = mixins.length, proto, method;
  14394. NewClass.__KityMixins = {
  14395. constructor: []
  14396. };
  14397. for (i = 0; i < length; i++) {
  14398. proto = mixins[i].prototype;
  14399. for (method in proto) {
  14400. if (false === proto.hasOwnProperty(method) || method.indexOf("__Kity") === 0) {
  14401. continue;
  14402. }
  14403. if (method === "constructor") {
  14404. // constructor 特殊处理
  14405. NewClass.__KityMixins.constructor.push(proto[method]);
  14406. } else {
  14407. NewClass.prototype[method] = NewClass.__KityMixins[method] = proto[method];
  14408. }
  14409. }
  14410. }
  14411. return NewClass;
  14412. }
  14413. function extend(BaseClass, extension) {
  14414. if (extension.__KityClassName) {
  14415. extension = extension.prototype;
  14416. }
  14417. for (var methodName in extension) {
  14418. if (extension.hasOwnProperty(methodName) && methodName.indexOf("__Kity") && methodName != "constructor") {
  14419. var method = BaseClass.prototype[methodName] = extension[methodName];
  14420. method.__KityMethodClass = BaseClass;
  14421. method.__KityMethodName = methodName;
  14422. }
  14423. }
  14424. return BaseClass;
  14425. }
  14426. /**
  14427. * @method kity.createClass()
  14428. * @grammar kity.createClass(classname, defines) => {Class}
  14429. * @description 创建一个类
  14430. * @param {string} classname 类名,用于调试的时候查看,可选
  14431. * @param {object} defines 类定义
  14432. * defines.base {Class}
  14433. * 定义的类的基类,如果不配置,则表示基类为 kity.Class
  14434. * defines.mixins {Class[]}
  14435. * 定义的类要融合的类列表
  14436. * defines.constructor {Function}
  14437. * 定义类的构造函数,如果父类显式定义了构造函数,需要在构造函数中使用 callBase() 方法调用父类的构造函数
  14438. * defines.* {Function}
  14439. * 定义类的其它函数
  14440. *
  14441. * @example 创建一个类
  14442. *
  14443. * ```js
  14444. * var Animal = kity.createClass('Animal', {
  14445. * constructor: function(name) {
  14446. * this.name = name;
  14447. * },
  14448. * toString: function() {
  14449. * return this.name;
  14450. * }
  14451. * });
  14452. *
  14453. * var a = new Animal('kity');
  14454. * console.log(a.toString()); // "kity"
  14455. * ```
  14456. *
  14457. * @example 继承一个类
  14458. *
  14459. * ```js
  14460. * var Cat = kity.createClass('Cat', {
  14461. * base: Animal,
  14462. * constructor: function(name, color) {
  14463. * // 调用父类构造函数
  14464. * this.callBase(name);
  14465. * },
  14466. * toString: function() {
  14467. * return 'A ' + this.color + ' cat, ' + this.callBase();
  14468. * }
  14469. * });
  14470. *
  14471. * var cat = new Cat('kity', 'black');
  14472. * console.log(cat.toString()); // "A black cat, kity"
  14473. * ```
  14474. *
  14475. * @example 混合类的能力
  14476. * ```js
  14477. * var Walkable = kity.createClass('Walkable', {
  14478. * constructor: function() {
  14479. * this.speed = 'fast';
  14480. * },
  14481. * walk: function() {
  14482. * console.log('I am walking ' + this.speed);
  14483. * }
  14484. * });
  14485. *
  14486. * var Dog = kity.createClass('Dog', {
  14487. * base: Animal,
  14488. * mixins: [Walkable],
  14489. * constructor: function(name) {
  14490. * this.callBase(name);
  14491. * this.callMixins();
  14492. * }
  14493. * });
  14494. *
  14495. * var dog = new Dog('doggy');
  14496. * console.log(dog.toString() + ' say:');
  14497. * dog.walk();
  14498. * ```
  14499. */
  14500. exports.createClass = function(classname, defines) {
  14501. var constructor, NewClass, BaseClass;
  14502. if (arguments.length === 1) {
  14503. defines = arguments[0];
  14504. classname = "AnonymousClass";
  14505. }
  14506. BaseClass = defines.base || Class;
  14507. if (defines.hasOwnProperty("constructor")) {
  14508. constructor = defines.constructor;
  14509. if (BaseClass != Class) {
  14510. checkBaseConstructorCall(constructor, classname);
  14511. }
  14512. } else {
  14513. constructor = function() {
  14514. this.callBase.apply(this, arguments);
  14515. this.callMixin.apply(this, arguments);
  14516. };
  14517. }
  14518. NewClass = inherit(constructor, BaseClass, classname);
  14519. NewClass = mixin(NewClass, defines.mixins);
  14520. NewClass.__KityClassName = constructor.__KityClassName = classname;
  14521. NewClass.__KityBaseClass = constructor.__KityBaseClass = BaseClass;
  14522. NewClass.__KityMethodName = constructor.__KityMethodName = "constructor";
  14523. NewClass.__KityMethodClass = constructor.__KityMethodClass = NewClass;
  14524. // 下面这些不需要拷贝到原型链上
  14525. delete defines.mixins;
  14526. delete defines.constructor;
  14527. delete defines.base;
  14528. NewClass = extend(NewClass, defines);
  14529. return NewClass;
  14530. };
  14531. /**
  14532. * @method kity.extendClass()
  14533. * @grammar kity.extendClass(clazz, extension) => {Class}
  14534. * @description 拓展一个已有的类
  14535. *
  14536. * @example
  14537. *
  14538. * ```js
  14539. * kity.extendClass(Dog, {
  14540. * spark: function() {
  14541. * console.log('wao wao wao!');
  14542. * }
  14543. * });
  14544. *
  14545. * new Dog().spark(); // "wao wao wao!";
  14546. * ```
  14547. */
  14548. exports.extendClass = extend;
  14549. }
  14550. };
  14551. //src/core/utils.js
  14552. /**
  14553. * @fileOverview
  14554. *
  14555. * 一些常用的工具方法
  14556. */
  14557. _p[12] = {
  14558. value: function() {
  14559. /**
  14560. * @class kity.Utils
  14561. * @catalog core
  14562. * @static
  14563. * @description 提供常用的工具方法
  14564. */
  14565. var utils = {
  14566. /**
  14567. * @method each()
  14568. * @for kity.Utils
  14569. * @grammar each(obj, interator, context)
  14570. * @param {Object|Array} obj 要迭代的对象或数组
  14571. * @param {Function} iterator 迭代函数
  14572. * @param {Any} context 迭代函数的上下文
  14573. *
  14574. * @example 迭代数组
  14575. *
  14576. * ```js
  14577. * kity.Utils.each([1, 2, 3, 4, 5], function(value, index, array) {
  14578. * console.log(value, index);
  14579. * });
  14580. * // 1, 0
  14581. * // 2, 1
  14582. * // 3, 2
  14583. * // 4, 3
  14584. * // 5, 4
  14585. * ```
  14586. *
  14587. * @example 迭代对象
  14588. *
  14589. * ```js
  14590. * var obj = {
  14591. * name: 'kity',
  14592. * version: '1.2.1'
  14593. * };
  14594. * var param = [];
  14595. * kity.Utils.each(obj, function(value, key, obj) {
  14596. * param.push(key + '=' + value);
  14597. * });
  14598. * console.log(param.join('&')); // "name=kity&version=1.2.1"
  14599. * ```
  14600. */
  14601. each: function each(obj, iterator, context) {
  14602. if (obj === null) {
  14603. return;
  14604. }
  14605. if (obj.length === +obj.length) {
  14606. for (var i = 0, l = obj.length; i < l; i++) {
  14607. if (iterator.call(context, obj[i], i, obj) === false) {
  14608. return false;
  14609. }
  14610. }
  14611. } else {
  14612. for (var key in obj) {
  14613. if (obj.hasOwnProperty(key)) {
  14614. if (iterator.call(context, obj[key], key, obj) === false) {
  14615. return false;
  14616. }
  14617. }
  14618. }
  14619. }
  14620. },
  14621. /**
  14622. * @method extend()
  14623. * @for kity.Utils
  14624. * @grammar extend(target, sources..., notCover) => {object}
  14625. * @description 把源对象的属性合并到目标对象上
  14626. * @param {object} target 目标对象
  14627. * @param {parameter} sources 源对象
  14628. * @param {boolean} notCover 是否不要覆盖源对象已有的属性
  14629. *
  14630. * @example
  14631. *
  14632. * ```js
  14633. * var a = {
  14634. * key1: 'a1',
  14635. * key2: 'a2'
  14636. * };
  14637. *
  14638. * var b = {
  14639. * key2: 'b2',
  14640. * key3: 'b3'
  14641. * };
  14642. *
  14643. * var c = {
  14644. * key4: 'c4'
  14645. * };
  14646. *
  14647. * var d = kity.extend(a, b, c);
  14648. *
  14649. * console.log(d === a); // true
  14650. * console.log(a); // {key1: 'a1', key2: 'b2', key3: 'b3', key4: 'c4'}
  14651. * ```
  14652. */
  14653. extend: function extend(t) {
  14654. var a = arguments, notCover = this.isBoolean(a[a.length - 1]) ? a[a.length - 1] : false, len = this.isBoolean(a[a.length - 1]) ? a.length - 1 : a.length;
  14655. for (var i = 1; i < len; i++) {
  14656. var x = a[i];
  14657. for (var k in x) {
  14658. if (!notCover || !t.hasOwnProperty(k)) {
  14659. t[k] = x[k];
  14660. }
  14661. }
  14662. }
  14663. return t;
  14664. },
  14665. /**
  14666. * @method deepExtend()
  14667. * @for kity.Utils
  14668. * @grammar deepExtend(target, sources..., notCover)
  14669. * @description 把源对象的属性合并到目标对象上,如果属性是对象,会递归合并
  14670. * @param {object} target 目标对象
  14671. * @param {parameter} sources 源对象
  14672. * @param {boolean} notCover 是否不要覆盖源对象已有的属性
  14673. */
  14674. deepExtend: function(t, s) {
  14675. var a = arguments, notCover = this.isBoolean(a[a.length - 1]) ? a[a.length - 1] : false, len = this.isBoolean(a[a.length - 1]) ? a.length - 1 : a.length;
  14676. for (var i = 1; i < len; i++) {
  14677. var x = a[i];
  14678. for (var k in x) {
  14679. if (!notCover || !t.hasOwnProperty(k)) {
  14680. if (this.isObject(t[k]) && this.isObject(x[k])) {
  14681. this.deepExtend(t[k], x[k], notCover);
  14682. } else {
  14683. t[k] = x[k];
  14684. }
  14685. }
  14686. }
  14687. }
  14688. return t;
  14689. },
  14690. /**
  14691. * @method clone()
  14692. * @for kity.Utils
  14693. * @grammar clone(obj) => {object}
  14694. * @description 返回一个对象的克隆副本(非深度复制)
  14695. * @param {object} obj 要克隆的对象
  14696. *
  14697. * @example
  14698. *
  14699. * ```js
  14700. * var source = {
  14701. * key1: {
  14702. * key2: 'value2'
  14703. * },
  14704. * key3: 'value3'
  14705. * };
  14706. *
  14707. * var target = kity.Utils.clone(source);
  14708. *
  14709. * console.log(target === source); // false
  14710. * console.log(target.key1 === source.key1); // true
  14711. * console.log(target.key3 === source.key3); // true
  14712. * ```
  14713. */
  14714. clone: function clone(obj) {
  14715. var cloned = {};
  14716. for (var m in obj) {
  14717. if (obj.hasOwnProperty(m)) {
  14718. cloned[m] = obj[m];
  14719. }
  14720. }
  14721. return cloned;
  14722. },
  14723. /**
  14724. * @method copy()
  14725. * @for kity.Utils
  14726. * @grammar copy(obj) => {object}
  14727. * @description 返回一个对象的拷贝副本(深度复制)
  14728. * @param {object} obj 要拷贝的对象
  14729. *
  14730. * @example
  14731. *
  14732. * ```js
  14733. * var source = {
  14734. * key1: {
  14735. * key2: 'value2'
  14736. * },
  14737. * key3: 'value3'
  14738. * };
  14739. *
  14740. * var target = kity.Utils.copy(source);
  14741. *
  14742. * console.log(target === source); // false
  14743. * console.log(target.key1 === source.key1); // false
  14744. * console.log(target.key3 === source.key3); // true,因为是值类型
  14745. * ```
  14746. */
  14747. copy: function copy(obj) {
  14748. if (typeof obj !== "object") return obj;
  14749. if (typeof obj === "function") return null;
  14750. return JSON.parse(JSON.stringify(obj));
  14751. },
  14752. queryPath: function(path, obj) {
  14753. var arr = path.split(".");
  14754. var i = 0, tmp = obj, l = arr.length;
  14755. while (i < l) {
  14756. if (arr[i] in tmp) {
  14757. tmp = tmp[arr[i]];
  14758. i++;
  14759. if (i >= l || tmp === undefined) {
  14760. return tmp;
  14761. }
  14762. } else {
  14763. return undefined;
  14764. }
  14765. }
  14766. },
  14767. getValue: function(value, defaultValue) {
  14768. return value !== undefined ? value : defaultValue;
  14769. },
  14770. /**
  14771. * @method flatten()
  14772. * @for kity.Utils
  14773. * @grammar flatten(arr) => {Array}
  14774. * @description 返回给定数组的扁平化版本
  14775. * @param {Array} arr 要扁平化的数组
  14776. *
  14777. * @example
  14778. *
  14779. * ```js
  14780. * var flattened = kity.Utils.flatten([[1, 2], [2, 3], [[4, 5], [6, 7]]]);
  14781. * console.log(flattened); // [1, 2, 3, 4, 5, 6, 7];
  14782. * ```
  14783. */
  14784. flatten: function flatten(arr) {
  14785. var result = [], length = arr.length, i;
  14786. for (i = 0; i < length; i++) {
  14787. if (arr[i] instanceof Array) {
  14788. result = result.concat(utils.flatten(arr[i]));
  14789. } else {
  14790. result.push(arr[i]);
  14791. }
  14792. }
  14793. return result;
  14794. },
  14795. /**
  14796. * @method paralle()
  14797. * @for kity.Utils
  14798. * @grammar paralle() => {Any}
  14799. *
  14800. * @description 平行地对 v1 和 v2 进行指定的操作
  14801. *
  14802. * 如果 v1 是数字,那么直接进行 op 操作
  14803. * 如果 v1 是对象,那么返回一个对象,其元素是 v1 和 v2 同键值的每个元素平行地进行 op 操作的结果
  14804. * 如果 v1 是数组,那么返回一个数组,其元素是 v1 和 v2 同索引的每个元素平行地进行 op 操作的结果
  14805. *
  14806. * @param {Number|Object|Array} v1 第一个操作数
  14807. * @param {Number|Object|Array} v2 第二个操作数
  14808. * @param {Function} op 操作函数
  14809. *
  14810. *
  14811. *
  14812. * @example
  14813. *
  14814. * ```js
  14815. * var a = {
  14816. * value1: 1,
  14817. * value2: 2,
  14818. * value3: [3, 4, 5]
  14819. * };
  14820. *
  14821. * var b = {
  14822. * value1: 2,
  14823. * value2: 3,
  14824. * value3: [4, 5, 6]
  14825. * };
  14826. *
  14827. * var c = kity.Utils.paralle(a, b, function(v1, v2) {
  14828. * return v1 + v2;
  14829. * });
  14830. *
  14831. * console.log(c.value1); // 3
  14832. * console.log(c.value2); // 5
  14833. * console.log(c.value3); // [7, 9, 11]
  14834. *
  14835. * ```
  14836. */
  14837. paralle: function paralle(v1, v2, op) {
  14838. var Class, field, index, name, value;
  14839. // 数组
  14840. if (v1 instanceof Array) {
  14841. value = [];
  14842. for (index = 0; index < v1.length; index++) {
  14843. value.push(utils.paralle(v1[index], v2[index], op));
  14844. }
  14845. return value;
  14846. }
  14847. // 对象
  14848. if (v1 instanceof Object) {
  14849. // 如果值是一个支持原始表示的实例,获取其原始表示
  14850. Class = v1.getClass && v1.getClass();
  14851. if (Class && Class.parse) {
  14852. v1 = v1.valueOf();
  14853. v2 = v2.valueOf();
  14854. value = utils.paralle(v1, v2, op);
  14855. value = Class.parse(value);
  14856. } else {
  14857. value = {};
  14858. for (name in v1) {
  14859. if (v1.hasOwnProperty(name) && v2.hasOwnProperty(name)) {
  14860. value[name] = utils.paralle(v1[name], v2[name], op);
  14861. }
  14862. }
  14863. }
  14864. return value;
  14865. }
  14866. // 是否数字
  14867. if (false === isNaN(parseFloat(v1))) {
  14868. return op(v1, v2);
  14869. }
  14870. return value;
  14871. },
  14872. /**
  14873. * 创建 op 操作的一个平行化版本
  14874. */
  14875. parallelize: function parallelize(op) {
  14876. return function(v1, v2) {
  14877. return utils.paralle(v1, v2, op);
  14878. };
  14879. }
  14880. };
  14881. /**
  14882. * @method isString()
  14883. * @for kity.Utils
  14884. * @grammar isString(unknown) => {boolean}
  14885. * @description 判断一个值是否为字符串类型
  14886. * @param {any} unknown 要判断的值
  14887. */
  14888. /**
  14889. * @method isFunction()
  14890. * @for kity.Utils
  14891. * @grammar isFunction(unknown) => {boolean}
  14892. * @description 判断一个值是否为函数类型
  14893. * @param {any} unknown 要判断的值
  14894. */
  14895. /**
  14896. * @method isArray()
  14897. * @for kity.Utils
  14898. * @grammar isArray(unknown) => {boolean}
  14899. * @description 判断一个值是否为数组类型
  14900. * @param {any} unknown 要判断的值
  14901. */
  14902. /**
  14903. * @method isNumber()
  14904. * @for kity.Utils
  14905. * @grammar isNumber(unknown) => {boolean}
  14906. * @description 判断一个值是否为数字类型
  14907. * @param {any} unknown 要判断的值
  14908. */
  14909. /**
  14910. * @method isRegExp()
  14911. * @for kity.Utils
  14912. * @grammar isRegExp(unknown) => {boolean}
  14913. * @description 判断一个值是否为正则表达式类型
  14914. * @param {any} unknown 要判断的值
  14915. */
  14916. /**
  14917. * @method isObject()
  14918. * @for kity.Utils
  14919. * @grammar isObject(unknown) => {boolean}
  14920. * @description 判断一个值是否为对象类型
  14921. * @param {any} unknown 要判断的值
  14922. */
  14923. /**
  14924. * @method isBoolean()
  14925. * @for kity.Utils
  14926. * @grammar isBoolean(unknown) => {boolean}
  14927. * @description 判断一个值是否为布尔类型
  14928. * @param {any} unknown 要判断的值
  14929. */
  14930. utils.each([ "String", "Function", "Array", "Number", "RegExp", "Object", "Boolean" ], function(v) {
  14931. utils["is" + v] = function typeCheck(obj) {
  14932. return Object.prototype.toString.apply(obj) == "[object " + v + "]";
  14933. };
  14934. });
  14935. return utils;
  14936. }
  14937. };
  14938. //src/filter/effect/colormatrixeffect.js
  14939. /**
  14940. * 颜色矩阵运算效果封装
  14941. */
  14942. _p[13] = {
  14943. value: function(require, exports, module) {
  14944. var Effect = _p.r(16), Utils = _p.r(12);
  14945. var ColorMatrixEffect = _p.r(11).createClass("ColorMatrixEffect", {
  14946. base: Effect,
  14947. constructor: function(type, input) {
  14948. this.callBase(Effect.NAME_COLOR_MATRIX);
  14949. this.set("type", Utils.getValue(type, ColorMatrixEffect.TYPE_MATRIX));
  14950. this.set("in", Utils.getValue(input, Effect.INPUT_SOURCE_GRAPHIC));
  14951. }
  14952. });
  14953. Utils.extend(ColorMatrixEffect, {
  14954. // 类型常量
  14955. TYPE_MATRIX: "matrix",
  14956. TYPE_SATURATE: "saturate",
  14957. TYPE_HUE_ROTATE: "hueRotate",
  14958. TYPE_LUMINANCE_TO_ALPHA: "luminanceToAlpha",
  14959. // 矩阵常量
  14960. MATRIX_ORIGINAL: "10000010000010000010".split("").join(" "),
  14961. MATRIX_EMPTY: "00000000000000000000".split("").join(" ")
  14962. });
  14963. return ColorMatrixEffect;
  14964. }
  14965. };
  14966. //src/filter/effect/compositeeffect.js
  14967. /**
  14968. * 高斯模糊效果封装
  14969. */
  14970. _p[14] = {
  14971. value: function(require, exports, module) {
  14972. var Effect = _p.r(16), Utils = _p.r(12);
  14973. var CompositeEffect = _p.r(11).createClass("CompositeEffect", {
  14974. base: Effect,
  14975. constructor: function(operator, input, input2) {
  14976. this.callBase(Effect.NAME_COMPOSITE);
  14977. this.set("operator", Utils.getValue(operator, CompositeEffect.OPERATOR_OVER));
  14978. if (input) {
  14979. this.set("in", input);
  14980. }
  14981. if (input2) {
  14982. this.set("in2", input2);
  14983. }
  14984. }
  14985. });
  14986. Utils.extend(CompositeEffect, {
  14987. // operator 常量
  14988. OPERATOR_OVER: "over",
  14989. OPERATOR_IN: "in",
  14990. OPERATOR_OUT: "out",
  14991. OPERATOR_ATOP: "atop",
  14992. OPERATOR_XOR: "xor",
  14993. OPERATOR_ARITHMETIC: "arithmetic"
  14994. });
  14995. return CompositeEffect;
  14996. }
  14997. };
  14998. //src/filter/effect/convolvematrixeffect.js
  14999. /**
  15000. * 像素级别的矩阵卷积运算效果封装
  15001. */
  15002. _p[15] = {
  15003. value: function(require, exports, module) {
  15004. var Effect = _p.r(16), Utils = _p.r(12);
  15005. var ConvolveMatrixEffect = _p.r(11).createClass("ConvolveMatrixEffect", {
  15006. base: Effect,
  15007. constructor: function(edgeMode, input) {
  15008. this.callBase(Effect.NAME_CONVOLVE_MATRIX);
  15009. this.set("edgeMode", Utils.getValue(edgeMode, ConvolveMatrixEffect.MODE_DUPLICATE));
  15010. this.set("in", Utils.getValue(input, Effect.INPUT_SOURCE_GRAPHIC));
  15011. }
  15012. });
  15013. Utils.extend(ConvolveMatrixEffect, {
  15014. MODE_DUPLICATE: "duplicate",
  15015. MODE_WRAP: "wrap",
  15016. MODE_NONE: "none"
  15017. });
  15018. return ConvolveMatrixEffect;
  15019. }
  15020. };
  15021. //src/filter/effect/effect.js
  15022. /*
  15023. * 效果类
  15024. * 该类型的对象不存储任何内部属性, 所有操作都是针对该类对象所维护的节点进行的
  15025. */
  15026. _p[16] = {
  15027. value: function(require, exports, module) {
  15028. var svg = _p.r(67), Effect = _p.r(11).createClass("Effect", {
  15029. constructor: function(type) {
  15030. this.node = svg.createNode(type);
  15031. },
  15032. getId: function() {
  15033. return this.node.id;
  15034. },
  15035. setId: function(id) {
  15036. this.node.id = id;
  15037. return this;
  15038. },
  15039. set: function(key, value) {
  15040. this.node.setAttribute(key, value);
  15041. return this;
  15042. },
  15043. get: function(key) {
  15044. return this.node.getAttribute(key);
  15045. },
  15046. getNode: function() {
  15047. return this.node;
  15048. },
  15049. // 返回该效果的result
  15050. toString: function() {
  15051. return this.node.getAttribute("result") || "";
  15052. }
  15053. });
  15054. _p.r(12).extend(Effect, {
  15055. // 特效名称常量
  15056. NAME_GAUSSIAN_BLUR: "feGaussianBlur",
  15057. NAME_OFFSET: "feOffset",
  15058. NAME_COMPOSITE: "feComposite",
  15059. NAME_COLOR_MATRIX: "feColorMatrix",
  15060. NAME_CONVOLVE_MATRIX: "feConvolveMatrix",
  15061. // 输入常量
  15062. INPUT_SOURCE_GRAPHIC: "SourceGraphic",
  15063. INPUT_SOURCE_ALPHA: "SourceAlpha",
  15064. INPUT_BACKGROUND_IMAGE: "BackgroundImage",
  15065. INPUT_BACKGROUND_ALPHA: "BackgroundAlpha",
  15066. INPUT_FILL_PAINT: "FillPaint",
  15067. INPUT_STROKE_PAINT: "StrokePaint"
  15068. });
  15069. return Effect;
  15070. }
  15071. };
  15072. //src/filter/effect/gaussianblureffect.js
  15073. /**
  15074. * 高斯模糊效果封装
  15075. */
  15076. _p[17] = {
  15077. value: function(require, exports, module) {
  15078. var Effect = _p.r(16), Utils = _p.r(12);
  15079. return _p.r(11).createClass("GaussianblurEffect", {
  15080. base: Effect,
  15081. constructor: function(stdDeviation, input) {
  15082. this.callBase(Effect.NAME_GAUSSIAN_BLUR);
  15083. this.set("stdDeviation", Utils.getValue(stdDeviation, 1));
  15084. this.set("in", Utils.getValue(input, Effect.INPUT_SOURCE_GRAPHIC));
  15085. }
  15086. });
  15087. }
  15088. };
  15089. //src/filter/effect/offseteffect.js
  15090. /**
  15091. * 偏移效果封装
  15092. */
  15093. _p[18] = {
  15094. value: function(require, exports, module) {
  15095. var Effect = _p.r(16), Utils = _p.r(12);
  15096. return _p.r(11).createClass("OffsetEffect", {
  15097. base: Effect,
  15098. constructor: function(dx, dy, input) {
  15099. this.callBase(Effect.NAME_OFFSET);
  15100. this.set("dx", Utils.getValue(dx, 0));
  15101. this.set("dy", Utils.getValue(dy, 0));
  15102. this.set("in", Utils.getValue(input, Effect.INPUT_SOURCE_GRAPHIC));
  15103. }
  15104. });
  15105. }
  15106. };
  15107. //src/filter/effectcontainer.js
  15108. /*
  15109. * Effect所用的container
  15110. */
  15111. _p[19] = {
  15112. value: function(require) {
  15113. return _p.r(11).createClass("EffectContainer", {
  15114. base: _p.r(29),
  15115. addEffect: function(point, pos) {
  15116. return this.addItem.apply(this, arguments);
  15117. },
  15118. prependEffect: function() {
  15119. return this.prependItem.apply(this, arguments);
  15120. },
  15121. appendEffect: function() {
  15122. return this.appendItem.apply(this, arguments);
  15123. },
  15124. removeEffect: function(pos) {
  15125. return this.removeItem.apply(this, arguments);
  15126. },
  15127. addEffects: function() {
  15128. return this.addItems.apply(this, arguments);
  15129. },
  15130. setEffects: function() {
  15131. return this.setItems.apply(this, arguments);
  15132. },
  15133. getEffect: function() {
  15134. return this.getItem.apply(this, arguments);
  15135. },
  15136. getEffects: function() {
  15137. return this.getItems.apply(this, arguments);
  15138. },
  15139. getFirstEffect: function() {
  15140. return this.getFirstItem.apply(this, arguments);
  15141. },
  15142. getLastEffect: function() {
  15143. return this.getLastItem.apply(this, arguments);
  15144. },
  15145. handleAdd: function(effectItem, pos) {
  15146. var count = this.getEffects().length, nextEffectItem = this.getItem(pos + 1);
  15147. // 最后一个节点, 直接追加
  15148. if (count === pos + 1) {
  15149. this.node.appendChild(effectItem.getNode());
  15150. return;
  15151. }
  15152. this.node.insertBefore(effectItem.getNode(), nextEffectItem.getNode());
  15153. }
  15154. });
  15155. }
  15156. };
  15157. //src/filter/filter.js
  15158. /**
  15159. * Filter 基类
  15160. */
  15161. _p[20] = {
  15162. value: function(require, exports, module) {
  15163. var svg = _p.r(67);
  15164. var Class = _p.r(11);
  15165. var Filter = Class.createClass("Filter", {
  15166. mixins: [ _p.r(19) ],
  15167. constructor: function(x, y, width, height) {
  15168. this.node = svg.createNode("filter");
  15169. if (x !== undefined) {
  15170. this.set("x", x);
  15171. }
  15172. if (y !== undefined) {
  15173. this.set("y", y);
  15174. }
  15175. if (width !== undefined) {
  15176. this.set("width", width);
  15177. }
  15178. if (height !== undefined) {
  15179. this.set("height", height);
  15180. }
  15181. },
  15182. getId: function() {
  15183. return this.id;
  15184. },
  15185. setId: function(id) {
  15186. this.node.id = id;
  15187. return this;
  15188. },
  15189. set: function(key, value) {
  15190. this.node.setAttribute(key, value);
  15191. return this;
  15192. },
  15193. get: function(key) {
  15194. return this.node.getAttribute(key);
  15195. },
  15196. getNode: function() {
  15197. return this.node;
  15198. }
  15199. });
  15200. var Shape = _p.r(60);
  15201. Class.extendClass(Shape, {
  15202. applyFilter: function(filter) {
  15203. var filterId = filter.get("id");
  15204. if (filterId) {
  15205. this.node.setAttribute("filter", "url(#" + filterId + ")");
  15206. }
  15207. return this;
  15208. }
  15209. });
  15210. return Filter;
  15211. }
  15212. };
  15213. //src/filter/gaussianblurfilter.js
  15214. /*
  15215. * 高斯模糊滤镜
  15216. */
  15217. _p[21] = {
  15218. value: function(require, exports, module) {
  15219. var GaussianblurEffect = _p.r(17);
  15220. return _p.r(11).createClass("GaussianblurFilter", {
  15221. base: _p.r(20),
  15222. constructor: function(stdDeviation) {
  15223. this.callBase();
  15224. this.addEffect(new GaussianblurEffect(stdDeviation));
  15225. }
  15226. });
  15227. }
  15228. };
  15229. //src/filter/projectionfilter.js
  15230. /*
  15231. * 投影滤镜
  15232. */
  15233. _p[22] = {
  15234. value: function(require, exports, module) {
  15235. var GaussianblurEffect = _p.r(17), Effect = _p.r(16), ColorMatrixEffect = _p.r(13), Color = _p.r(28), Utils = _p.r(12), CompositeEffect = _p.r(14), OffsetEffect = _p.r(18);
  15236. return _p.r(11).createClass("ProjectionFilter", {
  15237. base: _p.r(20),
  15238. constructor: function(stdDeviation, dx, dy) {
  15239. this.callBase();
  15240. this.gaussianblurEffect = new GaussianblurEffect(stdDeviation, Effect.INPUT_SOURCE_ALPHA);
  15241. this.gaussianblurEffect.set("result", "gaussianblur");
  15242. this.addEffect(this.gaussianblurEffect);
  15243. this.offsetEffect = new OffsetEffect(dx, dy, this.gaussianblurEffect);
  15244. this.offsetEffect.set("result", "offsetBlur");
  15245. this.addEffect(this.offsetEffect);
  15246. this.colorMatrixEffect = new ColorMatrixEffect(ColorMatrixEffect.TYPE_MATRIX, this.offsetEffect);
  15247. this.colorMatrixEffect.set("values", ColorMatrixEffect.MATRIX_ORIGINAL);
  15248. this.colorMatrixEffect.set("result", "colorOffsetBlur");
  15249. this.addEffect(this.colorMatrixEffect);
  15250. this.compositeEffect = new CompositeEffect(CompositeEffect.OPERATOR_OVER, Effect.INPUT_SOURCE_GRAPHIC, this.colorMatrixEffect);
  15251. this.addEffect(this.compositeEffect);
  15252. },
  15253. // 设置投影颜色
  15254. setColor: function(color) {
  15255. var matrix = null, originMatrix = null, colorValue = [];
  15256. if (Utils.isString(color)) {
  15257. color = Color.parse(color);
  15258. }
  15259. if (!color) {
  15260. return this;
  15261. }
  15262. matrix = ColorMatrixEffect.MATRIX_EMPTY.split(" ");
  15263. colorValue.push(color.get("r"));
  15264. colorValue.push(color.get("g"));
  15265. colorValue.push(color.get("b"));
  15266. // rgb 分量更改
  15267. for (var i = 0, len = colorValue.length; i < len; i++) {
  15268. matrix[i * 5 + 3] = colorValue[i] / 255;
  15269. }
  15270. // alpha 分量更改
  15271. matrix[18] = color.get("a");
  15272. this.colorMatrixEffect.set("values", matrix.join(" "));
  15273. return this;
  15274. },
  15275. // 设置投影透明度
  15276. setOpacity: function(opacity) {
  15277. var matrix = this.colorMatrixEffect.get("values").split(" ");
  15278. matrix[18] = opacity;
  15279. this.colorMatrixEffect.set("values", matrix.join(" "));
  15280. return this;
  15281. },
  15282. // 设置阴影偏移量
  15283. setOffset: function(dx, dy) {
  15284. this.setOffsetX(dx);
  15285. this.setOffsetY(dy);
  15286. },
  15287. setOffsetX: function(dx) {
  15288. this.offsetEffect.set("dx", dx);
  15289. },
  15290. setOffsetY: function(dy) {
  15291. this.offsetEffect.set("dy", dy);
  15292. },
  15293. setDeviation: function(deviation) {
  15294. this.gaussianblurEffect.set("stdDeviation", deviation);
  15295. }
  15296. });
  15297. }
  15298. };
  15299. //src/graphic/bezier.js
  15300. /**
  15301. * @fileOverview
  15302. *
  15303. * 贝塞尔曲线
  15304. */
  15305. _p[23] = {
  15306. value: function(require, exports, module) {
  15307. /**
  15308. * @class kity.Bezier
  15309. * @mixins kity.PointContainer
  15310. * @base kity.Path
  15311. * @description 绘制和使用贝塞尔曲线。贝塞尔曲线作为一个贝塞尔点的容器,任何贝塞尔点的改变都会更改贝塞尔曲线的外观
  15312. */
  15313. return _p.r(11).createClass("Bezier", {
  15314. mixins: [ _p.r(51) ],
  15315. base: _p.r(46),
  15316. /**
  15317. * @constructor
  15318. * @for kity.Bezier
  15319. *
  15320. * @grammar new kity.Bezier(bezierPoints)
  15321. *
  15322. * @param {kity.BezierPoints[]} bezierPoints 贝塞尔点集合,每个元素应该是 {kity.BezierPoint} 类型
  15323. *
  15324. * @example
  15325. *
  15326. * ```js
  15327. * var bezier = new kity.Bezier([
  15328. * new kity.BezierPoint(0, 0).setForward(100, 0),
  15329. * new kity.BezierPoint(100, 100).setBackward(100, 0)
  15330. * ]);
  15331. * ```
  15332. */
  15333. constructor: function(bezierPoints) {
  15334. this.callBase();
  15335. bezierPoints = bezierPoints || [];
  15336. this.changeable = true;
  15337. this.setBezierPoints(bezierPoints);
  15338. },
  15339. /**
  15340. * @method getBezierPoints()
  15341. * @for kity.Bezier
  15342. * @description 返回当前贝塞尔曲线的贝塞尔点集合
  15343. *
  15344. * @grammar getBezierPoints() => {kity.BezierPoints[]}
  15345. *
  15346. */
  15347. getBezierPoints: function() {
  15348. return this.getPoints();
  15349. },
  15350. /**
  15351. * @method setBezierPoints()
  15352. * @for kity.Bezier
  15353. * @description 设置当前贝塞尔曲线的贝塞尔点集合
  15354. *
  15355. * @grammar setBeizerPoints(bezierPoints) => {this}
  15356. *
  15357. * @param {kity.BezierPoint[]} bezierPoints 贝塞尔点集合
  15358. */
  15359. setBezierPoints: function(bezierPoints) {
  15360. return this.setPoints(bezierPoints);
  15361. },
  15362. //当点集合发生变化时采取的动作
  15363. onContainerChanged: function() {
  15364. if (this.changeable) {
  15365. this.update();
  15366. }
  15367. },
  15368. update: function() {
  15369. var drawer = null, bezierPoints = this.getBezierPoints();
  15370. //单独的一个点不画任何图形
  15371. if (bezierPoints.length < 2) {
  15372. return;
  15373. }
  15374. drawer = this.getDrawer();
  15375. drawer.clear();
  15376. var vertex = bezierPoints[0].getVertex(), forward = null, backward = null;
  15377. drawer.moveTo(vertex.x, vertex.y);
  15378. for (var i = 1, len = bezierPoints.length; i < len; i++) {
  15379. vertex = bezierPoints[i].getVertex();
  15380. backward = bezierPoints[i].getBackward();
  15381. forward = bezierPoints[i - 1].getForward();
  15382. drawer.bezierTo(forward.x, forward.y, backward.x, backward.y, vertex.x, vertex.y);
  15383. }
  15384. return this;
  15385. }
  15386. });
  15387. }
  15388. };
  15389. //src/graphic/bezierpoint.js
  15390. /**
  15391. * @fileOverview
  15392. *
  15393. * 表示一个贝塞尔点
  15394. */
  15395. _p[24] = {
  15396. value: function(require, exports, module) {
  15397. var ShapePoint = _p.r(63);
  15398. var Vector = _p.r(73);
  15399. /**
  15400. * @class kity.BezierPoint
  15401. *
  15402. * @description 表示一个贝塞尔点
  15403. * 一个贝塞尔点由顶点坐标(曲线经过的点)、前方控制点、后方控制点表示
  15404. */
  15405. var BezierPoint = _p.r(11).createClass("BezierPoint", {
  15406. /**
  15407. * @constructor
  15408. * @for kity.BezierPoint
  15409. *
  15410. * @description 创建一个具有默认顶点坐标的贝塞尔点,两个控制点的坐标和顶点一致
  15411. *
  15412. * @param {Number} x 顶点的 x 坐标
  15413. * @param {Number} y 顶点的 y 坐标
  15414. * @param {Boolean} isSmooth 指示当前贝塞尔点是否光滑,光滑会约束顶点和两个控制点共线
  15415. */
  15416. constructor: function(x, y, isSmooth) {
  15417. //顶点
  15418. this.vertex = new ShapePoint(x, y);
  15419. //控制点
  15420. this.forward = new ShapePoint(x, y);
  15421. this.backward = new ShapePoint(x, y);
  15422. //是否平滑
  15423. this.setSmooth(isSmooth === undefined || isSmooth);
  15424. this.setSymReflaction(true);
  15425. },
  15426. /**
  15427. * @method clone()
  15428. * @for kity.BezierPoint
  15429. * @description 返回贝塞尔点的一份拷贝
  15430. *
  15431. * @grammar clone() => {kity.BezierPoint}
  15432. */
  15433. clone: function() {
  15434. var newPoint = new BezierPoint(), tmp = null;
  15435. tmp = this.getVertex();
  15436. newPoint.setVertex(tmp.x, tmp.y);
  15437. tmp = this.getForward();
  15438. newPoint.setForward(tmp.x, tmp.y);
  15439. tmp = this.getBackward();
  15440. newPoint.setBackward(tmp.x, tmp.y);
  15441. newPoint.setSymReflaction(this.isSymReflaction);
  15442. newPoint.setSmooth(this.isSmooth());
  15443. return newPoint;
  15444. },
  15445. /**
  15446. * @method setVertex()
  15447. * @for kity.BezierPoint
  15448. * @description 设置贝塞尔点的顶点坐标,注意,控制点的坐标不会跟着变化。希望控制点的坐标跟着变化,请用 moveTo() 方法
  15449. *
  15450. * @grammar setVertex(x, y) => {this}
  15451. *
  15452. * @param {Number} x 顶点的 x 坐标
  15453. * @param {Number} y 顶点的 y 坐标
  15454. */
  15455. setVertex: function(x, y) {
  15456. this.vertex.setPoint(x, y);
  15457. this.update();
  15458. return this;
  15459. },
  15460. /**
  15461. * @method moveTo()
  15462. * @for kity.BezierPoint
  15463. * @description 同步移动整个贝塞尔点,使顶点的移动到指定的坐标中。控制点的位置相对顶点坐标固定。
  15464. *
  15465. * @grammar moveTo() => {this}
  15466. *
  15467. * @param {Number} x 顶点的目标 x 坐标
  15468. * @param {Number} y 顶点的目标 y 坐标
  15469. *
  15470. */
  15471. moveTo: function(x, y) {
  15472. var oldForward = this.forward.getPoint(), oldBackward = this.backward.getPoint(), oldVertex = this.vertex.getPoint(), //移动距离
  15473. distance = {
  15474. left: x - oldVertex.x,
  15475. top: y - oldVertex.y
  15476. };
  15477. // 更新
  15478. this.forward.setPoint(oldForward.x + distance.left, oldForward.y + distance.top);
  15479. this.backward.setPoint(oldBackward.x + distance.left, oldBackward.y + distance.top);
  15480. this.vertex.setPoint(x, y);
  15481. this.update();
  15482. },
  15483. /**
  15484. * @method setForward()
  15485. * @for kity.BezierPoint
  15486. * @description 设置前方控制点的位置,如果贝塞尔点光滑,后方控制点会跟着联动
  15487. *
  15488. * @grammar setForward(x, y) => {this}
  15489. *
  15490. * @param {Number} x 前方控制点的 x 坐标
  15491. * @param {Number} y 前方控制点的 y 坐标
  15492. */
  15493. setForward: function(x, y) {
  15494. this.forward.setPoint(x, y);
  15495. //更新后置点
  15496. if (this.smooth) {
  15497. this.updateAnother(this.forward, this.backward);
  15498. }
  15499. this.update();
  15500. this.lastControlPointSet = this.forward;
  15501. return this;
  15502. },
  15503. /**
  15504. * @method setBackward()
  15505. * @for kity.BezierPoint
  15506. * @description 设置后方控制点的位置,如果贝塞尔点光滑,前方控制点会跟着联动
  15507. *
  15508. * @grammar setBackward(x, y) => {this}
  15509. *
  15510. * @param {Number} x 后方控制点的 x 坐标
  15511. * @param {Number} y 后方控制点的 y 坐标
  15512. */
  15513. setBackward: function(x, y) {
  15514. this.backward.setPoint(x, y);
  15515. //更新前置点
  15516. if (this.smooth) {
  15517. this.updateAnother(this.backward, this.forward);
  15518. }
  15519. this.update();
  15520. this.lastControlPointSet = this.backward;
  15521. return this;
  15522. },
  15523. /**
  15524. * @method setSymReflaction()
  15525. * @for kity.BezierPoint
  15526. * @description 设定是否镜像两个控制点的位置
  15527. *
  15528. * @grammar setSymReflaction(value) => {this}
  15529. *
  15530. * @param {boolean} value 如果设置为 true,且贝塞尔点光滑,两个控制点离顶点的距离相等
  15531. */
  15532. setSymReflaction: function(value) {
  15533. this.symReflaction = value;
  15534. if (this.smooth) this.setSmooth(true);
  15535. return this;
  15536. },
  15537. /**
  15538. * @method isSymReflaction()
  15539. * @for kity.BezierPoint
  15540. * @description 当前贝塞尔点的两个控制点是否被镜像约束
  15541. *
  15542. * @grammar isSymReflaction() => {boolean}
  15543. */
  15544. isSymReflaction: function() {
  15545. return this.symReflaction;
  15546. },
  15547. /**
  15548. * @private
  15549. *
  15550. * 根据前方控制点或后方控制点更新另一方
  15551. */
  15552. updateAnother: function(p, q) {
  15553. var v = this.getVertex(), pv = Vector.fromPoints(p.getPoint(), v), vq = Vector.fromPoints(v, q.getPoint());
  15554. vq = pv.normalize(this.isSymReflaction() ? pv.length() : vq.length());
  15555. q.setPoint(v.x + vq.x, v.y + vq.y);
  15556. return this;
  15557. },
  15558. /**
  15559. * @method setSmooth()
  15560. * @for kity.BezierPoint
  15561. * @description 设置贝塞尔点是否光滑,光滑会约束顶点和两个控制点共线
  15562. *
  15563. * @param {Boolean} isSmooth 设置为 true 让贝塞尔点光滑
  15564. */
  15565. setSmooth: function(isSmooth) {
  15566. var lc;
  15567. this.smooth = !!isSmooth;
  15568. if (this.smooth && (lc = this.lastControlPointSet)) {
  15569. this.updateAnother(lc, lc == this.forward ? this.backward : this.forward);
  15570. }
  15571. return this;
  15572. },
  15573. /**
  15574. * @method isSmooth()
  15575. * @for kity.BezierPoint
  15576. * @description 判断贝塞尔点是否光滑
  15577. *
  15578. * @grammar isSmooth() => {boolean}
  15579. */
  15580. isSmooth: function() {
  15581. return this.smooth;
  15582. },
  15583. /**
  15584. * @method getVertex()
  15585. * @for kity.BezierPoint
  15586. * @description 获得当前贝塞尔点的顶点
  15587. *
  15588. * @grammar getVertex() => {kity.ShapePoint}
  15589. */
  15590. getVertex: function() {
  15591. return this.vertex.getPoint();
  15592. },
  15593. /**
  15594. * @method getForward()
  15595. * @for kity.BezierPoint
  15596. * @description 获得当前贝塞尔点的前方控制点
  15597. *
  15598. * @grammar getForward() => {kity.ShapePoint}
  15599. */
  15600. getForward: function() {
  15601. return this.forward.getPoint();
  15602. },
  15603. /**
  15604. * @method getBackward()
  15605. * @for kity.BezierPoint
  15606. * @description 获得当前贝塞尔点的后方控制点
  15607. *
  15608. * @grammar getBackward() => {kity.ShapePoint}
  15609. */
  15610. getBackward: function() {
  15611. return this.backward.getPoint();
  15612. },
  15613. /**
  15614. * @private
  15615. *
  15616. * 联动更新相关的贝塞尔曲线
  15617. */
  15618. update: function() {
  15619. if (!this.container) {
  15620. return this;
  15621. }
  15622. //新增参数 this, 把当前引起变化的点传递过去, 以便有需要的地方可以获取到引起变化的源
  15623. if (this.container.update) this.container.update(this);
  15624. }
  15625. });
  15626. return BezierPoint;
  15627. }
  15628. };
  15629. //src/graphic/box.js
  15630. /**
  15631. * @fileOverview
  15632. *
  15633. * 表示一个矩形区域
  15634. */
  15635. _p[25] = {
  15636. value: function(require, exports, module) {
  15637. /**
  15638. * @class kity.Box
  15639. * @description 表示一个矩形区域
  15640. */
  15641. var Box = _p.r(11).createClass("Box", {
  15642. /**
  15643. * @constructor
  15644. * @for kity.Box
  15645. *
  15646. * @grammar new kity.Box(x, y, width, height)
  15647. * @grammar new kity.Box(box)
  15648. *
  15649. * @param {Number} x|box.x 矩形区域的 x 坐标
  15650. * @param {Number} y|box.y 矩形区域的 y 坐标
  15651. * @param {Number} width|box.width 矩形区域的宽度
  15652. * @param {Number} height|box.height 矩形区域的高度
  15653. *
  15654. * @example
  15655. *
  15656. * ```js
  15657. * var box = new kity.Box(10, 20, 50, 50);
  15658. * var box2 = new kity.Box({x: 10, y: 20, width: 50, height: 50});
  15659. * ```
  15660. */
  15661. constructor: function(x, y, width, height) {
  15662. var box = arguments[0];
  15663. if (box && typeof box === "object") {
  15664. x = box.x;
  15665. y = box.y;
  15666. width = box.width;
  15667. height = box.height;
  15668. }
  15669. if (width < 0) {
  15670. x -= width = -width;
  15671. }
  15672. if (height < 0) {
  15673. y -= height = -height;
  15674. }
  15675. /**
  15676. * @property x
  15677. * @for kity.Box
  15678. * @type {Number}
  15679. * @readOnly
  15680. * @description 矩形区域的 x 坐标
  15681. */
  15682. this.x = x || 0;
  15683. /**
  15684. * @property y
  15685. * @for kity.Box
  15686. * @type {Number}
  15687. * @readOnly
  15688. * @description 矩形区域的 y 坐标
  15689. */
  15690. this.y = y || 0;
  15691. /**
  15692. * @property width
  15693. * @for kity.Box
  15694. * @type {Number}
  15695. * @readOnly
  15696. * @description 矩形区域的宽度
  15697. */
  15698. this.width = width || 0;
  15699. /**
  15700. * @property height
  15701. * @for kity.Box
  15702. * @type {Number}
  15703. * @readOnly
  15704. * @description 矩形区域的高度
  15705. */
  15706. this.height = height || 0;
  15707. /**
  15708. * @property left
  15709. * @for kity.Box
  15710. * @type {Number}
  15711. * @readOnly
  15712. * @description 矩形区域的最左侧坐标,等价于 x 的值
  15713. */
  15714. this.left = this.x;
  15715. /**
  15716. * @property right
  15717. * @for kity.Box
  15718. * @type {Number}
  15719. * @readOnly
  15720. * @description 矩形区域的最右侧坐标,等价于 x + width 的值
  15721. */
  15722. this.right = this.x + this.width;
  15723. /**
  15724. * @property top
  15725. * @for kity.Box
  15726. * @type {Number}
  15727. * @readOnly
  15728. * @description 矩形区域的最上侧坐标,等价于 y 的值
  15729. */
  15730. this.top = this.y;
  15731. /**
  15732. * @property bottom
  15733. * @for kity.Box
  15734. * @type {Number}
  15735. * @readOnly
  15736. * @description 矩形区域的最下侧坐标,等价于 y + height 的值
  15737. */
  15738. this.bottom = this.y + this.height;
  15739. /**
  15740. * @property cx
  15741. * @for kity.Box
  15742. * @type {Number}
  15743. * @readOnly
  15744. * @description 矩形区域的中心 x 坐标
  15745. */
  15746. this.cx = this.x + this.width / 2;
  15747. /**
  15748. * @property cy
  15749. * @for kity.Box
  15750. * @type {Number}
  15751. * @readOnly
  15752. * @description 矩形区域的中心 y 坐标
  15753. */
  15754. this.cy = this.y + this.height / 2;
  15755. },
  15756. /**
  15757. * @method getRangeX()
  15758. * @for kity.Box
  15759. * @description 获得矩形区域的 x 值域
  15760. *
  15761. * @grammar getRangeX() => {Number[]}
  15762. *
  15763. * @example
  15764. *
  15765. * var box = new kity.Box(10, 10, 30, 50);
  15766. * console.log(box.getRangeX()); // [10, 40]
  15767. */
  15768. getRangeX: function() {
  15769. return [ this.left, this.right ];
  15770. },
  15771. /**
  15772. * @method getRangeY()
  15773. * @for kity.Box
  15774. * @description 获得矩形区域的 y 值域
  15775. *
  15776. * @grammar getRangeY() => {Number[]}
  15777. *
  15778. * @example
  15779. *
  15780. * var box = new kity.Box(10, 10, 30, 50);
  15781. * console.log(box.getRangeY()); // [10, 60]
  15782. */
  15783. getRangeY: function() {
  15784. return [ this.top, this.bottom ];
  15785. },
  15786. /**
  15787. * @method merge()
  15788. * @for kity.Box
  15789. * @description 把当前矩形区域和指定的矩形区域合并,返回一个新的矩形区域(即包含两个源矩形区域的最小矩形区域)
  15790. *
  15791. * @grammar merge(another) => {kity.Box}
  15792. * @param {kity.Box} another 要合并的矩形区域
  15793. *
  15794. * @example
  15795. *
  15796. * ```js
  15797. * var box1 = new kity.Box(10, 10, 50, 50);
  15798. * var box2 = new kity.Box(30, 30, 50, 50);
  15799. * var box3 = box1.merge(box2);
  15800. * console.log(box3.valueOf()); // [10, 10, 70, 70]
  15801. * ```
  15802. */
  15803. merge: function(another) {
  15804. if (this.isEmpty()) {
  15805. return new Box(another.x, another.y, another.width, another.height);
  15806. }
  15807. var left = Math.min(this.left, another.left), right = Math.max(this.right, another.right), top = Math.min(this.top, another.top), bottom = Math.max(this.bottom, another.bottom);
  15808. return new Box(left, top, right - left, bottom - top);
  15809. },
  15810. /**
  15811. * @method intersect()
  15812. * @for kity.Box
  15813. * @description 求当前矩形区域和指定的矩形区域重叠的矩形区域
  15814. *
  15815. * @grammar intersect(another) => {kity.Box}
  15816. * @param {kity.Box} another 要求重叠的矩形区域
  15817. *
  15818. * @example
  15819. *
  15820. * ```js
  15821. * var box1 = new kity.Box(10, 10, 50, 50);
  15822. * var box2 = new kity.Box(30, 30, 50, 50);
  15823. * var box3 = box1.intersect(box2);
  15824. * console.log(box3.valueOf()); // [30, 30, 20, 20]
  15825. * ```
  15826. */
  15827. intersect: function(another) {
  15828. if (!another instanceof Box) {
  15829. another = new Box(another);
  15830. }
  15831. var left = Math.max(this.left, another.left), right = Math.min(this.right, another.right), top = Math.max(this.top, another.top), bottom = Math.min(this.bottom, another.bottom);
  15832. if (left > right || top > bottom) return new Box();
  15833. return new Box(left, top, right - left, bottom - top);
  15834. },
  15835. /**
  15836. * @method expand()
  15837. * @for kity.Box
  15838. * @description 扩展(或收缩)当前的盒子,返回新的盒子
  15839. *
  15840. * @param {Number} top
  15841. * 矩形区域的上边界往上扩展的值;如果是负数,则上边界往下收缩
  15842. *
  15843. * @param {Number} right
  15844. * [Optional] 矩形区域的右边界往右拓展的值;
  15845. * 如果是负数,则右边界往左收缩;
  15846. * 如果不设置该值,使用和 top 同样的值。
  15847. *
  15848. * @param {Number} bottom
  15849. * [Optional] 矩形区域的下边界往下拓展的值;
  15850. * 如果是负数,则下边界往上收缩;
  15851. * 如果不设置该值,使用和 top 同样的值。
  15852. *
  15853. * @param {Number} left
  15854. * [Optional] 矩形区域的左边界往左拓展的值;
  15855. * 如果是负数,则左边界往右收缩;
  15856. * 如果不设置该值,使用和 right 同样的值。
  15857. *
  15858. * @example
  15859. *
  15860. * ```js
  15861. * var box = new kity.Box(10, 10, 20, 20);
  15862. * var box1 = box.expand(10); // [0, 0, 40, 40]
  15863. * var box2 = box.expand(10, 20); // [0, -10, 40, 60]
  15864. * var box3 = box.expand(1, 2, 3, 4); // [9, 8, 24, 26]
  15865. * ```
  15866. */
  15867. expand: function(top, right, bottom, left) {
  15868. if (arguments.length < 1) {
  15869. return new Box(this);
  15870. }
  15871. if (arguments.length < 2) {
  15872. right = top;
  15873. }
  15874. if (arguments.length < 3) {
  15875. bottom = top;
  15876. }
  15877. if (arguments.length < 4) {
  15878. left = right;
  15879. }
  15880. var x = this.left - left, y = this.top - top, width = this.width + right, height = this.height + top;
  15881. return new Box(x, y, width, height);
  15882. },
  15883. /**
  15884. * @method valueOf()
  15885. * @for kity.Box
  15886. * @description 返回当前盒子的数组表示
  15887. *
  15888. * @grammar valueOf() => {Number[]}
  15889. *
  15890. * @example
  15891. *
  15892. * ```js
  15893. * var box = new kity.Box(0, 0, 200, 50);
  15894. * console.log(box.valueOf()); // [0, 0, 200, 50]
  15895. * ```
  15896. */
  15897. valueOf: function() {
  15898. return [ this.x, this.y, this.width, this.height ];
  15899. },
  15900. /**
  15901. * @method toString()
  15902. * @for kity.Box
  15903. * @description 返回当前盒子的字符串表示
  15904. *
  15905. * @grammar toString() => {String}
  15906. *
  15907. * @example
  15908. *
  15909. * ```js
  15910. * var box = new kity.Box(0, 0, 200, 50);
  15911. * console.log(box.toString()); // "0 0 200 50"
  15912. */
  15913. toString: function() {
  15914. return this.valueOf().join(" ");
  15915. },
  15916. /**
  15917. * @method isEmpty()
  15918. * @for kity.Box
  15919. * @description 判断当前盒子是否具有尺寸(面积大
  15920. *
  15921. * @grammar isEmpty() => {boolean}
  15922. *
  15923. * @example
  15924. * ```js
  15925. * var box = new kity.Box(0, 0, 0, 100000);
  15926. * console.log(box.isEmpty()); // true
  15927. * ```
  15928. */
  15929. isEmpty: function() {
  15930. return !this.width || !this.height;
  15931. }
  15932. });
  15933. /**
  15934. * @method parse()
  15935. * @static
  15936. * @for kity.Box
  15937. * @description 解析一个字符串或数组为 kity.Box 对象
  15938. *
  15939. * @grammar kity.Box.parse(any) => {kity.Box}
  15940. *
  15941. * @param {Number[]|String} any 要解析的字符串或数组
  15942. *
  15943. * @example
  15944. *
  15945. * ```js
  15946. * console.log(kity.Box.parse('0 0 100 200'));
  15947. * console.log(kity.Box.parse([0, 0, 100, 200]));
  15948. * ```
  15949. */
  15950. Box.parse = function(any) {
  15951. if (typeof any == "string") {
  15952. return Box.parse(any.split(/[\s,]+/).map(parseFloat));
  15953. }
  15954. if (any instanceof Array) {
  15955. return new Box(any[0], any[1], any[2], any[3]);
  15956. }
  15957. if ("x" in any) return new Box(any);
  15958. return null;
  15959. };
  15960. return Box;
  15961. }
  15962. };
  15963. //src/graphic/circle.js
  15964. /**
  15965. * @fileOverview
  15966. *
  15967. * 绘制和使用圆形
  15968. */
  15969. _p[26] = {
  15970. value: function(require, exports, module) {
  15971. /**
  15972. * @class kity.Circle
  15973. * @base kity.Ellipse
  15974. * @description 表示一个圆形
  15975. */
  15976. return _p.r(11).createClass("Circle", {
  15977. base: _p.r(32),
  15978. /**
  15979. * @constructor
  15980. * @for kity.Circle
  15981. *
  15982. * @grammar new kity.Circle(radius, cx, cy)
  15983. *
  15984. * @param {Number} radius 半径
  15985. * @param {Number} cx 圆心 x 坐标
  15986. * @param {Number} cy 圆心 y 坐标
  15987. */
  15988. constructor: function(radius, cx, cy) {
  15989. this.callBase(radius, radius, cx, cy);
  15990. },
  15991. /**
  15992. * @method
  15993. * @for kity.Circle
  15994. * @description 获取圆形的半径
  15995. *
  15996. * @grammar getRadius() => {Number}
  15997. */
  15998. getRadius: function() {
  15999. return this.getRadiusX();
  16000. },
  16001. /**
  16002. * @method
  16003. * @for kity.Circle
  16004. * @description 设置圆形的半径
  16005. *
  16006. * @grammar setRadius() => {this}
  16007. *
  16008. * @param {Number} radius 半径大小
  16009. */
  16010. setRadius: function(radius) {
  16011. return this.callBase(radius, radius);
  16012. }
  16013. });
  16014. }
  16015. };
  16016. //src/graphic/clip.js
  16017. /**
  16018. * @fileOverview
  16019. *
  16020. * 支持图形裁切
  16021. */
  16022. _p[27] = {
  16023. value: function(require, exports, module) {
  16024. var Class = _p.r(11);
  16025. var Shape = _p.r(60);
  16026. /**
  16027. * @class kity.Clip
  16028. * @base kity.Resource
  16029. * @mixins kity.ShapeContainer
  16030. *
  16031. * @description 创建图形裁切,用于裁切目标图形
  16032. */
  16033. var Clip = Class.createClass("Clip", {
  16034. base: Shape,
  16035. mixins: [ _p.r(61) ],
  16036. /**
  16037. * @constructor
  16038. * @for kity.Clip
  16039. *
  16040. * @grammar new kity.Clip(paper)
  16041. *
  16042. * @param {kity.Paper} paper 资源所属的文档
  16043. *
  16044. * @example
  16045. *
  16046. * ```js
  16047. * var circle = paper.put(new kity.Circle(100).fill('yellow'));
  16048. * var clip = new kity.Clip(paper);
  16049. * clip.addShape(new kity.Circle(100, 50, 0));
  16050. * clip.clip(circle);
  16051. * ```
  16052. */
  16053. constructor: function(paper) {
  16054. this.callBase("clipPath", paper);
  16055. },
  16056. /**
  16057. * @method clip()
  16058. * @for kity.Clip
  16059. * @description 将裁切应用到指定的图形上,应用之后,目标图形将显示与裁切形状重合的部分
  16060. *
  16061. * @grammar clip(shape) => {this}
  16062. *
  16063. * @param {kity.Shape} shape 要应用裁切的图形
  16064. */
  16065. clip: function(shape) {
  16066. shape.getNode().setAttribute("clip-path", this);
  16067. return this;
  16068. }
  16069. });
  16070. Class.extendClass(Shape, {
  16071. /**
  16072. * @method clipWidth()
  16073. * @for kity.Shape
  16074. *
  16075. * @grammar clipWidth(clip) => {this}
  16076. *
  16077. * @param {kity.Clip|kity.Shape} clip 要用于裁切当前图形的图形;
  16078. * 如果 clip 本身是一个裁切对象(kity.Clip 类型),则直接裁切;
  16079. * 否则将创建新的裁切包含给定的图形,然后对当前图形进行裁切
  16080. *
  16081. * @example
  16082. *
  16083. * ```js
  16084. * var circle = paper.put(new kity.Circle(100));
  16085. * var rect = paper.put(new kity.Rect(100, 100, -100, 0));
  16086. *
  16087. * circle.clipWidth(rect);
  16088. * ```
  16089. */
  16090. clipWith: function(clip) {
  16091. if (clip instanceof Shape) {
  16092. clip = new Clip(clip.getPaper()).addShape(clip);
  16093. }
  16094. clip.clip(this);
  16095. return this;
  16096. }
  16097. });
  16098. return Clip;
  16099. }
  16100. };
  16101. //src/graphic/color.js
  16102. /**
  16103. * @fileOverview
  16104. *
  16105. * 提供颜色支持
  16106. */
  16107. _p[28] = {
  16108. value: function(require, exports, module) {
  16109. var Utils = _p.r(12), StandardColor = _p.r(64), ColorUtils = {}, /**
  16110. * @class kity.Color
  16111. * @description 表示一个颜色
  16112. */
  16113. Color = _p.r(11).createClass("Color", {
  16114. /**
  16115. * @constructor
  16116. * @for kity.Color
  16117. *
  16118. * @grammar new kity.Color(r, g, b)
  16119. * @grammar new kity.Color(r, g, b, a)
  16120. * @grammar new kity.Color(colorString)
  16121. *
  16122. * @param {Number} r 红色分量,取值 0 - 255
  16123. * @param {Number} g 绿色分量,取值 0 - 255
  16124. * @param {Number} b 蓝色分量,取值 0 - 255
  16125. * @param {Number} a 透明度(可选),取值 0 - 100
  16126. * @param {String} colorString 一个代表颜色的字符串,可以是:
  16127. * 熟知颜色表:如 'red', 'yellow'
  16128. * HEX 表示:如 '#368', '#123456'
  16129. * RGB 表示:如 'RGB(200, 200, 0)', 'RGBA(200, 200, 200, .5)'
  16130. * HSL 表示:如 'HSL(100, 60%, 80%)', 'HSLA(100, 60%, 80%, .5)'
  16131. */
  16132. constructor: function() {
  16133. var colorValue = null;
  16134. //parse构造
  16135. if (typeof arguments[0] === "string") {
  16136. colorValue = ColorUtils.parseToValue(arguments[0]);
  16137. //解析失败
  16138. if (colorValue === null) {
  16139. colorValue = {
  16140. r: 0,
  16141. g: 0,
  16142. b: 0,
  16143. h: 0,
  16144. s: 0,
  16145. l: 0,
  16146. a: 1
  16147. };
  16148. }
  16149. } else {
  16150. colorValue = {
  16151. r: arguments[0] | 0,
  16152. g: arguments[1] | 0,
  16153. b: arguments[2] | 0,
  16154. //alpha 默认为1
  16155. a: arguments[3] === undefined ? 1 : parseFloat(arguments[3])
  16156. };
  16157. colorValue = ColorUtils.overflowFormat(colorValue);
  16158. //获取hsl分量
  16159. colorValue = Utils.extend(colorValue, ColorUtils.rgbValueToHslValue(colorValue));
  16160. }
  16161. this._color = colorValue;
  16162. },
  16163. /**
  16164. * @method set()
  16165. * @for kity.Color
  16166. *
  16167. * @description 设置当前颜色某个分量的值
  16168. *
  16169. * @grammar set(name, value) => {this}
  16170. *
  16171. * @param {string} name 要设置的颜色通道的名称
  16172. * r: 红色(Red),取值范围 [0, 255]
  16173. * g: 绿色(Green),取值范围 [0, 255]
  16174. * b: 蓝色(Blue),取值范围 [0, 255]
  16175. * a: 透明度(Alpha),取值范围 [0, 1]
  16176. * h: 色环角度(Hue),取值范围 [0, 359]
  16177. * s: 饱和度(Saturation),取值范围 [0, 100]
  16178. * l: 亮度(Lightness),取值范围 [0, 100]
  16179. * r、g、b 值和 h、s、l 值会联动修改
  16180. * @param {number} value 要设置的值
  16181. */
  16182. set: function(name, value) {
  16183. var values = null;
  16184. //设置的值非法
  16185. if (!Color._MAX_VALUE[name]) {
  16186. throw new Error("Color set(): Illegal parameter");
  16187. }
  16188. if (name !== "a") {
  16189. value = Math.floor(value);
  16190. }
  16191. if (name == "h") {
  16192. value = (value + 360) % 360;
  16193. }
  16194. this._color[name] = Math.max(Color._MIN_VALUE[name], Math.min(Color._MAX_VALUE[name], value));
  16195. if ("rgb".indexOf(name) !== -1) {
  16196. this._color = Utils.extend(this._color, ColorUtils.rgbValueToHslValue(this._color));
  16197. } else if ("hsl".indexOf(name) !== -1) {
  16198. this._color = Utils.extend(this._color, ColorUtils.hslValueToRGBValue(this._color));
  16199. }
  16200. return this;
  16201. },
  16202. /**
  16203. * @method inc()
  16204. *
  16205. * @description 返回新的颜色,表示当前颜色增加指定通道的值之后的颜色
  16206. *
  16207. * @grammar inc(name, value) => {this}
  16208. *
  16209. * @param {string} name 要增加的通道的名称,具体含义请查看 set 方法
  16210. * @param {number} value 增量值
  16211. */
  16212. inc: function(name, value) {
  16213. value = this.get(name) + value;
  16214. if (name == "h") {
  16215. value = (value + 360) % 360;
  16216. } else {
  16217. value = Math.min(Color._MAX_VALUE[name], value);
  16218. value = Math.max(Color._MIN_VALUE[name], value);
  16219. }
  16220. return this.clone().set(name, value);
  16221. },
  16222. /**
  16223. * @method dec()
  16224. * @for kity.Color
  16225. *
  16226. * @description 返回新的颜色,表示当前颜色减少指定通道的值之后的颜色
  16227. *
  16228. * @grammar dec(name, value) => {this}
  16229. *
  16230. * @param {string} name 要减少值的通道的名称,具体含义请查看 set 方法
  16231. * @param {number} value 减量值
  16232. */
  16233. dec: function(name, value) {
  16234. return this.inc(name, -value);
  16235. },
  16236. /**
  16237. * @method clone()
  16238. * @for kity.Color
  16239. *
  16240. * @description 返回当前颜色的一个拷贝
  16241. *
  16242. * @grammar clone() => {kity.Color}
  16243. */
  16244. clone: function() {
  16245. return new Color(this.toRGBA());
  16246. },
  16247. /**
  16248. * @method get()
  16249. * @for kity.Color
  16250. *
  16251. * @description 返回当前颜色指定的分量
  16252. *
  16253. * @grammar get() => {number}
  16254. */
  16255. get: function(name) {
  16256. if (!Color._MAX_VALUE[name]) {
  16257. return null;
  16258. }
  16259. return this._color[name];
  16260. },
  16261. getValues: function() {
  16262. return Utils.clone(this._color);
  16263. },
  16264. /**
  16265. * @method valueOf()
  16266. * @for kity.Color
  16267. *
  16268. * @description 返回当前颜色的一个字面量表示
  16269. *
  16270. * @return {plain} 颜色字面量,其结构为:
  16271. * {
  16272. * r: 0,
  16273. * g: 0,
  16274. * b: 0,
  16275. * a: 0,
  16276. * h: 0,
  16277. * s: 0,
  16278. * l: 0
  16279. * }
  16280. */
  16281. valueOf: function() {
  16282. return this.getValues();
  16283. },
  16284. /**
  16285. * @method toRGB()
  16286. * @for kity.Color
  16287. *
  16288. * @description 返回当前颜色的 RGB 表示,如果颜色有透明度,将抛弃透明度属性(想要保留请使用 toRGBA())方法。
  16289. *
  16290. * @grammar toRGB() => {string}
  16291. */
  16292. toRGB: function() {
  16293. return ColorUtils.toString(this._color, "rgb");
  16294. },
  16295. /**
  16296. * @method toRGBA()
  16297. * @for kity.Color
  16298. *
  16299. * @description 返回当前颜色的 RGBA 表示
  16300. *
  16301. * @grammar toRGBA() => {string}
  16302. */
  16303. toRGBA: function() {
  16304. return ColorUtils.toString(this._color, "rgba");
  16305. },
  16306. /**
  16307. * @method toHEX()
  16308. * @for kity.Color
  16309. *
  16310. * @description 返回当前颜色的 HEX 表示,如果颜色有透明度,将抛弃透明度属性(想要保留请使用 toRGBA())方法。
  16311. *
  16312. * @grammar toHEX() => {string}
  16313. */
  16314. toHEX: function() {
  16315. return ColorUtils.toString(this._color, "hex");
  16316. },
  16317. /**
  16318. * @method toHSL()
  16319. * @for kity.Color
  16320. *
  16321. * @description 返回当前颜色的 HSL 表示,如果颜色有透明度,将抛弃透明度属性(想要保留请使用 toHSLA())方法。
  16322. *
  16323. * @grammar toHSL() => {string}
  16324. */
  16325. toHSL: function() {
  16326. return ColorUtils.toString(this._color, "hsl");
  16327. },
  16328. /**
  16329. * @method toHSLA()
  16330. * @for kity.Color
  16331. *
  16332. * @description 返回当前颜色的 HSLA 表示
  16333. *
  16334. * @grammar toHSLA() => {string}
  16335. */
  16336. toHSLA: function() {
  16337. return ColorUtils.toString(this._color, "hsla");
  16338. },
  16339. /**
  16340. * @method toString()
  16341. * @for kity.Color
  16342. *
  16343. * @description 返回当前颜色的 RGB 或 RGBA 表示,如果颜色有透明度,将使用 RGBA 形式,否则是 RGB 形式
  16344. * @grammar toString() => {string}
  16345. */
  16346. toString: function() {
  16347. if (this._color.a === 1) {
  16348. return this.toRGB();
  16349. }
  16350. return this.toRGBA();
  16351. }
  16352. });
  16353. //Color 静态方法
  16354. Utils.extend(Color, {
  16355. //各分量可表示的最大值
  16356. _MAX_VALUE: {
  16357. r: 255,
  16358. g: 255,
  16359. b: 255,
  16360. h: 360,
  16361. s: 100,
  16362. l: 100,
  16363. a: 1
  16364. },
  16365. //各分量最小值
  16366. _MIN_VALUE: {
  16367. r: 0,
  16368. g: 0,
  16369. b: 0,
  16370. h: 0,
  16371. s: 0,
  16372. l: 0,
  16373. a: 0
  16374. },
  16375. //分量常量
  16376. R: "r",
  16377. G: "g",
  16378. B: "b",
  16379. H: "h",
  16380. S: "s",
  16381. L: "l",
  16382. A: "a",
  16383. /**
  16384. * @method parse()
  16385. * @static
  16386. * @for kity.Color
  16387. *
  16388. * @description 解析一个颜色字符串为 kity.Color 对象
  16389. *
  16390. * @grammar kity.Color.parse(valStr)
  16391. *
  16392. * @param {string} valStr 一个代表颜色的字符串,可以是:
  16393. * 熟知颜色表:如 'red', 'yellow'
  16394. * HEX 表示:如 '#368', '#123456'
  16395. * RGB 表示:如 'RGB(200, 200, 0)', 'RGBA(200, 200, 200, .5)'
  16396. * HSL 表示:如 'HSL(100, 60%, 80%)', 'HSLA(100, 60%, 80%, .5)'
  16397. */
  16398. parse: function(valStr) {
  16399. var rgbValue;
  16400. if (Utils.isString(valStr)) {
  16401. rgbValue = ColorUtils.parseToValue(valStr);
  16402. }
  16403. if (Utils.isObject(valStr) && "r" in valStr) {
  16404. rgbValue = valStr;
  16405. }
  16406. //解析失败, 返回一个默认color实例
  16407. if (rgbValue === null) {
  16408. return new Color();
  16409. }
  16410. return new Color(rgbValue.r, rgbValue.g, rgbValue.b, rgbValue.a);
  16411. },
  16412. /**
  16413. * @method createHSL()
  16414. * @for kity.Color
  16415. * @static
  16416. *
  16417. * @description 创建一个 HSL 颜色
  16418. *
  16419. * @grammar kity.Color.createHSL(h, s, l) => {kity.Color}
  16420. *
  16421. * @param {number} h 色环(Hue)分量值,取值范围 [0, 359]
  16422. * @param {number} s 饱和度(Saturation)分量值,取值范围 [0, 100]
  16423. * @param {number} l 亮度(Lighteness)分量值,取值范围 [0, 100]
  16424. */
  16425. createHSL: function(h, s, l) {
  16426. return Color.createHSLA(h, s, l, 1);
  16427. },
  16428. /**
  16429. * @method createHSLA()
  16430. * @for kity.Color
  16431. * @static
  16432. *
  16433. * @description 创建一个 HSLA 颜色
  16434. *
  16435. * @grammar kity.Color.createHSLA(h, s, l, a) => {kity.Color}
  16436. *
  16437. * @param {number} h 色环(Hue)分量值,取值范围 [0, 359]
  16438. * @param {number} s 饱和度(Saturation)分量值,取值范围 [0, 100]
  16439. * @param {number} l 亮度(Lighteness)分量值,取值范围 [0, 100]
  16440. * @param {number} a 透明度(Alpha)分量值,取值范围 [0, 1]
  16441. */
  16442. createHSLA: function(h, s, l, a) {
  16443. var colorValue = null;
  16444. s += "%";
  16445. l += "%";
  16446. colorValue = [ "hsla(" + h, s, l, a + ")" ];
  16447. return Color.parse(colorValue.join(", "));
  16448. },
  16449. /**
  16450. * @method createRGB()
  16451. * @for kity.Color
  16452. * @static
  16453. *
  16454. * @description 创建一个 RGB 颜色
  16455. *
  16456. * @grammar kity.Color.createRGB(r, g, b) => {kity.Color}
  16457. *
  16458. * @param {number} r 红色(Red)分量值,取值范围 [0, 255]
  16459. * @param {number} g 绿色(Green)分量值,取值范围 [0, 255]
  16460. * @param {number} b 蓝色(Blue)分量值,取值范围 [0, 255]
  16461. */
  16462. createRGB: function(r, g, b) {
  16463. return Color.createRGBA(r, g, b, 1);
  16464. },
  16465. /**
  16466. * @method createRGBA()
  16467. * @for kity.Color
  16468. * @static
  16469. *
  16470. * @description 创建一个 RGBA 颜色
  16471. *
  16472. * @grammar kity.Color.createRGBA(r, g, b, a) => {kity.Color}
  16473. *
  16474. * @param {number} r 红色(Red)分量值,取值范围 [0, 255]
  16475. * @param {number} g 绿色(Green)分量值,取值范围 [0, 255]
  16476. * @param {number} b 蓝色(Blue)分量值,取值范围 [0, 255]
  16477. * @param {number} a 透明度(Alpha)分量值,取值范围 [0, 1]
  16478. */
  16479. createRGBA: function(r, g, b, a) {
  16480. return new Color(r, g, b, a);
  16481. }
  16482. });
  16483. //内部工具对象
  16484. Utils.extend(ColorUtils, {
  16485. parseToValue: function(valStr) {
  16486. var rgbaValue = {};
  16487. /* 优先检测在调色板中是否有对应的颜色 */
  16488. valStr = StandardColor.EXTEND_STANDARD[valStr] || StandardColor.COLOR_STANDARD[valStr] || valStr;
  16489. /* 颜色转换 */
  16490. //hex格式
  16491. if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(valStr)) {
  16492. rgbaValue = ColorUtils.hexToValue(valStr);
  16493. } else if (/^(rgba?)/i.test(valStr)) {
  16494. rgbaValue = ColorUtils.rgbaToValue(valStr);
  16495. } else if (/^(hsla?)/i.test(valStr)) {
  16496. rgbaValue = ColorUtils.hslaToValue(valStr);
  16497. } else {
  16498. return null;
  16499. }
  16500. return ColorUtils.overflowFormat(rgbaValue);
  16501. },
  16502. hexToValue: function(hexStr) {
  16503. var result = {}, keys = [ "r", "g", "b" ];
  16504. if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(hexStr)) {
  16505. hexStr = RegExp.$1.split("");
  16506. Utils.each(keys, function(key, index) {
  16507. if (hexStr.length === 3) {
  16508. result[key] = ColorUtils.toNumber(hexStr[index] + hexStr[index]);
  16509. } else {
  16510. result[key] = ColorUtils.toNumber(hexStr[index * 2] + hexStr[index * 2 + 1]);
  16511. }
  16512. });
  16513. //转换出hsl值
  16514. result = Utils.extend(result, ColorUtils.rgbValueToHslValue(result));
  16515. result.a = 1;
  16516. return result;
  16517. }
  16518. return null;
  16519. },
  16520. rgbaToValue: function(rgbaStr) {
  16521. var result = {}, hasAlpha = false, keys = [ "r", "g", "b" ];
  16522. if (/^(rgba?)/i.test(rgbaStr)) {
  16523. hasAlpha = RegExp.$1.length === 4;
  16524. rgbaStr = rgbaStr.replace(/^rgba?/i, "").replace(/\s+/g, "").replace(/[^0-9,.]/g, "").split(",");
  16525. Utils.each(keys, function(key, index) {
  16526. result[key] = rgbaStr[index] | 0;
  16527. });
  16528. //转换出hsl值
  16529. result = Utils.extend(result, ColorUtils.rgbValueToHslValue(result));
  16530. result.a = hasAlpha ? parseFloat(rgbaStr[3]) : 1;
  16531. return result;
  16532. }
  16533. return null;
  16534. },
  16535. hslaToValue: function(hslaStr) {
  16536. var result = {}, hasAlpha = false;
  16537. if (/^(hsla?)/i.test(hslaStr)) {
  16538. hasAlpha = RegExp.$1.length === 4;
  16539. hslaStr = hslaStr.replace(/^hsla?/i, "").replace(/\s+/g, "").replace(/[^0-9,.]/g, "").split(",");
  16540. //记录hsl值
  16541. result.h = hslaStr[0] | 0;
  16542. result.s = hslaStr[1] | 0;
  16543. result.l = hslaStr[2] | 0;
  16544. //转换出rgb值
  16545. result = Utils.extend(result, ColorUtils.hslValueToRGBValue(result));
  16546. //hsl值转换为rgb值
  16547. result = ColorUtils.hslValueToRGBValue(result);
  16548. result.a = hasAlpha ? parseFloat(hslaStr[3]) : 1;
  16549. return result;
  16550. }
  16551. return null;
  16552. },
  16553. //hsl值对象转换为rgb值对象
  16554. hslValueToRGBValue: function(hslValue) {
  16555. function trans(v1, v2, vH) {
  16556. if (vH < 0) {
  16557. vH += 1;
  16558. } else if (vH > 1) {
  16559. vH -= 1;
  16560. }
  16561. if (6 * vH < 1) {
  16562. return v1 + (v2 - v1) * 6 * vH;
  16563. } else if (2 * vH < 1) {
  16564. return v2;
  16565. } else if (3 * vH < 2) {
  16566. return v1 + (v2 - v1) * ((2 / 3 - vH) * 6);
  16567. }
  16568. return v1;
  16569. }
  16570. var q = null, p = null, result = {};
  16571. hslValue = Utils.extend({}, hslValue);
  16572. hslValue.h = hslValue.h / 360;
  16573. hslValue.s = hslValue.s / 100;
  16574. hslValue.l = hslValue.l / 100;
  16575. //分量计算
  16576. if (hslValue.s === 0) {
  16577. result.r = result.g = result.b = hslValue.l;
  16578. } else {
  16579. if (hslValue.l < .5) {
  16580. q = hslValue.l * (1 + hslValue.s);
  16581. } else {
  16582. q = hslValue.l + hslValue.s - hslValue.l * hslValue.s;
  16583. }
  16584. p = 2 * hslValue.l - q;
  16585. result.r = trans(p, q, hslValue.h + 1 / 3);
  16586. result.g = trans(p, q, hslValue.h);
  16587. result.b = trans(p, q, hslValue.h - 1 / 3);
  16588. }
  16589. result.r = Math.min(Math.round(result.r * 255), 255);
  16590. result.g = Math.min(Math.round(result.g * 255), 255);
  16591. result.b = Math.min(Math.round(result.b * 255), 255);
  16592. return result;
  16593. },
  16594. //rgb值对象转换为hsl值对象
  16595. rgbValueToHslValue: function(rgbValue) {
  16596. var max = null, min = null, result = {};
  16597. rgbValue = Utils.extend({}, rgbValue);
  16598. rgbValue.r = rgbValue.r / 255;
  16599. rgbValue.g = rgbValue.g / 255;
  16600. rgbValue.b = rgbValue.b / 255;
  16601. max = Math.max(rgbValue.r, rgbValue.g, rgbValue.b);
  16602. min = Math.min(rgbValue.r, rgbValue.g, rgbValue.b);
  16603. //h分量计算
  16604. if (max === min) {
  16605. result.h = 0;
  16606. } else if (max === rgbValue.r) {
  16607. if (rgbValue.g >= rgbValue.b) {
  16608. result.h = 60 * (rgbValue.g - rgbValue.b) / (max - min);
  16609. } else {
  16610. result.h = 60 * (rgbValue.g - rgbValue.b) / (max - min) + 360;
  16611. }
  16612. } else if (max === rgbValue.g) {
  16613. result.h = 60 * (rgbValue.b - rgbValue.r) / (max - min) + 120;
  16614. } else if (max === rgbValue.b) {
  16615. result.h = 60 * (rgbValue.r - rgbValue.g) / (max - min) + 240;
  16616. }
  16617. //l分量计算
  16618. result.l = (max + min) / 2;
  16619. //s分量计算
  16620. if (result.l === 0 || max === min) {
  16621. result.s = 0;
  16622. } else if (result.l > 0 && result.l <= .5) {
  16623. result.s = (max - min) / (max + min);
  16624. } else {
  16625. result.s = (max - min) / (2 - max - min);
  16626. }
  16627. //格式化hsl结果
  16628. result.h = Math.round(result.h);
  16629. result.s = Math.round(result.s * 100);
  16630. result.l = Math.round(result.l * 100);
  16631. return result;
  16632. },
  16633. toString: function(colorValue, type) {
  16634. var vals = [];
  16635. colorValue = Utils.extend({}, colorValue);
  16636. if (type.indexOf("hsl") !== -1) {
  16637. colorValue.s += "%";
  16638. colorValue.l += "%";
  16639. }
  16640. if (type !== "hex") {
  16641. Utils.each(type.split(""), function(key) {
  16642. vals.push(colorValue[key]);
  16643. });
  16644. return (type + "(" + vals.join(", ") + ")").toLowerCase();
  16645. } else {
  16646. vals.push(ColorUtils.toHexValue(+colorValue.r));
  16647. vals.push(ColorUtils.toHexValue(+colorValue.g));
  16648. vals.push(ColorUtils.toHexValue(+colorValue.b));
  16649. return ("#" + vals.join("")).toLowerCase();
  16650. }
  16651. },
  16652. //16进制的2个数字转化为10进制, 如果转化失败, 返回0
  16653. toNumber: function(value) {
  16654. return Number("0x" + value) | 0;
  16655. },
  16656. toHexValue: function(value) {
  16657. var result = value.toString(16);
  16658. return result.length === 1 ? "0" + result : result;
  16659. },
  16660. //溢出控制
  16661. overflowFormat: function(value) {
  16662. var tmpValue = Utils.extend({}, value), keys = "rgba";
  16663. Utils.each(keys.split(""), function(key) {
  16664. if (!tmpValue.hasOwnProperty(key)) {
  16665. return;
  16666. }
  16667. //上溢出
  16668. tmpValue[key] = Math.min(Color._MAX_VALUE[key], tmpValue[key]);
  16669. //下溢出
  16670. tmpValue[key] = Math.max(Color._MIN_VALUE[key], tmpValue[key]);
  16671. });
  16672. return tmpValue;
  16673. }
  16674. });
  16675. return Color;
  16676. }
  16677. };
  16678. //src/graphic/container.js
  16679. _p[29] = {
  16680. value: function(require, exports, module) {
  16681. function itemRemove() {
  16682. this.container.removeItem(this);
  16683. return this;
  16684. }
  16685. return _p.r(11).createClass("Container", {
  16686. getItems: function() {
  16687. return this.items || (this.items = []);
  16688. },
  16689. getItem: function(index) {
  16690. return this.getItems()[index];
  16691. },
  16692. getFirstItem: function() {
  16693. return this.getItem(0);
  16694. },
  16695. getLastItem: function() {
  16696. return this.getItem(this.getItems().length - 1);
  16697. },
  16698. indexOf: function(item) {
  16699. return this.getItems().indexOf(item);
  16700. },
  16701. eachItem: function(fn) {
  16702. var items = this.getItems(), length = items.length, i;
  16703. for (i = 0; i < length; i++) {
  16704. fn.call(this, i, items[i]);
  16705. }
  16706. return this;
  16707. },
  16708. addItem: function(item, pos, noEvent) {
  16709. var items = this.getItems(), length = items.length;
  16710. if (~items.indexOf(item)) {
  16711. return this;
  16712. }
  16713. if (!(pos >= 0 && pos < length)) {
  16714. pos = length;
  16715. }
  16716. items.splice(pos, 0, item);
  16717. if (typeof item === "object") {
  16718. item.container = this;
  16719. item.remove = itemRemove;
  16720. }
  16721. this.handleAdd(item, pos);
  16722. if (!noEvent) {
  16723. this.onContainerChanged("add", [ item ]);
  16724. }
  16725. return this;
  16726. },
  16727. addItems: function(items) {
  16728. for (var i = 0, l = items.length; i < l; i++) {
  16729. this.addItem(items[i], -1, true);
  16730. }
  16731. this.onContainerChanged("add", items);
  16732. return this;
  16733. },
  16734. setItems: function(items) {
  16735. return this.clear().addItems(items);
  16736. },
  16737. appendItem: function(item) {
  16738. return this.addItem(item);
  16739. },
  16740. prependItem: function(item) {
  16741. return this.addItem(item, 0);
  16742. },
  16743. removeItem: function(pos, noEvent) {
  16744. if (typeof pos !== "number") {
  16745. return this.removeItem(this.indexOf(pos));
  16746. }
  16747. var items = this.getItems(), length = items.length, item = items[pos];
  16748. if (item === undefined) {
  16749. return this;
  16750. }
  16751. items.splice(pos, 1);
  16752. if (item.container) {
  16753. delete item.container;
  16754. }
  16755. if (item.remove) {
  16756. delete item.remove;
  16757. }
  16758. this.handleRemove(item, pos);
  16759. if (!noEvent) {
  16760. this.onContainerChanged("remove", [ item ]);
  16761. }
  16762. return this;
  16763. },
  16764. clear: function() {
  16765. var removed = [];
  16766. var item;
  16767. while (item = this.getFirstItem()) {
  16768. removed.push(item);
  16769. this.removeItem(0, true);
  16770. }
  16771. this.onContainerChanged("remove", removed);
  16772. return this;
  16773. },
  16774. onContainerChanged: function(type, items) {},
  16775. handleAdd: function(item, index) {},
  16776. handleRemove: function(item, index) {}
  16777. });
  16778. }
  16779. };
  16780. //src/graphic/curve.js
  16781. /*
  16782. * 曲线
  16783. * */
  16784. _p[30] = {
  16785. value: function(require, exports, module) {
  16786. var Utils = _p.r(12), CurveUtil = {
  16787. /*
  16788. * 获取由两个以上的点组成的曲线的平移线
  16789. * @param points 曲线上的点的集合, 集合中的点的数量必须大于2
  16790. * @return 平移线数组
  16791. */
  16792. getCurvePanLines: function(points, smoothFactor) {
  16793. //计算原始点的中点坐标
  16794. var centerPoints = CurveUtil.getCenterPoints(points), //注意:计算中点连线的中点坐标, 得出平移线
  16795. panLines = CurveUtil.getPanLine(points.length, centerPoints);
  16796. //平移线移动到顶点
  16797. return CurveUtil.getMovedPanLines(points, panLines, smoothFactor);
  16798. },
  16799. /*
  16800. * 计算给定点集合的连线的中点
  16801. * @param points
  16802. */
  16803. getCenterPoints: function(points) {
  16804. var centerPoints = {}, key = null;
  16805. for (var i = 0, j = 0, len = points.length; i < len; i++) {
  16806. //j是下一个点的索引
  16807. j = i === len - 1 ? 0 : i + 1;
  16808. key = i + "," + j;
  16809. //计算中点坐标
  16810. centerPoints[key] = {
  16811. x: (points[i].x + points[j].y) / 2,
  16812. y: (points[i].x + points[j].y) / 2
  16813. };
  16814. }
  16815. return centerPoints;
  16816. },
  16817. /*
  16818. * 对getCenterPoints()接口获取到的数据做处理, 计算出各个顶点对应的平移线数据
  16819. * @param length 集合中点的个数
  16820. * @param points 点集合, 该集合应该是getCenterPoints()接口返回的数据
  16821. */
  16822. getPanLine: function(length, points) {
  16823. var result = {}, //顶点索引
  16824. pointIndex = null;
  16825. for (var i = 0, j; i < length; i++) {
  16826. var point1 = null, point2 = null;
  16827. //计算当前点
  16828. j = (i + 1) % length;
  16829. //保存当前处理的顶点索引
  16830. pointIndex = j;
  16831. point1 = points[i + "," + j];
  16832. //计算下一个点
  16833. i = j;
  16834. j = (i + 1) % length;
  16835. point2 = points[i + "," + j];
  16836. result[pointIndex] = {
  16837. points: [ {
  16838. x: point1.x,
  16839. y: point1.y
  16840. }, {
  16841. x: point2.x,
  16842. y: point2.y
  16843. } ],
  16844. center: {
  16845. x: (point1.x + point2.x) / 2,
  16846. y: (point1.y + point2.y) / 2
  16847. }
  16848. };
  16849. //还原i值
  16850. i = (pointIndex + length - 1) % length;
  16851. }
  16852. return result;
  16853. },
  16854. /*
  16855. * 计算平移线移动到顶点后的位置
  16856. * @param points 顶点集合
  16857. * @param panLines 平移线集合
  16858. */
  16859. getMovedPanLines: function(points, panLines, smoothFactor) {
  16860. var result = {};
  16861. Utils.each(points, function(point, index) {
  16862. //当前平移线
  16863. var currentPanLine = panLines[index], //平移线中点
  16864. center = currentPanLine.center, //移动距离
  16865. distance = {
  16866. x: center.x - point.x,
  16867. y: center.y - point.y
  16868. };
  16869. var currentResult = result[index] = {
  16870. points: [],
  16871. center: {
  16872. x: point.x,
  16873. y: point.y
  16874. }
  16875. };
  16876. //计算控制点到顶点的距离, 并且应用平滑系数到距离上
  16877. Utils.each(currentPanLine.points, function(controlPoint, index) {
  16878. var moved = {
  16879. x: controlPoint.x - distance.x,
  16880. y: controlPoint.y - distance.y
  16881. };
  16882. var vertex = currentResult.center;
  16883. var dx = moved.x - vertex.x;
  16884. var dy = moved.y - vertex.y;
  16885. moved.x = vertex.x + smoothFactor * dx;
  16886. moved.y = vertex.y + smoothFactor * dy;
  16887. currentResult.points.push(moved);
  16888. });
  16889. });
  16890. return result;
  16891. }
  16892. };
  16893. return _p.r(11).createClass("Curve", {
  16894. base: _p.r(46),
  16895. mixins: [ _p.r(51) ],
  16896. constructor: function(points, isColse) {
  16897. this.callBase();
  16898. this.setPoints(points || []);
  16899. this.closeState = !!isColse;
  16900. this.changeable = true;
  16901. this.smoothFactor = 1;
  16902. this.update();
  16903. },
  16904. //当点集合发生变化时采取的动作
  16905. onContainerChanged: function() {
  16906. if (this.changeable) {
  16907. this.update();
  16908. }
  16909. },
  16910. setSmoothFactor: function(factor) {
  16911. this.smoothFactor = factor < 0 ? 0 : factor;
  16912. this.update();
  16913. return this;
  16914. },
  16915. getSmoothFactor: function() {
  16916. return this.smoothFactor;
  16917. },
  16918. update: function() {
  16919. var points = this.getPoints(), withControlPoints = null, drawer = this.getDrawer(), curPoint = null, curControlPoint = null, prevControlPoint = null;
  16920. drawer.clear();
  16921. if (points.length === 0) {
  16922. return this;
  16923. } else {
  16924. drawer.moveTo(points[0]);
  16925. }
  16926. if (points.length === 1) {
  16927. return this;
  16928. }
  16929. if (points.length === 2) {
  16930. drawer.lineTo(points[1]);
  16931. return this;
  16932. }
  16933. //获取已转换过后的带控制点的所有点
  16934. withControlPoints = CurveUtil.getCurvePanLines(points, this.getSmoothFactor());
  16935. for (var i = 1, len = points.length; i < len; i++) {
  16936. //当前顶点
  16937. curPoint = withControlPoints[i].center;
  16938. //当前控制点
  16939. if (this.closeState || i != len - 1) {
  16940. curControlPoint = withControlPoints[i].points[0];
  16941. } else {
  16942. //非闭合状态下最后一个点的处理
  16943. curControlPoint = withControlPoints[i].center;
  16944. }
  16945. if (this.closeState || i != 1) {
  16946. prevControlPoint = withControlPoints[i - 1].points[1];
  16947. } else {
  16948. //非闭合状态下第一个点的处理
  16949. prevControlPoint = withControlPoints[i - 1].center;
  16950. }
  16951. drawer.bezierTo(prevControlPoint.x, prevControlPoint.y, curControlPoint.x, curControlPoint.y, curPoint.x, curPoint.y);
  16952. }
  16953. //处理闭合
  16954. if (this.closeState) {
  16955. curPoint = withControlPoints[0].center;
  16956. curControlPoint = withControlPoints[0].points[0];
  16957. prevControlPoint = withControlPoints[points.length - 1].points[1];
  16958. drawer.bezierTo(prevControlPoint.x, prevControlPoint.y, curControlPoint.x, curControlPoint.y, curPoint.x, curPoint.y);
  16959. }
  16960. return this;
  16961. },
  16962. close: function() {
  16963. this.closeState = true;
  16964. return this.update();
  16965. },
  16966. open: function() {
  16967. this.closeState = false;
  16968. return this.update();
  16969. },
  16970. isClose: function() {
  16971. return !!this.closeState;
  16972. }
  16973. });
  16974. }
  16975. };
  16976. //src/graphic/data.js
  16977. _p[31] = {
  16978. value: function(require, exports, module) {
  16979. return _p.r(11).createClass("Data", {
  16980. constructor: function() {
  16981. this._data = {};
  16982. },
  16983. setData: function(name, value) {
  16984. this._data[name] = value;
  16985. return this;
  16986. },
  16987. getData: function(name) {
  16988. return this._data[name];
  16989. },
  16990. removeData: function(name) {
  16991. delete this._data[name];
  16992. return this;
  16993. }
  16994. });
  16995. }
  16996. };
  16997. //src/graphic/ellipse.js
  16998. _p[32] = {
  16999. value: function(require, exports, module) {
  17000. var Utils = _p.r(12), Point = _p.r(50);
  17001. return _p.r(11).createClass("Ellipse", {
  17002. base: _p.r(46),
  17003. constructor: function(rx, ry, cx, cy) {
  17004. this.callBase();
  17005. this.rx = rx || 0;
  17006. this.ry = ry || 0;
  17007. this.cx = cx || 0;
  17008. this.cy = cy || 0;
  17009. this.update();
  17010. },
  17011. update: function() {
  17012. var rx = this.rx, ry = this.ry, x1 = this.cx + rx, x2 = this.cx - rx, y = this.cy;
  17013. var drawer = this.getDrawer();
  17014. drawer.clear();
  17015. drawer.moveTo(x1, y);
  17016. drawer.arcTo(rx, ry, 0, 1, 1, x2, y);
  17017. drawer.arcTo(rx, ry, 0, 1, 1, x1, y);
  17018. return this;
  17019. },
  17020. getRadius: function() {
  17021. return {
  17022. x: this.rx,
  17023. y: this.ry
  17024. };
  17025. },
  17026. getRadiusX: function() {
  17027. return this.rx;
  17028. },
  17029. getRadiusY: function() {
  17030. return this.ry;
  17031. },
  17032. getCenter: function() {
  17033. return new Point(this.cx, this.cy);
  17034. },
  17035. getCenterX: function() {
  17036. return this.cx;
  17037. },
  17038. getCenterY: function() {
  17039. return this.cy;
  17040. },
  17041. setRadius: function(rx, ry) {
  17042. this.rx = rx;
  17043. this.ry = ry;
  17044. return this.update();
  17045. },
  17046. setRadiusX: function(rx) {
  17047. this.rx = rx;
  17048. return this.update();
  17049. },
  17050. setRadiusY: function(ry) {
  17051. this.ry = ry;
  17052. return this.update();
  17053. },
  17054. setCenter: function(cx, cy) {
  17055. if (arguments.length == 1) {
  17056. var p = Point.parse(arguments[0]);
  17057. cx = p.x;
  17058. cy = p.y;
  17059. }
  17060. this.cx = cx;
  17061. this.cy = cy;
  17062. return this.update();
  17063. },
  17064. setCenterX: function(cx) {
  17065. this.cx = cx;
  17066. return this.update();
  17067. },
  17068. setCenterY: function(cy) {
  17069. this.cy = cy;
  17070. return this.update();
  17071. }
  17072. });
  17073. }
  17074. };
  17075. //src/graphic/eventhandler.js
  17076. /*
  17077. * kity event 实现
  17078. */
  17079. _p[33] = {
  17080. value: function(require, exports, module) {
  17081. // polyfill
  17082. (function() {
  17083. function CustomEvent(event, params) {
  17084. params = params || {
  17085. bubbles: false,
  17086. cancelable: false,
  17087. detail: undefined
  17088. };
  17089. var evt = document.createEvent("CustomEvent");
  17090. evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
  17091. return evt;
  17092. }
  17093. CustomEvent.prototype = window.Event.prototype;
  17094. window.CustomEvent = CustomEvent;
  17095. })();
  17096. var Utils = _p.r(12), ShapeEvent = _p.r(62);
  17097. // 内部处理器缓存
  17098. var INNER_HANDLER_CACHE = {}, // 用户处理器缓存
  17099. USER_HANDLER_CACHE = {}, guid = 0;
  17100. // 添加事件统一入口
  17101. function _addEvent(type, handler, isOnce) {
  17102. isOnce = !!isOnce;
  17103. if (Utils.isString(type)) {
  17104. type = type.match(/\S+/g);
  17105. }
  17106. Utils.each(type, function(currentType) {
  17107. listen.call(this, this.node, currentType, handler, isOnce);
  17108. }, this);
  17109. return this;
  17110. }
  17111. // 移除事件统一入口
  17112. function _removeEvent(type, handler) {
  17113. var userHandlerList = null, eventId = this._EVNET_UID, isRemoveAll = handler === undefined;
  17114. userHandlerList = USER_HANDLER_CACHE[eventId][type];
  17115. //移除指定的监听器
  17116. if (!isRemoveAll) {
  17117. isRemoveAll = true;
  17118. Utils.each(userHandlerList, function removeKityEvent(fn, index) {
  17119. if (fn === handler) {
  17120. // 不能结束, 需要查找完整个list, 避免丢失移除多次绑定同一个处理器的情况
  17121. delete userHandlerList[index];
  17122. } else {
  17123. isRemoveAll = false;
  17124. }
  17125. });
  17126. }
  17127. //删除所有监听器
  17128. if (isRemoveAll) {
  17129. deleteDomEvent(this.node, type, INNER_HANDLER_CACHE[eventId][type]);
  17130. delete USER_HANDLER_CACHE[eventId][type];
  17131. delete INNER_HANDLER_CACHE[eventId][type];
  17132. }
  17133. return this;
  17134. }
  17135. // 执行绑定, 该方法context为shape或者mixin了eventhandler的对象
  17136. function listen(node, type, handler, isOnce) {
  17137. var eid = this._EVNET_UID, targetObject = this;
  17138. // 初始化内部监听器
  17139. if (!INNER_HANDLER_CACHE[eid]) {
  17140. INNER_HANDLER_CACHE[eid] = {};
  17141. }
  17142. if (!INNER_HANDLER_CACHE[eid][type]) {
  17143. // 内部监听器
  17144. INNER_HANDLER_CACHE[eid][type] = function kityEventHandler(e) {
  17145. e = new ShapeEvent(e || window.event);
  17146. Utils.each(USER_HANDLER_CACHE[eid][type], function executeKityEvent(fn) {
  17147. var result;
  17148. if (fn) {
  17149. result = fn.call(targetObject, e);
  17150. //once 绑定, 执行完后删除
  17151. if (isOnce) {
  17152. targetObject.off(type, fn);
  17153. }
  17154. }
  17155. // 如果用户handler里return了false, 则该节点上的此后的同类型事件将不再执行
  17156. return result;
  17157. }, targetObject);
  17158. };
  17159. }
  17160. // 初始化用户监听器列表
  17161. if (!USER_HANDLER_CACHE[eid]) {
  17162. USER_HANDLER_CACHE[eid] = {};
  17163. }
  17164. if (!USER_HANDLER_CACHE[eid][type]) {
  17165. USER_HANDLER_CACHE[eid][type] = [ handler ];
  17166. // 绑定对应类型的事件
  17167. // dom对象利用dom event进行处理, 非dom对象, 由消息分发机制处理
  17168. if (!!node && "on" + type in node) {
  17169. bindDomEvent(node, type, INNER_HANDLER_CACHE[eid][type]);
  17170. }
  17171. } else {
  17172. USER_HANDLER_CACHE[eid][type].push(handler);
  17173. }
  17174. }
  17175. // 绑定dom事件
  17176. function bindDomEvent(node, type, handler) {
  17177. if (node.addEventListener) {
  17178. node.addEventListener(type, handler, false);
  17179. } else {
  17180. node.attachEvent("on" + type, handler);
  17181. }
  17182. }
  17183. // 删除dom事件
  17184. function deleteDomEvent(node, type, handler) {
  17185. if (node.removeEventListener) {
  17186. node.removeEventListener(type, handler, false);
  17187. } else {
  17188. node.detachEvent(type, handler);
  17189. }
  17190. }
  17191. // 触发dom事件
  17192. function triggerDomEvent(node, type, params) {
  17193. var event = new CustomEvent(type, {
  17194. bubbles: true,
  17195. cancelable: true
  17196. });
  17197. event._kityParam = params;
  17198. node.dispatchEvent(event);
  17199. }
  17200. // 发送消息
  17201. function sendMessage(messageObj, type, msg) {
  17202. var event = null, handler = null;
  17203. var handlers = INNER_HANDLER_CACHE[messageObj._EVNET_UID];
  17204. if (!handlers) return;
  17205. handler = handlers[type];
  17206. if (!handler) {
  17207. return;
  17208. }
  17209. event = Utils.extend({
  17210. type: type,
  17211. target: messageObj
  17212. }, msg || {});
  17213. handler.call(messageObj, event);
  17214. }
  17215. // 对外接口
  17216. return _p.r(11).createClass("EventHandler", {
  17217. constructor: function() {
  17218. this._EVNET_UID = ++guid;
  17219. },
  17220. addEventListener: function(type, handler) {
  17221. return _addEvent.call(this, type, handler, false);
  17222. },
  17223. addOnceEventListener: function(type, handler) {
  17224. return _addEvent.call(this, type, handler, true);
  17225. },
  17226. removeEventListener: function(type, handler) {
  17227. return _removeEvent.call(this, type, handler);
  17228. },
  17229. on: function(type, handler) {
  17230. return this.addEventListener.apply(this, arguments);
  17231. },
  17232. once: function(type, handler) {
  17233. return this.addOnceEventListener.apply(this, arguments);
  17234. },
  17235. off: function() {
  17236. return this.removeEventListener.apply(this, arguments);
  17237. },
  17238. fire: function(type, params) {
  17239. return this.trigger.apply(this, arguments);
  17240. },
  17241. trigger: function(type, params) {
  17242. sendMessage(this, type, params);
  17243. return this;
  17244. }
  17245. });
  17246. }
  17247. };
  17248. //src/graphic/geometry.js
  17249. _p[34] = {
  17250. value: function(require) {
  17251. var utils = _p.r(12);
  17252. var Point = _p.r(50);
  17253. var Vector = _p.r(73);
  17254. var Matrix = _p.r(43);
  17255. var g = {};
  17256. var pathCommand = /([achlmrqstvz])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?\s*)+)/gi, pathValues = /(-?\d*\.?\d*(?:e[\-+]?\d+)?)\s*,?\s*/gi, paramCounts = {
  17257. a: 7,
  17258. c: 6,
  17259. h: 1,
  17260. l: 2,
  17261. m: 2,
  17262. q: 4,
  17263. s: 4,
  17264. t: 2,
  17265. v: 1,
  17266. z: 0
  17267. };
  17268. function pathClone(path) {
  17269. var result, i, j, segment, segmentCopy;
  17270. result = [];
  17271. for (i = 0; i < path.length; i++) {
  17272. segment = path[i];
  17273. result.push(segmentCopy = []);
  17274. for (j = 0; j < segment.length; j++) {
  17275. segmentCopy.push(segment[j]);
  17276. }
  17277. }
  17278. if (path.isUniform) result.isUniform = true;
  17279. if (path.isAbsolute) result.isAbsolute = true;
  17280. if (path.isCurve) result.isCurve = true;
  17281. return result;
  17282. }
  17283. // 缓存函数
  17284. // from raphael.js
  17285. function cacher(f, scope, postprocessor) {
  17286. function repush(array, item) {
  17287. for (var i = 0, ii = array.length; i < ii; i++) if (array[i] === item) {
  17288. return array.push(array.splice(i, 1)[0]);
  17289. }
  17290. }
  17291. function newf() {
  17292. var arg = Array.prototype.slice.call(arguments, 0), args = arg.join("␀"), cache = newf.cache = newf.cache || {}, count = newf.count = newf.count || [];
  17293. if (cache.hasOwnProperty(args)) {
  17294. repush(count, args);
  17295. return postprocessor ? postprocessor(cache[args]) : cache[args];
  17296. }
  17297. if (count.length >= 1e3) {
  17298. delete cache[count.shift()];
  17299. }
  17300. count.push(args);
  17301. cache[args] = f.apply(scope, arg);
  17302. return postprocessor ? postprocessor(cache[args]) : cache[args];
  17303. }
  17304. return newf;
  17305. }
  17306. /**
  17307. *
  17308. * kity.g.pathToString(pathSegment)
  17309. *
  17310. * 返回表示 PathSegment 的字符串
  17311. *
  17312. * @param {Array} pathSegment
  17313. * 要表示的 Path Segment
  17314. *
  17315. * @return {String} 表示该 Path 的字符串
  17316. *
  17317. * @example
  17318. *
  17319. * var pathSegment = [['M', 0, 0], ['L', 10, 10]]
  17320. * var pathString = kity.g.pathToString(pathSegment);
  17321. * // 返回 'M0,0L10,10'
  17322. */
  17323. g.pathToString = function(pathSegment) {
  17324. pathSegment = pathSegment || this;
  17325. if (typeof pathSegment == "string") return pathSegment;
  17326. if (pathSegment instanceof Array) {
  17327. pathSegment = utils.flatten(pathSegment);
  17328. return pathSegment.join(",").replace(/,?([achlmqrstvxz]),?/gi, "$1");
  17329. }
  17330. };
  17331. /**
  17332. * kity.g.parsePathString(pathString)
  17333. *
  17334. * 解析 Path 字符串成 PathSegment
  17335. *
  17336. * @copyright rapheal.js
  17337. *
  17338. * @example
  17339. *
  17340. * var seg = kity.g.parsePathString('M10,12l21-23-21.5,11z');
  17341. * // 返回: [['M', 10, 12], ['l', 21, -23], ['l', -21.5, 11], ['z']]
  17342. *
  17343. * @param {String} pathString Path 字符串
  17344. * @return {Array}
  17345. */
  17346. g.parsePathString = cacher(function(pathString) {
  17347. var data = [];
  17348. pathString.replace(pathCommand, function(a, b, c) {
  17349. var params = [], name = b.toLowerCase();
  17350. c.replace(pathValues, function(a, b) {
  17351. if (b) params.push(+b);
  17352. });
  17353. if (name == "m" && params.length > 2) {
  17354. data.push([ b ].concat(params.splice(0, 2)));
  17355. name = "l";
  17356. b = b == "m" ? "l" : "L";
  17357. }
  17358. if (name == "r") {
  17359. data.push([ b ].concat(params));
  17360. } else {
  17361. while (params.length >= paramCounts[name]) {
  17362. data.push([ b ].concat(params.splice(0, paramCounts[name])));
  17363. if (!paramCounts[name]) {
  17364. break;
  17365. }
  17366. }
  17367. }
  17368. });
  17369. data.isUniform = true;
  17370. data.toString = g.pathToString;
  17371. return data;
  17372. });
  17373. /**
  17374. * kity.g.pathToAbsolute(path)
  17375. *
  17376. * 把路径转换为绝对路径的形式
  17377. *
  17378. * @param {Array|String} path
  17379. * 要转换的 path 路径或者数组
  17380. *
  17381. * @return {Array}
  17382. * 转换后的 Path Segment
  17383. *
  17384. * @example
  17385. *
  17386. * var path = 'M10,10l50,50';
  17387. * var absPath = kity.g.pathToAbsolute(path);
  17388. * // 返回 [['M', 10, 10], ['L', 60, 60]]
  17389. */
  17390. g.pathToAbsolute = cacher(function(path) {
  17391. var pathArray = path.isUniform ? path : g.parsePathString(g.pathToString(path));
  17392. var res = [], x = 0, y = 0, mx = 0, my = 0, start = 0;
  17393. var r, pa, i, j, k, ii, jj, kk;
  17394. if (pathArray[0][0] == "M") {
  17395. x = +pathArray[0][1];
  17396. y = +pathArray[0][2];
  17397. mx = x;
  17398. my = y;
  17399. start++;
  17400. res[0] = [ "M", x, y ];
  17401. }
  17402. for (r, pa, i = start, ii = pathArray.length; i < ii; i++) {
  17403. res.push(r = []);
  17404. pa = pathArray[i];
  17405. if (pa[0] != pa[0].toUpperCase()) {
  17406. r[0] = pa[0].toUpperCase();
  17407. switch (r[0]) {
  17408. case "A":
  17409. r[1] = pa[1];
  17410. r[2] = pa[2];
  17411. r[3] = pa[3];
  17412. r[4] = pa[4];
  17413. r[5] = pa[5];
  17414. r[6] = +(pa[6] + x);
  17415. r[7] = +(pa[7] + y);
  17416. break;
  17417. case "V":
  17418. r[1] = +pa[1] + y;
  17419. break;
  17420. case "H":
  17421. r[1] = +pa[1] + x;
  17422. break;
  17423. case "M":
  17424. mx = +pa[1] + x;
  17425. my = +pa[2] + y;
  17426. break;
  17427. default:
  17428. for (j = 1, jj = pa.length; j < jj; j++) {
  17429. r[j] = +pa[j] + (j % 2 ? x : y);
  17430. }
  17431. }
  17432. } else {
  17433. for (k = 0, kk = pa.length; k < kk; k++) {
  17434. r[k] = pa[k];
  17435. }
  17436. }
  17437. switch (r[0]) {
  17438. case "Z":
  17439. x = mx;
  17440. y = my;
  17441. break;
  17442. case "H":
  17443. x = r[1];
  17444. break;
  17445. case "V":
  17446. y = r[1];
  17447. break;
  17448. case "M":
  17449. mx = r[r.length - 2];
  17450. my = r[r.length - 1];
  17451. break;
  17452. default:
  17453. x = r[r.length - 2];
  17454. y = r[r.length - 1];
  17455. }
  17456. }
  17457. res.isUniform = true;
  17458. res.isAbsolute = true;
  17459. res.toString = g.pathToString;
  17460. return res;
  17461. });
  17462. // 把圆弧绘制的曲线转化为对应的三次贝塞尔形式
  17463. function a2c(x1, y1, rx, ry, angle, laf, sf, x2, y2, recursive) {
  17464. // copy from raphael.js
  17465. // for more information of where this math came from visit:
  17466. // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
  17467. var math = Math, PI = math.PI, abs = Math.abs, _120 = PI * 120 / 180, rad = PI / 180 * (+angle || 0), res = [], xy, rotate = function(x, y, rad) {
  17468. var X = x * math.cos(rad) - y * math.sin(rad), Y = x * math.sin(rad) + y * math.cos(rad);
  17469. return {
  17470. x: X,
  17471. y: Y
  17472. };
  17473. };
  17474. var cos, sin, h, x, y, rx2, ry2, k, cx, cy, f1, f2, df, f2old, x2old, y2old, c1, s1, c2, s2, t, hx, hy, m1, m2, m3, m4, newres, i, ii;
  17475. if (!recursive) {
  17476. xy = rotate(x1, y1, -rad);
  17477. x1 = xy.x;
  17478. y1 = xy.y;
  17479. xy = rotate(x2, y2, -rad);
  17480. x2 = xy.x;
  17481. y2 = xy.y;
  17482. cos = math.cos(PI / 180 * angle);
  17483. sin = math.sin(PI / 180 * angle);
  17484. x = (x1 - x2) / 2;
  17485. y = (y1 - y2) / 2;
  17486. h = x * x / (rx * rx) + y * y / (ry * ry);
  17487. if (h > 1) {
  17488. h = math.sqrt(h);
  17489. rx = h * rx;
  17490. ry = h * ry;
  17491. }
  17492. rx2 = rx * rx;
  17493. ry2 = ry * ry;
  17494. k = (laf == sf ? -1 : 1) * math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x)));
  17495. cx = k * rx * y / ry + (x1 + x2) / 2;
  17496. cy = k * -ry * x / rx + (y1 + y2) / 2;
  17497. f1 = math.asin(((y1 - cy) / ry).toFixed(9));
  17498. f2 = math.asin(((y2 - cy) / ry).toFixed(9));
  17499. f1 = x1 < cx ? PI - f1 : f1;
  17500. f2 = x2 < cx ? PI - f2 : f2;
  17501. if (f1 < 0) f1 = PI * 2 + f1;
  17502. if (f2 < 0) f2 = PI * 2 + f2;
  17503. if (sf && f1 > f2) {
  17504. f1 = f1 - PI * 2;
  17505. }
  17506. if (!sf && f2 > f1) {
  17507. f2 = f2 - PI * 2;
  17508. }
  17509. } else {
  17510. f1 = recursive[0];
  17511. f2 = recursive[1];
  17512. cx = recursive[2];
  17513. cy = recursive[3];
  17514. }
  17515. df = f2 - f1;
  17516. if (abs(df) > _120) {
  17517. f2old = f2;
  17518. x2old = x2;
  17519. y2old = y2;
  17520. f2 = f1 + _120 * (sf && f2 > f1 ? 1 : -1);
  17521. x2 = cx + rx * math.cos(f2);
  17522. y2 = cy + ry * math.sin(f2);
  17523. res = a2c(x2, y2, rx, ry, angle, 0, sf, x2old, y2old, [ f2, f2old, cx, cy ]);
  17524. }
  17525. df = f2 - f1;
  17526. c1 = math.cos(f1);
  17527. s1 = math.sin(f1);
  17528. c2 = math.cos(f2);
  17529. s2 = math.sin(f2);
  17530. t = math.tan(df / 4);
  17531. hx = 4 / 3 * rx * t;
  17532. hy = 4 / 3 * ry * t;
  17533. m1 = [ x1, y1 ];
  17534. m2 = [ x1 + hx * s1, y1 - hy * c1 ];
  17535. m3 = [ x2 + hx * s2, y2 - hy * c2 ];
  17536. m4 = [ x2, y2 ];
  17537. m2[0] = 2 * m1[0] - m2[0];
  17538. m2[1] = 2 * m1[1] - m2[1];
  17539. if (recursive) {
  17540. return [ m2, m3, m4 ].concat(res);
  17541. } else {
  17542. res = [ m2, m3, m4 ].concat(res).join().split(",");
  17543. newres = [];
  17544. for (i = 0, ii = res.length; i < ii; i++) {
  17545. newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;
  17546. }
  17547. return newres;
  17548. }
  17549. }
  17550. // 把二次贝塞尔曲线参数转化为三次贝塞尔曲线参数
  17551. function q2c(x1, y1, ax, ay, x2, y2) {
  17552. // copy from raphael.js
  17553. var _13 = 1 / 3, _23 = 2 / 3;
  17554. return [ _13 * x1 + _23 * ax, _13 * y1 + _23 * ay, _13 * x2 + _23 * ax, _13 * y2 + _23 * ay, x2, y2 ];
  17555. }
  17556. /**
  17557. * kity.g.pathToCurve(path)
  17558. *
  17559. * 把路径转换为贝塞尔路径
  17560. *
  17561. * @param {Array|String} path
  17562. * 要转换的 path 路径或数组
  17563. *
  17564. * @return {Array}
  17565. * 转换后的 PathSegment,每一段都是 'C'
  17566. */
  17567. g.pathToCurve = cacher(function(path) {
  17568. var i, j, command, param;
  17569. var initPoint, currentPoint, endPoint, shouldClose, lastControlPoint, aussumedControlPoint;
  17570. var controlPoint1, controlPoint2;
  17571. var res = [];
  17572. // 处理的路径要求是一个绝对路径
  17573. if (!path.isAbsolute) path = g.pathToAbsolute(path);
  17574. for (i = 0; i < path.length; i++) {
  17575. command = path[i][0];
  17576. param = path[i].slice(1);
  17577. // 画笔移动
  17578. if (command == "M") {
  17579. initPoint = lastControlPoint = currentPoint = param;
  17580. res.push(path[i]);
  17581. continue;
  17582. }
  17583. // 路径闭合
  17584. if (command == "Z") {
  17585. shouldClose = true;
  17586. command = "L";
  17587. param = initPoint;
  17588. }
  17589. // 绘制命令的目的位置
  17590. endPoint = param.slice(param.length - 2);
  17591. // 对 'H' 命令的修正
  17592. if (command == "H") {
  17593. endPoint = [ param[0], currentPoint[1] ];
  17594. command = "L";
  17595. }
  17596. // 对 'V' 命令的修正
  17597. if (command == "V") {
  17598. endPoint = [ currentPoint[0], param[0] ];
  17599. command = "L";
  17600. }
  17601. // 对 'S' 命令求出隐含的控制点位置
  17602. if (command == "S" || command == "T") {
  17603. // 隐含控制点是上一个控制点关于当前位置的镜像
  17604. aussumedControlPoint = [ currentPoint[0] + (currentPoint[0] - lastControlPoint[0]), currentPoint[1] + (currentPoint[1] - lastControlPoint[1]) ];
  17605. }
  17606. // 针对不同的命令求控制点
  17607. switch (command) {
  17608. case "L":
  17609. controlPoint1 = currentPoint;
  17610. controlPoint2 = endPoint;
  17611. break;
  17612. case "C":
  17613. controlPoint1 = param.slice(0, 2);
  17614. controlPoint2 = param.slice(2, 4);
  17615. break;
  17616. case "S":
  17617. controlPoint1 = aussumedControlPoint.slice();
  17618. controlPoint2 = param.slice(0, 2);
  17619. break;
  17620. case "Q":
  17621. lastControlPoint = param.slice(0, 2);
  17622. param = q2c.apply(null, currentPoint.concat(param));
  17623. controlPoint1 = param.slice(0, 2);
  17624. controlPoint2 = param.slice(2, 4);
  17625. break;
  17626. case "T":
  17627. param = q2c.apply(null, currentPoint.concat(aussumedControlPoint).concat(param));
  17628. controlPoint1 = param.slice(0, 2);
  17629. controlPoint2 = param.slice(2, 4);
  17630. break;
  17631. case "A":
  17632. param = a2c.apply(null, currentPoint.concat(param));
  17633. j = 0;
  17634. while (j in param) {
  17635. controlPoint1 = param.slice(j, j + 2);
  17636. controlPoint2 = param.slice(j + 2, j + 4);
  17637. endPoint = param.slice(j + 4, j + 6);
  17638. // 写入当前一段曲线
  17639. res.push([ "C" ].concat(controlPoint1).concat(controlPoint2).concat(endPoint));
  17640. j += 6;
  17641. }
  17642. break;
  17643. }
  17644. if (command != "A") {
  17645. // 写入当前一段曲线
  17646. res.push([ "C" ].concat(controlPoint1).concat(controlPoint2).concat(endPoint));
  17647. }
  17648. // 为下次循环准备当前位置
  17649. currentPoint = endPoint;
  17650. // 二次贝塞尔曲线自己已经记录了上个控制点的位置,其它的记录控制点 2 的位置
  17651. if (command != "Q") {
  17652. lastControlPoint = controlPoint2;
  17653. }
  17654. if (shouldClose) {
  17655. res.push([ "Z" ]);
  17656. shouldClose = false;
  17657. }
  17658. }
  17659. res.isUniform = true;
  17660. res.isAbsolute = true;
  17661. res.isCurve = true;
  17662. res.toString = g.pathToString;
  17663. return res;
  17664. });
  17665. /**
  17666. * 将贝塞尔曲线切成两部分
  17667. *
  17668. * @see http://stackoverflow.com/questions/18655135/divide-bezier-curve-into-two-equal-halves
  17669. */
  17670. function cutBezier(bezierArray, t) {
  17671. function __(t) {
  17672. return function(p, q) {
  17673. return p + t * (q - p);
  17674. };
  17675. }
  17676. var _ = __(t || .5), ba = bezierArray, ax = ba[0], ay = ba[1], bx = ba[2], by = ba[3], cx = ba[4], cy = ba[5], dx = ba[6], dy = ba[7], ex = _(ax, bx), ey = _(ay, by), fx = _(bx, cx), fy = _(by, cy), gx = _(cx, dx), gy = _(cy, dy), hx = _(ex, fx), hy = _(ey, fy), jx = _(fx, gx), jy = _(fy, gy), kx = _(hx, jx), ky = _(hy, jy);
  17677. return [ [ ax, ay, ex, ey, hx, hy, kx, ky ], [ kx, ky, jx, jy, gx, gy, dx, dy ] ];
  17678. }
  17679. /**
  17680. * kity.g.cutBezier(bezierArray, t)
  17681. *
  17682. * 在指定位置把贝塞尔曲线切割为两部分
  17683. *
  17684. * @param {Array} bezierArray
  17685. * 表示贝塞尔曲线的一个数组 [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y]
  17686. * p1 和 p2 是贝塞尔曲线的起点和终点,c1 和 c2 是两个控制点
  17687. *
  17688. * @param {Number} t
  17689. * 切割的位置(0 到 1)
  17690. *
  17691. * @return {Array}
  17692. * 切割的两个贝塞尔曲线:[
  17693. * [p1x1, p1y1, c1x1, c1y1, c2x1, c2y1, p2x1, p2y1],
  17694. * [p1x2, p1y2, c1x2, c1y2, c2x2, c2y2, p2x2, p2y2]
  17695. * ]
  17696. *
  17697. */
  17698. g.cutBezier = cacher(cutBezier);
  17699. /**
  17700. * 求一段贝塞尔曲线的子段
  17701. *
  17702. * @param {Array} bezierArray
  17703. * 长度为 8 的数组,表示 [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y]
  17704. *
  17705. * @param {Number} t
  17706. * 子段的结束位置(0 到 1)
  17707. *
  17708. * @param {Number} t0
  17709. * 字段的开始位置(0 到 t),可不传,默认为 0
  17710. *
  17711. * @return {Array}
  17712. * 长度为 8 的数组,表示给定贝塞尔曲线的子段
  17713. */
  17714. g.subBezier = function(bezierArray, t, t0) {
  17715. var b2t = cutBezier(bezierArray, t)[0];
  17716. return t0 ? cutBezier(b2t, t0 / t)[1] : b2t;
  17717. };
  17718. /**
  17719. * 求贝塞尔曲线上的一个点
  17720. *
  17721. * @param {Array} bezierArray
  17722. * 长度为 8 的数组,表示 [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y]
  17723. *
  17724. * @param {Number} t
  17725. * 所求点的开始位置(0 到 1)
  17726. *
  17727. * @return {Point} p
  17728. * p.x: x 坐标
  17729. * p.y: y 坐标
  17730. * p.tan: 在 t 处的切线方向(类型为 kity.Vector,模为 1)
  17731. */
  17732. g.pointAtBezier = function(bezierArray, t) {
  17733. var b2t = cutBezier(bezierArray, t)[0];
  17734. var p = Point.parse(b2t.slice(6)), c = Point.parse(b2t.slice(4, 2)), v = Vector.fromPoints(c, p);
  17735. if (t === 0) {
  17736. p.tan = g.pointAtBezier(bezierArray, .01).tan;
  17737. } else {
  17738. p.tan = v.normalize();
  17739. }
  17740. return p;
  17741. };
  17742. /**
  17743. * 求贝塞尔曲线的长度
  17744. *
  17745. * @param {Array} bezierArray
  17746. * 长度为 8 的数组,表示 [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y]
  17747. *
  17748. * @param {Number} tolerate
  17749. * 允许的误差,默认是 0.1
  17750. *
  17751. * @return {Number} 贝塞尔曲线的长度
  17752. */
  17753. g.bezierLength = cacher(function bezierLength(bezierArray) {
  17754. // 表示(c[0]*t^4 + c[1]*t^3 + c[2]*t^2 + c[3]*t^1 + c[4])^(1/2)的函数
  17755. function f(x) {
  17756. var m = c0 * Math.pow(x, 4) + c1 * Math.pow(x, 3) + c2 * Math.pow(x, 2) + c3 * x + c4;
  17757. if (m < 0) {
  17758. m = 0;
  17759. }
  17760. return Math.pow(m, .5);
  17761. }
  17762. // 用Newton-Cotes型求积公式
  17763. var arr = bezierArray;
  17764. // 三次贝塞尔曲线函数求导后,求出对应的方程系数,用cx[],cy[]表示x`(t)和y`(t)的系数
  17765. var cx0, cx1, cx2;
  17766. var cy0, cy1, cy2;
  17767. // 用c[]表示x`(t)^2 + y`(t)^2的结果的系数
  17768. var c0, c1, c2, c3, c4;
  17769. // 求x`(t) 和 y`(t)的系数
  17770. cx0 = -3 * arr[0] + 9 * arr[2] - 9 * arr[4] + 3 * arr[6];
  17771. cx1 = 6 * arr[0] - 12 * arr[2] + 6 * arr[4];
  17772. cx2 = -3 * arr[0] + 3 * arr[2];
  17773. cy0 = -3 * arr[1] + 9 * arr[3] - 9 * arr[5] + 3 * arr[7];
  17774. cy1 = 6 * arr[1] - 12 * arr[3] + 6 * arr[5];
  17775. cy2 = -3 * arr[1] + 3 * arr[3];
  17776. // 求x`(t)^2 + y`(t)^2的结果的系数 c[]
  17777. c0 = Math.pow(cx0, 2) + Math.pow(cy0, 2);
  17778. c1 = 2 * (cx0 * cx1 + cy0 * cy1);
  17779. c2 = 2 * (cx0 * cx2 + cy0 * cy2) + Math.pow(cx1, 2) + Math.pow(cy1, 2);
  17780. c3 = 2 * (cx1 * cx2 + cy1 * cy2);
  17781. c4 = Math.pow(cx2, 2) + Math.pow(cy2, 2);
  17782. // 用cotes积分公式求值
  17783. return (f(0) + f(1) + 4 * (f(.125) + f(.375) + f(.625) + f(.875)) + 2 * (f(.25) + f(.5) + f(.75))) / 24;
  17784. });
  17785. // 计算一个 pathSegment 中每一段的在整体中所占的长度范围,以及总长度
  17786. // 方法要求每一段都是贝塞尔曲线
  17787. var getBezierPathSegmentRanges = cacher(function(pathSegment) {
  17788. var i, ii, segment, position, bezierLength, segmentRanges, totalLength;
  17789. segmentRanges = [];
  17790. // 总长度
  17791. totalLength = 0;
  17792. for (i = 0, ii = pathSegment.length; i < ii; i++) {
  17793. segment = pathSegment[i];
  17794. if (segment[0] == "M") {
  17795. position = segment.slice(1);
  17796. segmentRanges.push(null);
  17797. continue;
  17798. }
  17799. if (segment[0] == "Z") {
  17800. segmentRanges.push(null);
  17801. continue;
  17802. }
  17803. bezierLength = g.bezierLength(position.concat(segment.slice(1)));
  17804. segmentRanges.push([ totalLength, totalLength + bezierLength ]);
  17805. totalLength += bezierLength;
  17806. // 迭代当前位置
  17807. position = segment.slice(4);
  17808. }
  17809. segmentRanges.totalLength = totalLength;
  17810. return segmentRanges;
  17811. });
  17812. /**
  17813. * 求一段路径的子路径
  17814. *
  17815. * @param {Array|String} path
  17816. * 原路径
  17817. *
  17818. * @param {Number} t1
  17819. * 要求的子路径的结束位置(0 到 1)
  17820. *
  17821. * @param {Number} t0
  17822. * 要求的子路径的开始位置(0 到 t1),可不传,默认为 0
  17823. *
  17824. * @return {Array}
  17825. * 子路径的 PathSegment
  17826. */
  17827. g.subPath = function(path, t1, t0) {
  17828. var dt;
  17829. t0 = t0 || 0;
  17830. dt = t1 - t0;
  17831. dt = dt - (dt | 0);
  17832. t0 = t0 - (t0 | 0);
  17833. t1 = t0 + dt;
  17834. if (t1 > 1) {
  17835. return g.subPath(path, 1, t0).concat(g.subPath(path, t1 - 1));
  17836. }
  17837. if (!path.isCurve) {
  17838. path = g.pathToCurve(path);
  17839. }
  17840. // path 每一段在整体中的长度区间
  17841. var segmentRanges = getBezierPathSegmentRanges(path);
  17842. // path 总长度
  17843. var totalLength = segmentRanges.totalLength;
  17844. // t1 和 t0 位置命中的长度位置
  17845. var t1Length = totalLength * t1, t0Length = totalLength * (t0 || 0);
  17846. // 产生的子路径
  17847. var subPath = [];
  17848. // 迭代变量,a 是一段的长度区间左值,b 是右值,d 是区间长度
  17849. var i, ii, a, b, d;
  17850. var position;
  17851. var bezier, subBezier, stared;
  17852. for (i = 0, ii = path.length; i < ii; i++) {
  17853. if (path[i][0] == "M") {
  17854. position = path[i].slice(1);
  17855. if (stared) {
  17856. subPath.push(path[i].slice());
  17857. }
  17858. continue;
  17859. }
  17860. if (path[i][0] == "Z") {
  17861. // subpath 路径不闭合
  17862. continue;
  17863. }
  17864. a = segmentRanges[i][0];
  17865. b = segmentRanges[i][1];
  17866. d = b - a;
  17867. bezier = position.concat(path[i].slice(1));
  17868. if (t0Length > b) {
  17869. // t0 和 t1 都右溢出
  17870. // -----------------------------------
  17871. // t0 t1
  17872. // |________|
  17873. //
  17874. // 需要跳过当前块
  17875. position = bezier.slice(bezier.length - 2);
  17876. continue;
  17877. } else if (t0Length >= a) {
  17878. // 命中 t0;t1 可能命中或右溢出
  17879. // -----------------------------------
  17880. // t0 t1
  17881. // |______|__|
  17882. //
  17883. // or: |_|____|__|
  17884. //
  17885. // 取当前块 t0 到 t1 的部分
  17886. subBezier = g.subBezier(bezier, Math.min((t1Length - a) / d, 1), (t0Length - a) / d);
  17887. stared = true;
  17888. position = subBezier.slice(0, 2);
  17889. subPath.push([ "M" ].concat(subBezier.slice(0, 2)));
  17890. subPath.push([ "C" ].concat(subBezier.slice(2)));
  17891. } else if (t1Length >= b) {
  17892. // t0 左溢出;t1 右溢出,整个块是需要的
  17893. // -----------------------------------
  17894. // t0 t1
  17895. // |_________|
  17896. //
  17897. // 此时取整个块
  17898. subPath.push(path[i].slice());
  17899. } else if (t1Length >= a) {
  17900. // t0 左溢出;t1 命中,取当前块 t1 之前的部分
  17901. // -----------------------------------
  17902. // t0 t1
  17903. // |__|______|
  17904. // 取当前块 t1 之前的部分
  17905. subBezier = g.subBezier(bezier, (t1Length - a) / d);
  17906. subPath.push([ "C" ].concat(subBezier.slice(2)));
  17907. stared = false;
  17908. } else {
  17909. // 没有可以再要的了
  17910. break;
  17911. }
  17912. position = bezier.slice(bezier.length - 2);
  17913. }
  17914. subPath.isAbsolute = true;
  17915. subPath.isCurve = true;
  17916. subPath.isUniform = true;
  17917. subPath.toString = g.pathToString;
  17918. return subPath;
  17919. };
  17920. /**
  17921. * 求路径上的一个点
  17922. *
  17923. * @param {Array|String} path
  17924. * 要求点的路径
  17925. *
  17926. * @param {Number} t
  17927. * 要求的点的位置(0 到 1)
  17928. *
  17929. * @return {Point} p
  17930. * p.x: x 坐标
  17931. * p.y: y 坐标
  17932. * p.tan: 在 t 处的切线方向(类型为 kity.Vector,模为 1)
  17933. */
  17934. g.pointAtPath = function(path, t) {
  17935. if (!path.isCurve) {
  17936. path = g.pathToCurve(path);
  17937. }
  17938. var subPath = g.subPath(path, t);
  17939. var lastCurve = subPath[subPath.length - 1][0] == "Z" ? subPath[subPath.length - 2] : subPath[subPath.length - 1];
  17940. // 跳过 'C' 命令,只留参数
  17941. lastCurve = lastCurve.slice(1);
  17942. var p = Point.parse(lastCurve.slice(4)), c = Point.parse(lastCurve.slice(2, 4));
  17943. p.tan = Vector.fromPoints(c, p).normalize();
  17944. return p;
  17945. };
  17946. /**
  17947. * 求一段路径的长度
  17948. *
  17949. * @param {string|Array} path
  17950. * 要求的路径
  17951. *
  17952. * @return {Number}
  17953. * 路径的长度
  17954. */
  17955. g.pathLength = cacher(function(path) {
  17956. if (!path.isCurve) {
  17957. path = g.pathToCurve(path);
  17958. }
  17959. // path 每一段在整体中的长度区间
  17960. var segmentRanges = getBezierPathSegmentRanges(path);
  17961. return segmentRanges.totalLength;
  17962. });
  17963. /**
  17964. * 求一段路径的关键点
  17965. *
  17966. * @param {string|Array} path
  17967. * 要求的路径
  17968. *
  17969. * @return {Array}
  17970. * 关键点的集合
  17971. */
  17972. g.pathKeyPoints = cacher(function(path) {
  17973. var i, ii, command, keyPoints;
  17974. if (!path.isCurve) {
  17975. path = g.pathToCurve(path);
  17976. }
  17977. keyPoints = [];
  17978. for (i = 0, ii = path.length; i < ii; i++) {
  17979. if (path[i][0] == "z") continue;
  17980. keyPoints.push(path[i].slice(path[i].length - 2));
  17981. }
  17982. return keyPoints;
  17983. });
  17984. // 对比两个路径的关键位置,在合适的位置切割合适的路径,使得两个路径的段数一致
  17985. // TODO: 使用插值算法,使对应点更合理
  17986. var alignCurve = cacher(function(path1, path2) {
  17987. if (!path1.isCurve) path1 = g.pathToCurve(path1);
  17988. if (!path2.isCurve) path2 = g.pathToCurve(path2);
  17989. var p1 = pathClone(path1);
  17990. var p2 = pathClone(path2);
  17991. p1.i = 0;
  17992. p2.i = 0;
  17993. p1.o = p2;
  17994. p2.o = p1;
  17995. function command(p, i) {
  17996. return p[i || p.i] && p[i || p.i][0];
  17997. }
  17998. function param(p, i) {
  17999. return p[i || p.i] && p[i || p.i].slice(1);
  18000. }
  18001. function point(p, i) {
  18002. var _param = param(p, i);
  18003. return _param && _param.slice(-2);
  18004. }
  18005. function fixZ(p) {
  18006. if (command(p) == "Z") {
  18007. p.splice(p.i, 1);
  18008. return true;
  18009. }
  18010. return false;
  18011. }
  18012. function fixM(p) {
  18013. if (command(p) == "M") {
  18014. p.o.splice(p.o.i, 0, [ "M" ].concat(point(p.o, p.o.i - 1)));
  18015. p.i++;
  18016. p.o.i++;
  18017. return true;
  18018. }
  18019. return false;
  18020. }
  18021. function fill(p) {
  18022. var lastPoint;
  18023. var i = 1;
  18024. while (!lastPoint) {
  18025. lastPoint = point(p, p.length - i++);
  18026. }
  18027. p.o.i = p.i;
  18028. while (p.length < p.o.length) {
  18029. if (fixZ(p.o)) continue;
  18030. if (fixM(p.o)) continue;
  18031. p.push([ "C" ].concat(lastPoint).concat(lastPoint).concat(lastPoint));
  18032. p.i++;
  18033. p.o.i++;
  18034. }
  18035. }
  18036. while (p1.i < p1.length && p2.i < p2.length) {
  18037. if (fixZ(p1) || fixZ(p2)) continue;
  18038. if (command(p1) == command(p2)) {
  18039. p1.i++;
  18040. p2.i++;
  18041. continue;
  18042. }
  18043. if (fixM(p1) || fixM(p2)) continue;
  18044. p1.i++;
  18045. p2.i++;
  18046. }
  18047. if (p1.i == p1.length) fill(p1);
  18048. if (p2.i == p2.length) fill(p2);
  18049. delete p1.i;
  18050. delete p1.o;
  18051. delete p2.i;
  18052. delete p2.o;
  18053. return [ p1, p2 ];
  18054. });
  18055. g.alignCurve = alignCurve;
  18056. /**
  18057. * 获得两个路径的补间结果
  18058. *
  18059. * @param {string|Array} path1
  18060. * 补间起始路径
  18061. *
  18062. * @param {string|Array} path2
  18063. * 补间结束路径
  18064. *
  18065. * @param {Number} t
  18066. * 补间比例,0 返回跟 path1 等效的结果;1 返回跟 path2 等效的结果
  18067. *
  18068. * @return {PathSegment}
  18069. * 补间的结果
  18070. */
  18071. g.pathTween = function(path1, path2, t) {
  18072. if (t === 0) return path1;
  18073. if (t === 1) return path2;
  18074. var aligned = alignCurve(path1, path2);
  18075. var result = [], seg, i, j;
  18076. path1 = aligned[0];
  18077. path2 = aligned[1];
  18078. for (i = 0; i < path1.length; i++) {
  18079. result.push(seg = []);
  18080. seg.push(path1[i][0]);
  18081. for (j = 1; j < path1[i].length; j++) {
  18082. seg.push(path1[i][j] + t * (path2[i][j] - path1[i][j]));
  18083. }
  18084. }
  18085. result.isUniform = result.isCurve = result.isAbsolute = true;
  18086. return result;
  18087. };
  18088. /**
  18089. * 变换指定的路径
  18090. *
  18091. * @param {String|Array} path
  18092. * 需要变换的路径
  18093. *
  18094. * @param {kity.Matrix} matrix
  18095. * 使用的变换矩阵
  18096. *
  18097. * @return {Array}
  18098. * 变换后的路径
  18099. */
  18100. g.transformPath = cacher(function(path, matrix) {
  18101. var i, ii, j, result, seg, pair;
  18102. if (!path.isCurve) {
  18103. path = g.pathToCurve(path);
  18104. }
  18105. result = [];
  18106. for (i = 0, ii = path.length; i < ii; i++) {
  18107. result.push(seg = [ path[i][0] ]);
  18108. for (j = 1; j < path[i].length; j += 2) {
  18109. pair = path[i].slice(j, j + 2);
  18110. pair = matrix.transformPoint(Point.parse(pair));
  18111. result.push(pair);
  18112. }
  18113. }
  18114. return result;
  18115. });
  18116. // entend
  18117. _p.r(11).extendClass(Matrix, {
  18118. transformPath: function(path) {
  18119. return g.transformPath(path, this);
  18120. }
  18121. });
  18122. return g;
  18123. }
  18124. };
  18125. //src/graphic/gradient.js
  18126. _p[35] = {
  18127. value: function(require, exports, module) {
  18128. var svg = _p.r(67);
  18129. var Resource = _p.r(58);
  18130. var Color = _p.r(28);
  18131. return _p.r(11).createClass("GradientBrush", {
  18132. base: Resource,
  18133. constructor: function(gradientNodeType, paper) {
  18134. this.callBase(gradientNodeType, paper);
  18135. this.stops = [];
  18136. },
  18137. addStop: function(offset, color, opacity) {
  18138. var gstop = svg.createNode("stop");
  18139. if (!(color instanceof Color)) {
  18140. color = Color.parse(color);
  18141. }
  18142. if (opacity === undefined) {
  18143. opacity = color.get("a");
  18144. }
  18145. gstop.setAttribute("offset", offset);
  18146. gstop.setAttribute("stop-color", color.toRGB());
  18147. if (opacity < 1) {
  18148. gstop.setAttribute("stop-opacity", opacity);
  18149. }
  18150. this.node.appendChild(gstop);
  18151. return this;
  18152. }
  18153. });
  18154. }
  18155. };
  18156. //src/graphic/group.js
  18157. _p[36] = {
  18158. value: function(require, exports, module) {
  18159. var ShapeContainer = _p.r(61);
  18160. return _p.r(11).createClass("Group", {
  18161. mixins: [ ShapeContainer ],
  18162. base: _p.r(60),
  18163. constructor: function Group() {
  18164. this.callBase("g");
  18165. }
  18166. });
  18167. }
  18168. };
  18169. //src/graphic/hyperlink.js
  18170. _p[37] = {
  18171. value: function(require, exports, module) {
  18172. var ShapeContainer = _p.r(61);
  18173. return _p.r(11).createClass("HyperLink", {
  18174. mixins: [ ShapeContainer ],
  18175. base: _p.r(60),
  18176. constructor: function(url) {
  18177. this.callBase("a");
  18178. this.setHref(url);
  18179. },
  18180. setHref: function(href) {
  18181. this.node.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", href);
  18182. return this;
  18183. },
  18184. getHref: function() {
  18185. return this.node.getAttributeNS("xlink:href");
  18186. },
  18187. setTarget: function(target) {
  18188. this.node.setAttribute("target", target);
  18189. return this;
  18190. },
  18191. getTarget: function() {
  18192. return this.node.getAttribute("target");
  18193. }
  18194. });
  18195. }
  18196. };
  18197. //src/graphic/image.js
  18198. _p[38] = {
  18199. value: function(require, exports, module) {
  18200. return _p.r(11).createClass("Image", {
  18201. base: _p.r(60),
  18202. constructor: function(url, width, height, x, y) {
  18203. this.callBase("image");
  18204. this.url = url;
  18205. this.width = width || 0;
  18206. this.height = height || 0;
  18207. this.x = x || 0;
  18208. this.y = y || 0;
  18209. this.update();
  18210. },
  18211. update: function() {
  18212. this.node.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", this.url);
  18213. this.node.setAttribute("x", this.x);
  18214. this.node.setAttribute("y", this.y);
  18215. this.node.setAttribute("width", this.width);
  18216. this.node.setAttribute("height", this.height);
  18217. return this;
  18218. },
  18219. setUrl: function(url) {
  18220. this.url = url === "" ? null : url;
  18221. return this.update();
  18222. },
  18223. getUrl: function() {
  18224. return this.url;
  18225. },
  18226. setWidth: function(width) {
  18227. this.width = width;
  18228. return this.update();
  18229. },
  18230. getWidth: function() {
  18231. return this.width;
  18232. },
  18233. setHeight: function(height) {
  18234. this.height = height;
  18235. return this.update();
  18236. },
  18237. getHeight: function() {
  18238. return this.height;
  18239. },
  18240. setX: function(x) {
  18241. this.x = x;
  18242. return this.update();
  18243. },
  18244. getX: function() {
  18245. return this.x;
  18246. },
  18247. setY: function(y) {
  18248. this.y = y;
  18249. return this.update();
  18250. },
  18251. getY: function() {
  18252. return this.y;
  18253. }
  18254. });
  18255. }
  18256. };
  18257. //src/graphic/line.js
  18258. _p[39] = {
  18259. value: function(require, exports, module) {
  18260. return _p.r(11).createClass("Line", {
  18261. base: _p.r(46),
  18262. constructor: function(x1, y1, x2, y2) {
  18263. this.callBase();
  18264. this.point1 = {
  18265. x: x1 || 0,
  18266. y: y1 || 0
  18267. };
  18268. this.point2 = {
  18269. x: x2 || 0,
  18270. y: y2 || 0
  18271. };
  18272. this.update();
  18273. },
  18274. setPoint1: function(x, y) {
  18275. this.point1.x = x;
  18276. this.point1.y = y;
  18277. return this.update();
  18278. },
  18279. setPoint2: function(x, y) {
  18280. this.point2.x = x;
  18281. this.point2.y = y;
  18282. return this.update();
  18283. },
  18284. getPoint1: function() {
  18285. return {
  18286. x: this.point1.x,
  18287. y: this.point1.y
  18288. };
  18289. },
  18290. getPoint2: function() {
  18291. return {
  18292. x: this.point2.x,
  18293. y: this.point2.y
  18294. };
  18295. },
  18296. update: function() {
  18297. var drawer = this.getDrawer();
  18298. drawer.clear();
  18299. drawer.moveTo(this.point1.x, this.point1.y);
  18300. drawer.lineTo(this.point2.x, this.point2.y);
  18301. return this;
  18302. }
  18303. });
  18304. }
  18305. };
  18306. //src/graphic/lineargradient.js
  18307. _p[40] = {
  18308. value: function(require, exports, module) {
  18309. var svg = _p.r(67);
  18310. var Gradient = _p.r(35);
  18311. return _p.r(11).createClass("LinearGradientBrush", {
  18312. base: Gradient,
  18313. constructor: function(paper) {
  18314. this.callBase("linearGradient", paper);
  18315. this.setStartPosition(0, 0);
  18316. this.setEndPosition(1, 0);
  18317. },
  18318. setStartPosition: function(px, py) {
  18319. this.node.setAttribute("x1", px);
  18320. this.node.setAttribute("y1", py);
  18321. return this;
  18322. },
  18323. setEndPosition: function(px, py) {
  18324. this.node.setAttribute("x2", px);
  18325. this.node.setAttribute("y2", py);
  18326. return this;
  18327. },
  18328. getStartPosition: function() {
  18329. return {
  18330. x: +this.node.getAttribute("x1"),
  18331. y: +this.node.getAttribute("y1")
  18332. };
  18333. },
  18334. getEndPosition: function() {
  18335. return {
  18336. x: +this.node.getAttribute("x2"),
  18337. y: +this.node.getAttribute("y2")
  18338. };
  18339. }
  18340. });
  18341. }
  18342. };
  18343. //src/graphic/marker.js
  18344. _p[41] = {
  18345. value: function(require, exports, module) {
  18346. var Point = _p.r(50);
  18347. var Marker = _p.r(11).createClass("Marker", {
  18348. base: _p.r(58),
  18349. mixins: [ _p.r(61), _p.r(75) ],
  18350. constructor: function() {
  18351. this.callBase("marker");
  18352. this.setOrient("auto");
  18353. },
  18354. setRef: function(x, y) {
  18355. if (arguments.length === 1) {
  18356. y = x.y;
  18357. x = x.x;
  18358. }
  18359. this.node.setAttribute("refX", x);
  18360. this.node.setAttribute("refY", y);
  18361. return this;
  18362. },
  18363. getRef: function() {
  18364. return new Point(+this.node.getAttribute("refX"), +this.node.getAttribute("refY"));
  18365. },
  18366. setWidth: function(width) {
  18367. this.node.setAttribute("markerWidth", this.width = width);
  18368. return this;
  18369. },
  18370. setOrient: function(orient) {
  18371. this.node.setAttribute("orient", this.orient = orient);
  18372. return this;
  18373. },
  18374. getOrient: function() {
  18375. return this.orient;
  18376. },
  18377. getWidth: function() {
  18378. return +this.width;
  18379. },
  18380. setHeight: function(height) {
  18381. this.node.setAttribute("markerHeight", this.height = height);
  18382. return this;
  18383. },
  18384. getHeight: function() {
  18385. return +this.height;
  18386. }
  18387. });
  18388. var Path = _p.r(46);
  18389. _p.r(11).extendClass(Path, {
  18390. setMarker: function(marker, pos) {
  18391. pos = pos || "end";
  18392. if (!marker) {
  18393. this.node.removeAttribute("marker-" + pos);
  18394. } else {
  18395. this.node.setAttribute("marker-" + pos, marker.toString());
  18396. }
  18397. return this;
  18398. }
  18399. });
  18400. return Marker;
  18401. }
  18402. };
  18403. //src/graphic/mask.js
  18404. /**
  18405. * 蒙板
  18406. */
  18407. _p[42] = {
  18408. value: function(require, exports, module) {
  18409. var Class = _p.r(11);
  18410. var Shape = _p.r(60);
  18411. var Mask = Class.createClass("Mask", {
  18412. base: Shape,
  18413. mixins: [ _p.r(61) ],
  18414. constructor: function() {
  18415. this.callBase("mask");
  18416. },
  18417. mask: function(shape) {
  18418. shape.getNode().setAttribute("mask", "url(#" + this.getId() + ")");
  18419. return this;
  18420. }
  18421. });
  18422. Class.extendClass(Shape, {
  18423. maskWith: function(mask) {
  18424. mask.mask(this);
  18425. return this;
  18426. }
  18427. });
  18428. return Mask;
  18429. }
  18430. };
  18431. //src/graphic/matrix.js
  18432. _p[43] = {
  18433. value: function(require, exports, module) {
  18434. var utils = _p.r(12);
  18435. var Box = _p.r(25);
  18436. var mPattern = /matrix\s*\((.+)\)/i;
  18437. var Point = _p.r(50);
  18438. // 注意,合并的结果是先执行m2,再执行m1的结果
  18439. function mergeMatrixData(m2, m1) {
  18440. return {
  18441. a: m1.a * m2.a + m1.c * m2.b,
  18442. b: m1.b * m2.a + m1.d * m2.b,
  18443. c: m1.a * m2.c + m1.c * m2.d,
  18444. d: m1.b * m2.c + m1.d * m2.d,
  18445. e: m1.a * m2.e + m1.c * m2.f + m1.e,
  18446. f: m1.b * m2.e + m1.d * m2.f + m1.f
  18447. };
  18448. }
  18449. function d2r(deg) {
  18450. return deg * Math.PI / 180;
  18451. }
  18452. var Matrix = _p.r(11).createClass("Matrix", {
  18453. constructor: function() {
  18454. if (arguments.length) {
  18455. this.setMatrix.apply(this, arguments);
  18456. } else {
  18457. this.setMatrix(1, 0, 0, 1, 0, 0);
  18458. }
  18459. },
  18460. translate: function(x, y) {
  18461. this.m = mergeMatrixData(this.m, {
  18462. a: 1,
  18463. c: 0,
  18464. e: x,
  18465. b: 0,
  18466. d: 1,
  18467. f: y
  18468. });
  18469. return this;
  18470. },
  18471. rotate: function(deg) {
  18472. var rad = d2r(deg);
  18473. var sin = Math.sin(rad), cos = Math.cos(rad);
  18474. this.m = mergeMatrixData(this.m, {
  18475. a: cos,
  18476. c: -sin,
  18477. e: 0,
  18478. b: sin,
  18479. d: cos,
  18480. f: 0
  18481. });
  18482. return this;
  18483. },
  18484. scale: function(sx, sy) {
  18485. if (sy === undefined) {
  18486. sy = sx;
  18487. }
  18488. this.m = mergeMatrixData(this.m, {
  18489. a: sx,
  18490. c: 0,
  18491. e: 0,
  18492. b: 0,
  18493. d: sy,
  18494. f: 0
  18495. });
  18496. return this;
  18497. },
  18498. skew: function(degX, degY) {
  18499. if (degY === undefined) {
  18500. degY = degX;
  18501. }
  18502. var tx = Math.tan(d2r(degX)), ty = Math.tan(d2r(degY));
  18503. this.m = mergeMatrixData(this.m, {
  18504. a: 1,
  18505. c: tx,
  18506. e: 0,
  18507. b: ty,
  18508. d: 1,
  18509. f: 0
  18510. });
  18511. return this;
  18512. },
  18513. /**
  18514. * 获得反转矩阵
  18515. *
  18516. * 这是我解方程算出来的
  18517. */
  18518. inverse: function() {
  18519. var m = this.m, a = m.a, b = m.b, c = m.c, d = m.d, e = m.e, f = m.f, k, aa, bb, cc, dd, ee, ff;
  18520. k = a * d - b * c;
  18521. aa = d / k;
  18522. bb = -b / k;
  18523. cc = -c / k;
  18524. dd = a / k;
  18525. ee = (c * f - e * d) / k;
  18526. ff = (b * e - a * f) / k;
  18527. return new Matrix(aa, bb, cc, dd, ee, ff);
  18528. },
  18529. setMatrix: function(a, b, c, d, e, f) {
  18530. if (arguments.length === 1) {
  18531. this.m = utils.clone(arguments[0]);
  18532. } else {
  18533. this.m = {
  18534. a: a,
  18535. b: b,
  18536. c: c,
  18537. d: d,
  18538. e: e,
  18539. f: f
  18540. };
  18541. }
  18542. return this;
  18543. },
  18544. getMatrix: function() {
  18545. return utils.clone(this.m);
  18546. },
  18547. getTranslate: function() {
  18548. var m = this.m;
  18549. return {
  18550. x: m.e / m.a,
  18551. y: m.f / m.d
  18552. };
  18553. },
  18554. mergeMatrix: function(matrix) {
  18555. return new Matrix(mergeMatrixData(this.m, matrix.m));
  18556. },
  18557. merge: function(matrix) {
  18558. return this.mergeMatrix(matrix);
  18559. },
  18560. toString: function() {
  18561. return this.valueOf().join(" ");
  18562. },
  18563. valueOf: function() {
  18564. var m = this.m;
  18565. return [ m.a, m.b, m.c, m.d, m.e, m.f ];
  18566. },
  18567. equals: function(matrix) {
  18568. var m1 = this.m, m2 = matrix.m;
  18569. return m1.a == m2.a && m1.b == m2.b && m1.c == m2.c && m1.d == m2.d && m1.e == m2.e && m1.f == m2.f;
  18570. },
  18571. transformPoint: function() {
  18572. return Matrix.transformPoint.apply(null, [].slice.call(arguments).concat([ this.m ]));
  18573. },
  18574. transformBox: function(box) {
  18575. return Matrix.transformBox(box, this.m);
  18576. },
  18577. clone: function() {
  18578. return new Matrix(this.m);
  18579. }
  18580. });
  18581. Matrix.parse = function(str) {
  18582. var match;
  18583. var f = parseFloat;
  18584. if (str instanceof Array) {
  18585. return new Matrix({
  18586. a: str[0],
  18587. b: str[1],
  18588. c: str[2],
  18589. d: str[3],
  18590. e: str[4],
  18591. f: str[5]
  18592. });
  18593. }
  18594. if (match = mPattern.exec(str)) {
  18595. var values = match[1].split(",");
  18596. if (values.length != 6) {
  18597. values = match[1].split(" ");
  18598. }
  18599. return new Matrix({
  18600. a: f(values[0]),
  18601. b: f(values[1]),
  18602. c: f(values[2]),
  18603. d: f(values[3]),
  18604. e: f(values[4]),
  18605. f: f(values[5])
  18606. });
  18607. }
  18608. return new Matrix();
  18609. };
  18610. Matrix.transformPoint = function(x, y, m) {
  18611. if (arguments.length === 2) {
  18612. m = y;
  18613. y = x.y;
  18614. x = x.x;
  18615. }
  18616. return new Point(m.a * x + m.c * y + m.e, m.b * x + m.d * y + m.f);
  18617. };
  18618. Matrix.transformBox = function(box, matrix) {
  18619. var xMin = Number.MAX_VALUE, xMax = -Number.MAX_VALUE, yMin = Number.MAX_VALUE, yMax = -Number.MAX_VALUE;
  18620. var bps = [ [ box.x, box.y ], [ box.x + box.width, box.y ], [ box.x, box.y + box.height ], [ box.x + box.width, box.y + box.height ] ];
  18621. var bp, rp, rps = [];
  18622. while (bp = bps.pop()) {
  18623. rp = Matrix.transformPoint(bp[0], bp[1], matrix);
  18624. rps.push(rp);
  18625. xMin = Math.min(xMin, rp.x);
  18626. xMax = Math.max(xMax, rp.x);
  18627. yMin = Math.min(yMin, rp.y);
  18628. yMax = Math.max(yMax, rp.y);
  18629. }
  18630. box = new Box({
  18631. x: xMin,
  18632. y: yMin,
  18633. width: xMax - xMin,
  18634. height: yMax - yMin
  18635. });
  18636. utils.extend(box, {
  18637. closurePoints: rps
  18638. });
  18639. return box;
  18640. };
  18641. // 获得从 node 到 refer 的变换矩阵
  18642. Matrix.getCTM = function(target, refer) {
  18643. var ctm = {
  18644. a: 1,
  18645. b: 0,
  18646. c: 0,
  18647. d: 1,
  18648. e: 0,
  18649. f: 0
  18650. };
  18651. var node = target.shapeNode || target.node;
  18652. refer = refer || "parent";
  18653. // 根据参照坐标系选区的不一样,返回不同的结果
  18654. switch (refer) {
  18655. case "screen":
  18656. // 以浏览器屏幕为参照坐标系
  18657. ctm = node.getScreenCTM();
  18658. break;
  18659. case "doc":
  18660. case "paper":
  18661. // 以文档(Paper)为参照坐标系
  18662. ctm = node.getCTM();
  18663. break;
  18664. case "view":
  18665. case "top":
  18666. // 以顶层绘图容器(视野)为参照坐标系
  18667. if (target.getPaper()) {
  18668. ctm = node.getTransformToElement(target.getPaper().shapeNode);
  18669. }
  18670. break;
  18671. case "parent":
  18672. // 以父容器为参照坐标系
  18673. if (target.node.parentNode) {
  18674. ctm = node.getTransformToElement(target.node.parentNode);
  18675. }
  18676. break;
  18677. default:
  18678. // 其他情况,指定参照物
  18679. if (refer.node) {
  18680. ctm = node.getTransformToElement(refer.shapeNode || refer.node);
  18681. }
  18682. }
  18683. return ctm ? new Matrix(ctm.a, ctm.b, ctm.c, ctm.d, ctm.e, ctm.f) : new Matrix();
  18684. };
  18685. return Matrix;
  18686. }
  18687. };
  18688. //src/graphic/palette.js
  18689. /**
  18690. * 调色板
  18691. */
  18692. _p[44] = {
  18693. value: function(require, exports, module) {
  18694. //标准color
  18695. var StandardColor = _p.r(64), Color = _p.r(28), Utils = _p.r(12);
  18696. var Palette = _p.r(11).createClass("Palette", {
  18697. constructor: function() {
  18698. this.color = {};
  18699. },
  18700. /*
  18701. * 获取颜色名称所对应的颜色值的Color对象
  18702. * @param name 需要获取的颜色名称
  18703. * @return 对应颜色名称的color对象, 如果未找到对应的名称, 则返回null
  18704. */
  18705. get: function(name) {
  18706. var colorValue = this.color[name] || StandardColor.EXTEND_STANDARD[name] || StandardColor.COLOR_STANDARD[name] || "";
  18707. if (colorValue) {
  18708. return new Color(colorValue);
  18709. }
  18710. return null;
  18711. },
  18712. /*
  18713. * 获取给定名称的颜色的hex值表示
  18714. * @param name 需要获取的颜色名称
  18715. * @return 如果找到对应的名称, 则返回该名称所对应的hex格式的值, 否则, 返回一个空字符串
  18716. */
  18717. getColorValue: function(name) {
  18718. return this.color[name] || StandardColor.EXTEND_STANDARD[name] || StandardColor.COLOR_STANDARD[name] || "";
  18719. },
  18720. /*
  18721. * 向调色板实例添加自己独有的颜色名称,对已存在的颜色名称, 将会覆盖掉
  18722. * @param name 新添加的颜色名称
  18723. * @param value 新添加的颜色名称所对应的值, 可以是一个合法的颜色字符串或者是一个color对象
  18724. * @return 新添加的颜色的值
  18725. */
  18726. add: function(name, value) {
  18727. if (typeof value === "string") {
  18728. this.color[name] = new Color(value).toRGBA();
  18729. } else {
  18730. this.color[name] = value.toRGBA();
  18731. }
  18732. return value;
  18733. },
  18734. /*
  18735. * 删除调色板实例上用户自己添加的颜色, 该方法不能删除内置的颜色
  18736. * @param name 需要删除的颜色名称
  18737. * @return 删除是否成功的bool值
  18738. */
  18739. remove: function(name) {
  18740. if (this.color.hasOwnProperty(name)) {
  18741. delete this.color[name];
  18742. return true;
  18743. }
  18744. return false;
  18745. }
  18746. });
  18747. Utils.extend(Palette, {
  18748. getColor: function(name) {
  18749. var colorValue = StandardColor.EXTEND_STANDARD[name] || StandardColor.COLOR_STANDARD[name];
  18750. if (colorValue) {
  18751. return new Color(colorValue);
  18752. }
  18753. return null;
  18754. },
  18755. /*
  18756. * 通过给定的名字获取标准的颜色值表示, 返回的值以hex的方式提供
  18757. * @param name 需要获取的标准颜色名称
  18758. * @return 名字所对应的颜色值的hex表示, 如果未找到对应名称的值, 则返回一个空字符串
  18759. */
  18760. getColorValue: function(name) {
  18761. return StandardColor.EXTEND_STANDARD[name] || StandardColor.COLOR_STANDARD[name] || "";
  18762. },
  18763. /*
  18764. * 向调色板添加颜色名称,新添加的颜色对所有的调色板对象都可见
  18765. * 对已存在的颜色名称, 将会覆盖掉
  18766. * @param name 新添加的颜色名称
  18767. * @param value 新添加的颜色名称所对于的值, 应该是一个hex格式的颜色字符串, 如: ”#ff0000“
  18768. * @return 新添加的颜色的值
  18769. */
  18770. addColor: function(name, value) {
  18771. if (typeof value === "string") {
  18772. StandardColor.EXTEND_STANDARD[name] = new Color(value).toRGBA();
  18773. } else {
  18774. StandardColor.EXTEND_STANDARD[name] = value.toRGBA();
  18775. }
  18776. return value;
  18777. },
  18778. /*
  18779. * 删除用户自己添加的颜色, 该方法不能删除内置的颜色, 该方法不会影响调色板实例自由的颜色
  18780. * @param name 需要删除的颜色名称
  18781. * @return 删除是否成功的bool值
  18782. */
  18783. removeColor: function(name) {
  18784. if (StandardColor.EXTEND_STANDARD.hasOwnProperty(name)) {
  18785. delete StandardColor.EXTEND_STANDARD[name];
  18786. return true;
  18787. }
  18788. return false;
  18789. }
  18790. });
  18791. return Palette;
  18792. }
  18793. };
  18794. //src/graphic/paper.js
  18795. _p[45] = {
  18796. value: function(require, exports, module) {
  18797. var Class = _p.r(11);
  18798. var utils = _p.r(12);
  18799. var svg = _p.r(67);
  18800. var Container = _p.r(29);
  18801. var ShapeContainer = _p.r(61);
  18802. var ViewBox = _p.r(75);
  18803. var EventHandler = _p.r(33);
  18804. var Styled = _p.r(66);
  18805. var Matrix = _p.r(43);
  18806. var Paper = Class.createClass("Paper", {
  18807. mixins: [ ShapeContainer, EventHandler, Styled, ViewBox ],
  18808. constructor: function(container) {
  18809. this.callBase();
  18810. this.node = this.createSVGNode();
  18811. this.node.paper = this;
  18812. this.node.appendChild(this.resourceNode = svg.createNode("defs"));
  18813. this.node.appendChild(this.shapeNode = svg.createNode("g"));
  18814. this.resources = new Container();
  18815. this.setWidth("100%").setHeight("100%");
  18816. if (container) {
  18817. this.renderTo(container);
  18818. }
  18819. this.callMixin();
  18820. },
  18821. renderTo: function(container) {
  18822. if (utils.isString(container)) {
  18823. container = document.getElementById(container);
  18824. }
  18825. this.container = container;
  18826. container.appendChild(this.node);
  18827. },
  18828. createSVGNode: function() {
  18829. var node = svg.createNode("svg");
  18830. node.setAttribute("xmlns", "http://www.w3.org/2000/svg");
  18831. node.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
  18832. node.setAttribute("version", "1.1");
  18833. return node;
  18834. },
  18835. getNode: function() {
  18836. return this.node;
  18837. },
  18838. getContainer: function() {
  18839. return this.container;
  18840. },
  18841. getWidth: function() {
  18842. return this.node.clientWidth;
  18843. },
  18844. setWidth: function(width) {
  18845. this.node.setAttribute("width", width);
  18846. return this;
  18847. },
  18848. getHeight: function() {
  18849. return this.node.clientHeight;
  18850. },
  18851. setHeight: function(height) {
  18852. this.node.setAttribute("height", height);
  18853. return this;
  18854. },
  18855. setViewPort: function(cx, cy, zoom) {
  18856. var viewport, box;
  18857. if (arguments.length == 1) {
  18858. viewport = arguments[0];
  18859. cx = viewport.center.x;
  18860. cy = viewport.center.y;
  18861. zoom = viewport.zoom;
  18862. }
  18863. zoom = zoom || 1;
  18864. box = this.getViewBox();
  18865. var matrix = new Matrix();
  18866. var dx = box.x + box.width / 2 - cx, dy = box.y + box.height / 2 - cy;
  18867. matrix.translate(-cx, -cy);
  18868. matrix.scale(zoom);
  18869. matrix.translate(cx, cy);
  18870. matrix.translate(dx, dy);
  18871. this.shapeNode.setAttribute("transform", "matrix(" + matrix + ")");
  18872. this.viewport = {
  18873. center: {
  18874. x: cx,
  18875. y: cy
  18876. },
  18877. offset: {
  18878. x: dx,
  18879. y: dy
  18880. },
  18881. zoom: zoom
  18882. };
  18883. return this;
  18884. },
  18885. getViewPort: function() {
  18886. if (!this.viewport) {
  18887. var box = this.getViewBox();
  18888. return {
  18889. zoom: 1,
  18890. center: {
  18891. x: box.x + box.width / 2,
  18892. y: box.y + box.height / 2
  18893. },
  18894. offset: {
  18895. x: 0,
  18896. y: 0
  18897. }
  18898. };
  18899. }
  18900. return this.viewport;
  18901. },
  18902. getViewPortMatrix: function() {
  18903. return Matrix.parse(this.shapeNode.getAttribute("transform"));
  18904. },
  18905. getViewPortTransform: function() {
  18906. var m = this.shapeNode.getCTM();
  18907. return new Matrix(m.a, m.b, m.c, m.d, m.e, m.f);
  18908. },
  18909. getTransform: function() {
  18910. return this.getViewPortTransform().reverse();
  18911. },
  18912. addResource: function(resource) {
  18913. this.resources.appendItem(resource);
  18914. if (resource.node) {
  18915. this.resourceNode.appendChild(resource.node);
  18916. }
  18917. return this;
  18918. },
  18919. removeResource: function(resource) {
  18920. if (resource.remove) {
  18921. resource.remove();
  18922. }
  18923. if (resource.node) {
  18924. this.resourceNode.removeChild(resource.node);
  18925. }
  18926. return this;
  18927. },
  18928. getPaper: function() {
  18929. return this;
  18930. }
  18931. });
  18932. var Shape = _p.r(60);
  18933. Class.extendClass(Shape, {
  18934. getPaper: function() {
  18935. var parent = this.container;
  18936. while (parent && parent instanceof Paper === false) {
  18937. parent = parent.container;
  18938. }
  18939. return parent;
  18940. },
  18941. isAttached: function() {
  18942. return !!this.getPaper();
  18943. },
  18944. whenPaperReady: function(fn) {
  18945. var me = this;
  18946. function check() {
  18947. var paper = me.getPaper();
  18948. if (paper && fn) {
  18949. fn.call(me, paper);
  18950. }
  18951. return paper;
  18952. }
  18953. if (!check()) {
  18954. this.on("add treeadd", function listen() {
  18955. if (check()) {
  18956. me.off("add", listen);
  18957. me.off("treeadd", listen);
  18958. }
  18959. });
  18960. }
  18961. return this;
  18962. }
  18963. });
  18964. return Paper;
  18965. }
  18966. };
  18967. //src/graphic/path.js
  18968. _p[46] = {
  18969. value: function(require, exports, module) {
  18970. var Utils = _p.r(12);
  18971. var createClass = _p.r(11).createClass;
  18972. var Shape = _p.r(60);
  18973. var svg = _p.r(67);
  18974. var g = _p.r(34);
  18975. var slice = Array.prototype.slice, flatten = Utils.flatten;
  18976. var PathDrawer = createClass("PathDrawer", {
  18977. constructor: function(path) {
  18978. this.segment = [];
  18979. this.path = path;
  18980. this.__clear = false;
  18981. },
  18982. getPath: function() {
  18983. return this.path;
  18984. },
  18985. redraw: function() {
  18986. this._transation = this._transation || [];
  18987. return this.clear();
  18988. },
  18989. done: function() {
  18990. var transation = this._transation;
  18991. this._transation = null;
  18992. this.push(transation);
  18993. return this;
  18994. },
  18995. clear: function() {
  18996. if (this._transation) {
  18997. this._transation = [];
  18998. } else {
  18999. this.path.setPathData("M 0 0");
  19000. }
  19001. this._clear = true;
  19002. return this;
  19003. },
  19004. push: function() {
  19005. var segment = slice.call(arguments);
  19006. var originData;
  19007. if (this._transation) {
  19008. this._transation.push(segment);
  19009. return this;
  19010. }
  19011. if (this._clear) {
  19012. originData = "";
  19013. this._clear = false;
  19014. } else {
  19015. originData = this.path.getPathData();
  19016. }
  19017. originData = originData || "";
  19018. this.path.setPathData(originData + g.pathToString(segment));
  19019. return this;
  19020. },
  19021. moveTo: function(x, y) {
  19022. return this.push("M", slice.call(arguments));
  19023. },
  19024. moveBy: function(dx, dy) {
  19025. return this.push("m", slice.call(arguments));
  19026. },
  19027. lineTo: function(x, y) {
  19028. return this.push("L", slice.call(arguments));
  19029. },
  19030. lineBy: function(dx, dy) {
  19031. return this.push("l", slice.call(arguments));
  19032. },
  19033. arcTo: function(rx, ry, xr, laf, sf, x, y) {
  19034. return this.push("A", slice.call(arguments));
  19035. },
  19036. arcBy: function(rx, ry, xr, laf, sf, dx, dy) {
  19037. return this.push("a", arguments);
  19038. },
  19039. carcTo: function(r, laf, sf, x, y) {
  19040. return this.push("A", [ r, r, 0 ].concat(slice.call(arguments, 1)));
  19041. },
  19042. carcBy: function(r, laf, sf, dx, dy) {
  19043. return this.push("a", [ r, r, 0 ].concat(slice.call(arguments, 1)));
  19044. },
  19045. bezierTo: function(x1, y1, x2, y2, x, y) {
  19046. return this.push("C", slice.call(arguments));
  19047. },
  19048. bezierBy: function(dx1, dy1, dx2, dy2, dx, dy) {
  19049. return this.push("c", slice.call(arguments));
  19050. },
  19051. close: function() {
  19052. return this.push("z");
  19053. }
  19054. });
  19055. return createClass("Path", {
  19056. base: Shape,
  19057. constructor: function(data) {
  19058. this.callBase("path");
  19059. if (data) {
  19060. this.setPathData(data);
  19061. }
  19062. this.node.setAttribute("fill", svg.defaults.fill);
  19063. this.node.setAttribute("stroke", svg.defaults.stroke);
  19064. },
  19065. setPathData: function(data) {
  19066. data = data || "M0,0";
  19067. this.pathdata = g.pathToString(data);
  19068. this.node.setAttribute("d", this.pathdata);
  19069. this.trigger("shapeupdate", {
  19070. type: "pathdata"
  19071. });
  19072. return this;
  19073. },
  19074. getPathData: function() {
  19075. return this.pathdata || "";
  19076. },
  19077. getDrawer: function() {
  19078. return new PathDrawer(this);
  19079. },
  19080. isClosed: function() {
  19081. var data = this.getPathData();
  19082. return !!~data.indexOf("z") || !!~data.indexOf("Z");
  19083. }
  19084. });
  19085. }
  19086. };
  19087. //src/graphic/pattern.js
  19088. _p[47] = {
  19089. value: function(require, exports, module) {
  19090. var Resource = _p.r(58);
  19091. var ShapeContainer = _p.r(61);
  19092. var svg = _p.r(67);
  19093. return _p.r(11).createClass("PatternBrush", {
  19094. base: Resource,
  19095. mixins: [ ShapeContainer ],
  19096. constructor: function(paper) {
  19097. this.callBase("pattern", paper);
  19098. this.node.setAttribute("patternUnits", "userSpaceOnUse");
  19099. },
  19100. setX: function(x) {
  19101. this.x = x;
  19102. this.node.setAttribute("x", x);
  19103. return this;
  19104. },
  19105. setY: function(y) {
  19106. this.y = y;
  19107. this.node.setAttribute("y", y);
  19108. return this;
  19109. },
  19110. setWidth: function(width) {
  19111. this.width = width;
  19112. this.node.setAttribute("width", width);
  19113. return this;
  19114. },
  19115. setHeight: function(height) {
  19116. this.height = height;
  19117. this.node.setAttribute("height", height);
  19118. return this;
  19119. },
  19120. getWidth: function() {
  19121. return this.width;
  19122. },
  19123. getHeight: function() {
  19124. return this.height;
  19125. }
  19126. });
  19127. }
  19128. };
  19129. //src/graphic/pen.js
  19130. _p[48] = {
  19131. value: function(require, exports, module) {
  19132. var Color = _p.r(28);
  19133. return _p.r(11).createClass("Pen", {
  19134. constructor: function(brush, width) {
  19135. this.brush = brush;
  19136. this.width = width || 1;
  19137. this.linecap = null;
  19138. this.linejoin = null;
  19139. this.dashArray = null;
  19140. this.opacity = 1;
  19141. },
  19142. getBrush: function() {
  19143. return this.brush;
  19144. },
  19145. setBrush: function(brush) {
  19146. this.brush = brush;
  19147. return this;
  19148. },
  19149. setColor: function(color) {
  19150. return this.setBrush(color);
  19151. },
  19152. getColor: function() {
  19153. return this.brush instanceof Color ? this.brush : null;
  19154. },
  19155. getWidth: function() {
  19156. return this.width;
  19157. },
  19158. setWidth: function(width) {
  19159. this.width = width;
  19160. return this;
  19161. },
  19162. getOpacity: function() {
  19163. return this.opacity;
  19164. },
  19165. setOpacity: function(opacity) {
  19166. this.opacity = opacity;
  19167. },
  19168. getLineCap: function() {
  19169. return this.linecap;
  19170. },
  19171. setLineCap: function(linecap) {
  19172. this.linecap = linecap;
  19173. return this;
  19174. },
  19175. getLineJoin: function() {
  19176. return this.linejoin;
  19177. },
  19178. setLineJoin: function(linejoin) {
  19179. this.linejoin = linejoin;
  19180. return this;
  19181. },
  19182. getDashArray: function() {
  19183. return this.dashArray;
  19184. },
  19185. setDashArray: function(dashArray) {
  19186. this.dashArray = dashArray;
  19187. return this;
  19188. },
  19189. stroke: function(shape) {
  19190. var node = shape.node;
  19191. node.setAttribute("stroke", this.brush.toString());
  19192. node.setAttribute("stroke-width", this.getWidth());
  19193. if (this.getOpacity() < 1) {
  19194. node.setAttribute("stroke-opacity", this.getOpacity());
  19195. }
  19196. if (this.getLineCap()) {
  19197. node.setAttribute("stroke-linecap", this.getLineCap());
  19198. }
  19199. if (this.getLineJoin()) {
  19200. node.setAttribute("stroke-linejoin", this.getLineJoin());
  19201. }
  19202. if (this.getDashArray()) {
  19203. node.setAttribute("stroke-dasharray", this.getDashArray());
  19204. }
  19205. }
  19206. });
  19207. }
  19208. };
  19209. //src/graphic/pie.js
  19210. _p[49] = {
  19211. value: function(require, exports, module) {
  19212. return _p.r(11).createClass({
  19213. base: _p.r(68),
  19214. constructor: function(radius, angle, angleOffset) {
  19215. this.callBase([ 0, radius ], angle, angleOffset);
  19216. },
  19217. getRadius: function() {
  19218. return this.getSectionArray()[1];
  19219. },
  19220. setRadius: function(radius) {
  19221. this.setSectionArray([ 0, radius ]);
  19222. }
  19223. });
  19224. }
  19225. };
  19226. //src/graphic/point.js
  19227. /*
  19228. * 点对象抽象
  19229. */
  19230. _p[50] = {
  19231. value: function(require, exports, module) {
  19232. /**
  19233. * @class kity.Point
  19234. * @description 表示一个点
  19235. */
  19236. var Point = _p.r(11).createClass("Point", {
  19237. /**
  19238. * @constructor
  19239. * @for kity.Point
  19240. * @description 指定默认的 x 和 y 创建一个点
  19241. *
  19242. * @param {Number} x 点的 x 坐标
  19243. * @param {Number} y 点的 y 坐标
  19244. */
  19245. constructor: function(x, y) {
  19246. /**
  19247. * @property
  19248. * @for kity.Point
  19249. * @description 表示点的 x 坐标
  19250. * @type {Number}
  19251. */
  19252. this.x = x || 0;
  19253. /**
  19254. * @property
  19255. * @for kity.Point
  19256. * @description 表示点的 y 坐标
  19257. * @type {Number}
  19258. */
  19259. this.y = y || 0;
  19260. },
  19261. offset: function(dx, dy) {
  19262. if (arguments.length == 1) {
  19263. dy = dx.y;
  19264. dx = dx.x;
  19265. }
  19266. return new Point(this.x + dx, this.y + dy);
  19267. },
  19268. valueOf: function() {
  19269. return [ this.x, this.y ];
  19270. },
  19271. toString: function() {
  19272. return this.valueOf().join(" ");
  19273. },
  19274. spof: function() {
  19275. return new Point((this.x | 0) + .5, (this.y | 0) + .5);
  19276. },
  19277. round: function() {
  19278. return new Point(this.x | 0, this.y | 0);
  19279. },
  19280. isOrigin: function() {
  19281. return this.x === 0 && this.y === 0;
  19282. }
  19283. });
  19284. /**
  19285. * @static
  19286. * @method fromPolar()
  19287. * @for kity.Point
  19288. * @grammar kity.Point.fromPolar(radius, angle, unit) => kity.Point
  19289. * @param {Number} radius 极坐标中的半径
  19290. * @param {Number} angle 极坐标中的角度
  19291. * @param {String} unit 角度使用的单位,默认为 'deg' (角度),可以取值为 'rad',表示传入的是弧度值
  19292. */
  19293. Point.fromPolar = function(radius, angle, unit) {
  19294. if (unit != "rad") {
  19295. // deg to rad
  19296. angle = angle / 180 * Math.PI;
  19297. }
  19298. return new Point(radius * Math.cos(angle), radius * Math.sin(angle));
  19299. };
  19300. Point.parse = function(unknown) {
  19301. if (!unknown) return new Point();
  19302. if (unknown instanceof Point) {
  19303. return unknown;
  19304. }
  19305. if (typeof unknown == "string") {
  19306. return Point.parse(unknown.split(/\s*[\s,]\s*/));
  19307. }
  19308. if ("0" in unknown && "1" in unknown) {
  19309. return new Point(unknown[0], unknown[1]);
  19310. }
  19311. };
  19312. return Point;
  19313. }
  19314. };
  19315. //src/graphic/pointcontainer.js
  19316. /**
  19317. * 点集合容器
  19318. */
  19319. _p[51] = {
  19320. value: function(require, exports, module) {
  19321. return _p.r(11).createClass("PointContainer", {
  19322. base: _p.r(29),
  19323. constructor: function() {
  19324. this.callBase();
  19325. },
  19326. addPoint: function(point, pos) {
  19327. return this.addItem.apply(this, arguments);
  19328. },
  19329. prependPoint: function() {
  19330. return this.prependItem.apply(this, arguments);
  19331. },
  19332. appendPoint: function() {
  19333. return this.appendItem.apply(this, arguments);
  19334. },
  19335. removePoint: function(pos) {
  19336. return this.removeItem.apply(this, arguments);
  19337. },
  19338. addPoints: function() {
  19339. return this.addItems.apply(this, arguments);
  19340. },
  19341. setPoints: function() {
  19342. return this.setItems.apply(this, arguments);
  19343. },
  19344. getPoint: function() {
  19345. return this.getItem.apply(this, arguments);
  19346. },
  19347. getPoints: function() {
  19348. return this.getItems.apply(this, arguments);
  19349. },
  19350. getFirstPoint: function() {
  19351. return this.getFirstItem.apply(this, arguments);
  19352. },
  19353. getLastPoint: function() {
  19354. return this.getLastItem.apply(this, arguments);
  19355. }
  19356. });
  19357. }
  19358. };
  19359. //src/graphic/poly.js
  19360. /*
  19361. * 通过点来决定图形的公共父类
  19362. */
  19363. _p[52] = {
  19364. value: function(require, exports, module) {
  19365. var Utils = _p.r(12);
  19366. return _p.r(11).createClass("Poly", {
  19367. base: _p.r(46),
  19368. mixins: [ _p.r(51) ],
  19369. constructor: function(points, closeable) {
  19370. this.callBase();
  19371. //是否可闭合
  19372. this.closeable = !!closeable;
  19373. this.setPoints(points || []);
  19374. this.changeable = true;
  19375. this.update();
  19376. },
  19377. //当点集合发生变化时采取的动作
  19378. onContainerChanged: function() {
  19379. if (this.changeable) {
  19380. this.update();
  19381. }
  19382. },
  19383. update: function() {
  19384. var drawer = this.getDrawer(), points = this.getPoints();
  19385. drawer.clear();
  19386. if (!points.length) {
  19387. return this;
  19388. }
  19389. drawer.moveTo(points[0]);
  19390. for (var i = 1, point, len = points.length; i < len; i++) {
  19391. point = points[i];
  19392. drawer.lineTo(point);
  19393. }
  19394. if (this.closeable && points.length > 2) {
  19395. drawer.close();
  19396. }
  19397. return this;
  19398. }
  19399. });
  19400. }
  19401. };
  19402. //src/graphic/polygon.js
  19403. _p[53] = {
  19404. value: function(require, exports, module) {
  19405. return _p.r(11).createClass("Polygon", {
  19406. base: _p.r(52),
  19407. constructor: function(points) {
  19408. this.callBase(points, true);
  19409. }
  19410. });
  19411. }
  19412. };
  19413. //src/graphic/polyline.js
  19414. _p[54] = {
  19415. value: function(require, exports, module) {
  19416. return _p.r(11).createClass("Polyline", {
  19417. base: _p.r(52),
  19418. constructor: function(points) {
  19419. this.callBase(points);
  19420. }
  19421. });
  19422. }
  19423. };
  19424. //src/graphic/radialgradient.js
  19425. _p[55] = {
  19426. value: function(require, exports, module) {
  19427. var Gradient = _p.r(35);
  19428. return _p.r(11).createClass("RadialGradientBrush", {
  19429. base: Gradient,
  19430. constructor: function(paper) {
  19431. this.callBase("radialGradient", paper);
  19432. this.setCenter(.5, .5);
  19433. this.setFocal(.5, .5);
  19434. this.setRadius(.5);
  19435. },
  19436. setCenter: function(cx, cy) {
  19437. this.node.setAttribute("cx", cx);
  19438. this.node.setAttribute("cy", cy);
  19439. return this;
  19440. },
  19441. getCenter: function() {
  19442. return {
  19443. x: +this.node.getAttribute("cx"),
  19444. y: +this.node.getAttribute("cy")
  19445. };
  19446. },
  19447. setFocal: function(fx, fy) {
  19448. this.node.setAttribute("fx", fx);
  19449. this.node.setAttribute("fy", fy);
  19450. return this;
  19451. },
  19452. getFocal: function() {
  19453. return {
  19454. x: +this.node.getAttribute("fx"),
  19455. y: +this.node.getAttribute("fy")
  19456. };
  19457. },
  19458. setRadius: function(r) {
  19459. this.node.setAttribute("r", r);
  19460. return this;
  19461. },
  19462. getRadius: function() {
  19463. return +this.node.getAttribute("r");
  19464. }
  19465. });
  19466. }
  19467. };
  19468. //src/graphic/rect.js
  19469. _p[56] = {
  19470. value: function(require, exports, module) {
  19471. var RectUtils = {}, Utils = _p.r(12), Point = _p.r(50), Box = _p.r(25);
  19472. Utils.extend(RectUtils, {
  19473. //根据传递进来的width、height和radius属性,
  19474. //获取最适合的radius值
  19475. formatRadius: function(width, height, radius) {
  19476. var minValue = Math.floor(Math.min(width / 2, height / 2));
  19477. return Math.min(minValue, radius);
  19478. }
  19479. });
  19480. /**
  19481. * @class kity.Rect
  19482. * @description 表示一个矩形
  19483. * @base kity.Path
  19484. */
  19485. var Rect = _p.r(11).createClass("Rect", {
  19486. base: _p.r(46),
  19487. /**
  19488. * @constructor
  19489. * @for kity.Rect
  19490. * @grammar new kity.Rect(width, height, x, y, radius)
  19491. * @param {Number} width 矩形的初始化宽度
  19492. * @param {Number} height 矩形的初始化高度
  19493. * @param {Number} x 矩形的初始化 x 坐标
  19494. * @param {Number} y 矩形的初始化 y 坐标
  19495. * @param {Number} radius 矩形的初始化圆角大小
  19496. */
  19497. constructor: function(width, height, x, y, radius) {
  19498. this.callBase();
  19499. this.x = x || 0;
  19500. this.y = y || 0;
  19501. this.width = width || 0;
  19502. this.height = height || 0;
  19503. this.radius = RectUtils.formatRadius(this.width, this.height, radius || 0);
  19504. this.update();
  19505. },
  19506. update: function() {
  19507. var x = this.x, y = this.y, w = this.width, h = this.height, r = this.radius;
  19508. var drawer = this.getDrawer().redraw();
  19509. if (!r) {
  19510. // 直角
  19511. drawer.push("M", x, y);
  19512. drawer.push("h", w);
  19513. drawer.push("v", h);
  19514. drawer.push("h", -w);
  19515. drawer.push("z");
  19516. } else {
  19517. //圆角
  19518. w -= 2 * r;
  19519. h -= 2 * r;
  19520. drawer.push("M", x + r, y);
  19521. drawer.push("h", w);
  19522. drawer.push("a", r, r, 0, 0, 1, r, r);
  19523. drawer.push("v", h);
  19524. drawer.push("a", r, r, 0, 0, 1, -r, r);
  19525. drawer.push("h", -w);
  19526. drawer.push("a", r, r, 0, 0, 1, -r, -r);
  19527. drawer.push("v", -h);
  19528. drawer.push("a", r, r, 0, 0, 1, r, -r);
  19529. drawer.push("z");
  19530. }
  19531. drawer.done();
  19532. return this;
  19533. },
  19534. /**
  19535. * @method setWidth
  19536. * @for kity.Rect
  19537. * @grammar setWidth(width) => kity.Rect
  19538. * @description 设置矩形的宽度,设置后返回矩形实例本身
  19539. * @param {Number} width 宽度值
  19540. *
  19541. * @example
  19542. * ```js
  19543. * rect.setWidth(300);
  19544. * ```
  19545. */
  19546. setWidth: function(width) {
  19547. this.width = width;
  19548. return this.update();
  19549. },
  19550. /**
  19551. * @method setHeight
  19552. * @for kity.Rect
  19553. * @grammar setHeight(height) => kity.Rect
  19554. * @description 设置矩形的高度,设置后返回矩形实例本身
  19555. * @param {Number} height 高度值
  19556. *
  19557. * @example
  19558. * ```js
  19559. * rect.setHeight(200);
  19560. * ```
  19561. */
  19562. setHeight: function(height) {
  19563. this.height = height;
  19564. return this.update();
  19565. },
  19566. /**
  19567. * @method setSize
  19568. * @for kity.Rect
  19569. * @grammar setSize(width, height) => kity.Rect
  19570. * @description 设置矩形的尺寸,设置后返回矩形本身
  19571. * @param {Number} width 矩形的宽度值
  19572. * @param {Number} height 矩形的高度值
  19573. *
  19574. * @example
  19575. * ```js
  19576. * rect.setSize(300, 200);
  19577. * ```
  19578. */
  19579. setSize: function(width, height) {
  19580. this.width = width;
  19581. this.height = height;
  19582. return this.update();
  19583. },
  19584. /**
  19585. * @method setBox
  19586. * @for kity.Rect
  19587. * @grammar setBox(box) => kity.Rect
  19588. * @description 使用一个 kity 的盒子数据,
  19589. * @param {kity.Box} box 盒子数据
  19590. */
  19591. setBox: function(box) {
  19592. this.x = box.x;
  19593. this.y = box.y;
  19594. this.width = box.width;
  19595. this.height = box.height;
  19596. return this.update();
  19597. },
  19598. getBox: function() {
  19599. return new Box(this.x, this.y, this.width, this.height);
  19600. },
  19601. getRadius: function() {
  19602. return this.radius;
  19603. },
  19604. setRadius: function(radius) {
  19605. this.radius = RectUtils.formatRadius(this.width, this.height, radius || 0);
  19606. return this.update();
  19607. },
  19608. getPosition: function() {
  19609. return new Point(this.x, this.y);
  19610. },
  19611. setPosition: function(x, y) {
  19612. if (arguments.length == 1) {
  19613. var p = Point.parse(arguments[0]);
  19614. y = p.y;
  19615. x = p.x;
  19616. }
  19617. this.x = x;
  19618. this.y = y;
  19619. return this.update();
  19620. },
  19621. getWidth: function() {
  19622. return this.width;
  19623. },
  19624. getHeight: function() {
  19625. return this.height;
  19626. },
  19627. getPositionX: function() {
  19628. return this.x;
  19629. },
  19630. getPositionY: function() {
  19631. return this.y;
  19632. },
  19633. setPositionX: function(x) {
  19634. this.x = x;
  19635. return this.update();
  19636. },
  19637. setPositionY: function(y) {
  19638. this.y = y;
  19639. return this.update();
  19640. }
  19641. });
  19642. return Rect;
  19643. }
  19644. };
  19645. //src/graphic/regularpolygon.js
  19646. _p[57] = {
  19647. value: function(require, exports, module) {
  19648. var Point = _p.r(50);
  19649. return _p.r(11).createClass("RegularPolygon", {
  19650. base: _p.r(46),
  19651. constructor: function(side, radius, x, y) {
  19652. this.callBase();
  19653. this.radius = radius || 0;
  19654. this.side = Math.max(side || 3, 3);
  19655. if (arguments.length > 2) {
  19656. if (arguments.length == 3) {
  19657. y = x.y;
  19658. x = x.x;
  19659. }
  19660. }
  19661. this.center = new Point(x, y);
  19662. this.draw();
  19663. },
  19664. getSide: function() {
  19665. return this.side;
  19666. },
  19667. setSide: function(side) {
  19668. this.side = side;
  19669. return this.draw();
  19670. },
  19671. getRadius: function() {
  19672. return this.radius;
  19673. },
  19674. setRadius: function(radius) {
  19675. this.radius = radius;
  19676. return this.draw();
  19677. },
  19678. draw: function() {
  19679. var radius = this.radius, side = this.side, step = Math.PI * 2 / side, drawer = this.getDrawer(), i;
  19680. drawer.clear();
  19681. drawer.moveTo(Point.fromPolar(radius, Math.PI / 2, "rad").offset(this.center));
  19682. for (i = 0; i <= side; i++) {
  19683. drawer.lineTo(Point.fromPolar(radius, step * i + Math.PI / 2, "rad").offset(this.center));
  19684. }
  19685. drawer.close();
  19686. return this;
  19687. }
  19688. });
  19689. }
  19690. };
  19691. //src/graphic/resource.js
  19692. /**
  19693. * @fileOverview
  19694. *
  19695. * 资源节点基类
  19696. *
  19697. * @author: techird
  19698. * @copyright: Baidu FEX, 2014
  19699. */
  19700. _p[58] = {
  19701. value: function(require, exports, module) {
  19702. var svg = _p.r(67);
  19703. return _p.r(11).createClass("Resource", {
  19704. constructor: function(nodeType, paper) {
  19705. this.callBase();
  19706. this.node = svg.createNode(nodeType);
  19707. if (paper) {
  19708. paper.addResource(this);
  19709. }
  19710. },
  19711. toString: function() {
  19712. return "url(#" + this.node.id + ")";
  19713. }
  19714. });
  19715. }
  19716. };
  19717. //src/graphic/ring.js
  19718. _p[59] = {
  19719. value: function(require, exports, module) {
  19720. return _p.r(11).createClass({
  19721. base: _p.r(68),
  19722. constructor: function(innerRadius, outerRadius) {
  19723. this.callBase([ innerRadius, outerRadius ], 360, 0);
  19724. },
  19725. getInnerRadius: function() {
  19726. return this.getSectionArray()[0];
  19727. },
  19728. getOuterRadius: function() {
  19729. return this.getSectionArray()[1];
  19730. },
  19731. setInnerRadius: function(value) {
  19732. this.setSectionArray([ value, this.getOuterRadius() ]);
  19733. },
  19734. setOuterRadius: function(value) {
  19735. this.setSectionArray([ this.getInnerRadius(), value ]);
  19736. }
  19737. });
  19738. }
  19739. };
  19740. //src/graphic/shape.js
  19741. _p[60] = {
  19742. value: function(require, exports, module) {
  19743. var svg = _p.r(67);
  19744. var utils = _p.r(12);
  19745. var EventHandler = _p.r(33);
  19746. var Styled = _p.r(66);
  19747. var Data = _p.r(31);
  19748. var Matrix = _p.r(43);
  19749. var Pen = _p.r(48);
  19750. var slice = Array.prototype.slice;
  19751. var Box = _p.r(25);
  19752. var Shape = _p.r(11).createClass("Shape", {
  19753. mixins: [ EventHandler, Styled, Data ],
  19754. constructor: function Shape(tagName) {
  19755. this.node = svg.createNode(tagName);
  19756. this.node.shape = this;
  19757. this.transform = {
  19758. translate: null,
  19759. rotate: null,
  19760. scale: null,
  19761. matrix: null
  19762. };
  19763. this.callMixin();
  19764. },
  19765. getId: function() {
  19766. return this.node.id;
  19767. },
  19768. setId: function(id) {
  19769. this.node.id = id;
  19770. return this;
  19771. },
  19772. getNode: function() {
  19773. return this.node;
  19774. },
  19775. getBoundaryBox: function() {
  19776. var box;
  19777. try {
  19778. box = this.node.getBBox();
  19779. } catch (e) {
  19780. box = {
  19781. x: this.node.clientLeft,
  19782. y: this.node.clientTop,
  19783. width: this.node.clientWidth,
  19784. height: this.node.clientHeight
  19785. };
  19786. }
  19787. return new Box(box);
  19788. },
  19789. getRenderBox: function(refer) {
  19790. var box = this.getBoundaryBox();
  19791. var matrix = this.getTransform(refer);
  19792. return matrix.transformBox(box);
  19793. },
  19794. getWidth: function() {
  19795. return this.getRenderBox().width;
  19796. },
  19797. getHeight: function() {
  19798. return this.getRenderBox().height;
  19799. },
  19800. getSize: function() {
  19801. var box = this.getRenderBox();
  19802. delete box.x;
  19803. delete box.y;
  19804. return box;
  19805. },
  19806. setOpacity: function(value) {
  19807. this.node.setAttribute("opacity", value);
  19808. return this;
  19809. },
  19810. getOpacity: function() {
  19811. var opacity = this.node.getAttribute("opacity");
  19812. return opacity ? +opacity : 1;
  19813. },
  19814. setVisible: function(value) {
  19815. if (value) {
  19816. this.node.removeAttribute("display");
  19817. } else {
  19818. this.node.setAttribute("display", "none");
  19819. }
  19820. return this;
  19821. },
  19822. getVisible: function() {
  19823. this.node.getAttribute("display");
  19824. },
  19825. hasAncestor: function(node) {
  19826. var parent = this.container;
  19827. while (parent) {
  19828. if (parent === node) {
  19829. return true;
  19830. }
  19831. parent = parent.container;
  19832. }
  19833. return false;
  19834. },
  19835. getTransform: function(refer) {
  19836. return Matrix.getCTM(this, refer);
  19837. },
  19838. clearTransform: function() {
  19839. this.node.removeAttribute("transform");
  19840. this.transform = {
  19841. translate: null,
  19842. rotate: null,
  19843. scale: null,
  19844. matrix: null
  19845. };
  19846. this.trigger("shapeupdate", {
  19847. type: "transform"
  19848. });
  19849. return this;
  19850. },
  19851. _applyTransform: function() {
  19852. var t = this.transform, result = [];
  19853. if (t.translate) {
  19854. result.push([ "translate(", t.translate, ")" ]);
  19855. }
  19856. if (t.rotate) {
  19857. result.push([ "rotate(", t.rotate, ")" ]);
  19858. }
  19859. if (t.scale) {
  19860. result.push([ "scale(", t.scale, ")" ]);
  19861. }
  19862. if (t.matrix) {
  19863. result.push([ "matrix(", t.matrix, ")" ]);
  19864. }
  19865. this.node.setAttribute("transform", utils.flatten(result).join(" "));
  19866. return this;
  19867. },
  19868. setMatrix: function(m) {
  19869. this.transform.matrix = m;
  19870. return this._applyTransform();
  19871. },
  19872. setTranslate: function(t) {
  19873. this.transform.translate = t !== null && slice.call(arguments) || null;
  19874. return this._applyTransform();
  19875. },
  19876. setRotate: function(r) {
  19877. this.transform.rotate = r !== null && slice.call(arguments) || null;
  19878. return this._applyTransform();
  19879. },
  19880. setScale: function(s) {
  19881. this.transform.scale = s !== null && slice.call(arguments) || null;
  19882. return this._applyTransform();
  19883. },
  19884. translate: function(dx, dy) {
  19885. var m = this.transform.matrix || new Matrix();
  19886. if (dy === undefined) {
  19887. dy = 0;
  19888. }
  19889. this.transform.matrix = m.translate(dx, dy);
  19890. return this._applyTransform();
  19891. },
  19892. rotate: function(deg) {
  19893. var m = this.transform.matrix || new Matrix();
  19894. this.transform.matrix = m.rotate(deg);
  19895. return this._applyTransform();
  19896. },
  19897. scale: function(sx, sy) {
  19898. var m = this.transform.matrix || new Matrix();
  19899. if (sy === undefined) {
  19900. sy = sx;
  19901. }
  19902. this.transform.matrix = m.scale(sx, sy);
  19903. return this._applyTransform();
  19904. },
  19905. skew: function(sx, sy) {
  19906. var m = this.transform.matrix || new Matrix();
  19907. if (sy === undefined) {
  19908. sy = sx;
  19909. }
  19910. this.transform.matrix = m.skew(sx, sy);
  19911. return this._applyTransform();
  19912. },
  19913. stroke: function(pen, width) {
  19914. if (pen && pen.stroke) {
  19915. pen.stroke(this);
  19916. } else if (pen) {
  19917. // 字符串或重写了 toString 的对象
  19918. this.node.setAttribute("stroke", pen.toString());
  19919. if (width) {
  19920. this.node.setAttribute("stroke-width", width);
  19921. }
  19922. } else if (pen === null) {
  19923. this.node.removeAttribute("stroe");
  19924. }
  19925. return this;
  19926. },
  19927. fill: function(brush) {
  19928. // 字符串或重写了 toString 的对象
  19929. if (brush) {
  19930. this.node.setAttribute("fill", brush.toString());
  19931. }
  19932. if (brush === null) {
  19933. this.node.removeAttribute("fill");
  19934. }
  19935. return this;
  19936. },
  19937. setAttr: function(a, v) {
  19938. var me = this;
  19939. if (utils.isObject(a)) {
  19940. utils.each(a, function(val, key) {
  19941. me.setAttr(key, val);
  19942. });
  19943. }
  19944. if (v === undefined || v === null || v === "") {
  19945. this.node.removeAttribute(a);
  19946. } else {
  19947. this.node.setAttribute(a, v);
  19948. }
  19949. return this;
  19950. },
  19951. getAttr: function(a) {
  19952. return this.node.getAttribute(a);
  19953. }
  19954. });
  19955. return Shape;
  19956. }
  19957. };
  19958. //src/graphic/shapecontainer.js
  19959. _p[61] = {
  19960. value: function(require, exports, module) {
  19961. var Container = _p.r(29);
  19962. var utils = _p.r(12);
  19963. var ShapeContainer = _p.r(11).createClass("ShapeContainer", {
  19964. base: Container,
  19965. isShapeContainer: true,
  19966. /* private */
  19967. handleAdd: function(shape, index) {
  19968. var parent = this.getShapeNode();
  19969. parent.insertBefore(shape.node, parent.childNodes[index] || null);
  19970. shape.trigger("add", {
  19971. container: this
  19972. });
  19973. if (shape.notifyTreeModification) {
  19974. shape.notifyTreeModification("treeadd", this);
  19975. }
  19976. },
  19977. /* private */
  19978. handleRemove: function(shape, index) {
  19979. var parent = this.getShapeNode();
  19980. parent.removeChild(shape.node);
  19981. shape.trigger("remove", {
  19982. container: this
  19983. });
  19984. if (shape.notifyTreeModification) {
  19985. shape.notifyTreeModification("treeremove", this);
  19986. }
  19987. },
  19988. /* private */
  19989. notifyTreeModification: function(type, container) {
  19990. this.eachItem(function(index, shape) {
  19991. if (shape.notifyTreeModification) {
  19992. shape.notifyTreeModification(type, container);
  19993. }
  19994. shape.trigger(type, {
  19995. container: container
  19996. });
  19997. });
  19998. },
  19999. /* public */
  20000. getShape: function(index) {
  20001. return this.getItem(index);
  20002. },
  20003. /* public */
  20004. addShape: function(shape, index) {
  20005. return this.addItem(shape, index);
  20006. },
  20007. put: function(shape) {
  20008. this.addShape(shape);
  20009. return shape;
  20010. },
  20011. appendShape: function(shape) {
  20012. return this.addShape(shape);
  20013. },
  20014. prependShape: function(shape) {
  20015. return this.addShape(shape, 0);
  20016. },
  20017. replaceShape: function(replacer, origin) {
  20018. var index = this.indexOf(origin);
  20019. if (index === -1) {
  20020. return;
  20021. }
  20022. this.removeShape(index);
  20023. this.addShape(replacer, index);
  20024. return this;
  20025. },
  20026. addShapeBefore: function(shape, refer) {
  20027. var index = this.indexOf(refer);
  20028. return this.addShape(shape, index);
  20029. },
  20030. addShapeAfter: function(shape, refer) {
  20031. var index = this.indexOf(refer);
  20032. return this.addShape(shape, index === -1 ? undefined : index + 1);
  20033. },
  20034. /* public */
  20035. addShapes: function(shapes) {
  20036. return this.addItems(shapes);
  20037. },
  20038. /* public */
  20039. removeShape: function(index) {
  20040. return this.removeItem(index);
  20041. },
  20042. getShapes: function() {
  20043. return this.getItems();
  20044. },
  20045. getShapesByType: function(name) {
  20046. var shapes = [];
  20047. function getShapes(shape) {
  20048. if (name.toLowerCase() == shape.getType().toLowerCase()) {
  20049. shapes.push(shape);
  20050. }
  20051. if (shape.isShapeContainer) {
  20052. utils.each(shape.getShapes(), function(n) {
  20053. getShapes(n);
  20054. });
  20055. }
  20056. }
  20057. getShapes(this);
  20058. return shapes;
  20059. },
  20060. /* public */
  20061. getShapeById: function(id) {
  20062. return this.getShapeNode().getElementById(id).shape;
  20063. },
  20064. arrangeShape: function(shape, index) {
  20065. return this.removeShape(shape).addShape(shape, index);
  20066. },
  20067. /* protected */
  20068. getShapeNode: function() {
  20069. return this.shapeNode || this.node;
  20070. }
  20071. });
  20072. var Shape = _p.r(60);
  20073. _p.r(11).extendClass(Shape, {
  20074. bringTo: function(index) {
  20075. this.container.arrangeShape(this, index);
  20076. return this;
  20077. },
  20078. bringFront: function() {
  20079. return this.bringTo(this.container.indexOf(this) + 1);
  20080. },
  20081. bringBack: function() {
  20082. return this.bringTo(this.container.indexOf(this) - 1);
  20083. },
  20084. bringTop: function() {
  20085. this.container.removeShape(this).addShape(this);
  20086. return this;
  20087. },
  20088. bringRear: function() {
  20089. return this.bringTo(0);
  20090. },
  20091. bringRefer: function(referShape, offset) {
  20092. if (referShape.container) {
  20093. if (this.remove) {
  20094. this.remove();
  20095. }
  20096. referShape.container.addShape(this, referShape.container.indexOf(referShape) + (offset || 0));
  20097. }
  20098. return this;
  20099. },
  20100. bringAbove: function(referShape) {
  20101. return this.bringRefer(referShape);
  20102. },
  20103. bringBelow: function(referShape) {
  20104. return this.bringRefer(referShape, 1);
  20105. },
  20106. replaceBy: function(newShape) {
  20107. if (this.container) {
  20108. newShape.bringAbove(this);
  20109. this.remove();
  20110. }
  20111. return this;
  20112. }
  20113. });
  20114. return ShapeContainer;
  20115. }
  20116. };
  20117. //src/graphic/shapeevent.js
  20118. /*
  20119. * 图形事件包装类
  20120. * */
  20121. _p[62] = {
  20122. value: function(require, exprots, module) {
  20123. var Matrix = _p.r(43), Utils = _p.r(12), Point = _p.r(50);
  20124. return _p.r(11).createClass("ShapeEvent", {
  20125. constructor: function(event) {
  20126. var target = null;
  20127. // dom 事件封装对象
  20128. if (!Utils.isObject(event.target)) {
  20129. this.type = event.type;
  20130. target = event.target;
  20131. // use标签有特殊属性, 需要区别对待
  20132. if (target.correspondingUseElement) {
  20133. target = target.correspondingUseElement;
  20134. }
  20135. this.originEvent = event;
  20136. this.targetShape = target.shape || target.paper || event.currentTarget && (event.currentTarget.shape || event.currentTarget.paper);
  20137. if (event._kityParam) {
  20138. Utils.extend(this, event._kityParam);
  20139. }
  20140. } else {
  20141. Utils.extend(this, event);
  20142. }
  20143. },
  20144. preventDefault: function() {
  20145. var evt = this.originEvent;
  20146. if (!evt) {
  20147. return true;
  20148. }
  20149. if (evt.preventDefault) {
  20150. evt.preventDefault();
  20151. return evt.cancelable;
  20152. } else {
  20153. evt.returnValue = false;
  20154. return true;
  20155. }
  20156. },
  20157. //当前鼠标事件在用户坐标系中点击的点的坐标位置
  20158. getPosition: function(refer, touchIndex) {
  20159. if (!this.originEvent) {
  20160. return null;
  20161. }
  20162. var eventClient = this.originEvent.touches ? this.originEvent.touches[touchIndex || 0] : this.originEvent;
  20163. var target = this.targetShape;
  20164. var targetNode = target.shapeNode || target.node;
  20165. var pScreen = new Point(eventClient && eventClient.clientX || 0, eventClient && eventClient.clientY || 0);
  20166. var pTarget = Matrix.transformPoint(pScreen, targetNode.getScreenCTM().inverse());
  20167. var pRefer = Matrix.getCTM(target, refer || "view").transformPoint(pTarget);
  20168. return pRefer;
  20169. },
  20170. stopPropagation: function() {
  20171. var evt = this.originEvent;
  20172. if (!evt) {
  20173. return true;
  20174. }
  20175. if (evt.stopPropagation) {
  20176. evt.stopPropagation();
  20177. } else {
  20178. evt.cancelBubble = false;
  20179. }
  20180. }
  20181. });
  20182. }
  20183. };
  20184. //src/graphic/shapepoint.js
  20185. /*
  20186. * 图形上的点抽象
  20187. */
  20188. _p[63] = {
  20189. value: function(require, exports, module) {
  20190. return _p.r(11).createClass("ShapePoint", {
  20191. base: _p.r(50),
  20192. constructor: function(px, py) {
  20193. this.callBase(px, py);
  20194. },
  20195. setX: function(x) {
  20196. return this.setPoint(x, this.y);
  20197. },
  20198. setY: function(y) {
  20199. return this.setPoint(this.x, y);
  20200. },
  20201. setPoint: function(x, y) {
  20202. this.x = x;
  20203. this.y = y;
  20204. this.update();
  20205. return this;
  20206. },
  20207. getPoint: function() {
  20208. return this;
  20209. },
  20210. update: function() {
  20211. if (this.container && this.container.update) {
  20212. this.container.update();
  20213. }
  20214. return this;
  20215. }
  20216. });
  20217. }
  20218. };
  20219. //src/graphic/standardcolor.js
  20220. /**
  20221. * 标准颜色映射
  20222. */
  20223. _p[64] = {
  20224. value: {
  20225. COLOR_STANDARD: {
  20226. aliceblue: "#f0f8ff",
  20227. antiquewhite: "#faebd7",
  20228. aqua: "#00ffff",
  20229. aquamarine: "#7fffd4",
  20230. azure: "#f0ffff",
  20231. beige: "#f5f5dc",
  20232. bisque: "#ffe4c4",
  20233. black: "#000000",
  20234. blanchedalmond: "#ffebcd",
  20235. blue: "#0000ff",
  20236. blueviolet: "#8a2be2",
  20237. brown: "#a52a2a",
  20238. burlywood: "#deb887",
  20239. cadetblue: "#5f9ea0",
  20240. chartreuse: "#7fff00",
  20241. chocolate: "#d2691e",
  20242. coral: "#ff7f50",
  20243. cornflowerblue: "#6495ed",
  20244. cornsilk: "#fff8dc",
  20245. crimson: "#dc143c",
  20246. cyan: "#00ffff",
  20247. darkblue: "#00008b",
  20248. darkcyan: "#008b8b",
  20249. darkgoldenrod: "#b8860b",
  20250. darkgray: "#a9a9a9",
  20251. darkgreen: "#006400",
  20252. darkgrey: "#a9a9a9",
  20253. darkkhaki: "#bdb76b",
  20254. darkmagenta: "#8b008b",
  20255. darkolivegreen: "#556b2f",
  20256. darkorange: "#ff8c00",
  20257. darkorchid: "#9932cc",
  20258. darkred: "#8b0000",
  20259. darksalmon: "#e9967a",
  20260. darkseagreen: "#8fbc8f",
  20261. darkslateblue: "#483d8b",
  20262. darkslategray: "#2f4f4f",
  20263. darkslategrey: "#2f4f4f",
  20264. darkturquoise: "#00ced1",
  20265. darkviolet: "#9400d3",
  20266. deeppink: "#ff1493",
  20267. deepskyblue: "#00bfff",
  20268. dimgray: "#696969",
  20269. dimgrey: "#696969",
  20270. dodgerblue: "#1e90ff",
  20271. firebrick: "#b22222",
  20272. floralwhite: "#fffaf0",
  20273. forestgreen: "#228b22",
  20274. fuchsia: "#ff00ff",
  20275. gainsboro: "#dcdcdc",
  20276. ghostwhite: "#f8f8ff",
  20277. gold: "#ffd700",
  20278. goldenrod: "#daa520",
  20279. gray: "#808080",
  20280. green: "#008000",
  20281. greenyellow: "#adff2f",
  20282. grey: "#808080",
  20283. honeydew: "#f0fff0",
  20284. hotpink: "#ff69b4",
  20285. indianred: "#cd5c5c",
  20286. indigo: "#4b0082",
  20287. ivory: "#fffff0",
  20288. khaki: "#f0e68c",
  20289. lavender: "#e6e6fa",
  20290. lavenderblush: "#fff0f5",
  20291. lawngreen: "#7cfc00",
  20292. lemonchiffon: "#fffacd",
  20293. lightblue: "#add8e6",
  20294. lightcoral: "#f08080",
  20295. lightcyan: "#e0ffff",
  20296. lightgoldenrodyellow: "#fafad2",
  20297. lightgray: "#d3d3d3",
  20298. lightgreen: "#90ee90",
  20299. lightgrey: "#d3d3d3",
  20300. lightpink: "#ffb6c1",
  20301. lightsalmon: "#ffa07a",
  20302. lightseagreen: "#20b2aa",
  20303. lightskyblue: "#87cefa",
  20304. lightslategray: "#778899",
  20305. lightslategrey: "#778899",
  20306. lightsteelblue: "#b0c4de",
  20307. lightyellow: "#ffffe0",
  20308. lime: "#00ff00",
  20309. limegreen: "#32cd32",
  20310. linen: "#faf0e6",
  20311. magenta: "#ff00ff",
  20312. maroon: "#800000",
  20313. mediumaquamarine: "#66cdaa",
  20314. mediumblue: "#0000cd",
  20315. mediumorchid: "#ba55d3",
  20316. mediumpurple: "#9370db",
  20317. mediumseagreen: "#3cb371",
  20318. mediumslateblue: "#7b68ee",
  20319. mediumspringgreen: "#00fa9a",
  20320. mediumturquoise: "#48d1cc",
  20321. mediumvioletred: "#c71585",
  20322. midnightblue: "#191970",
  20323. mintcream: "#f5fffa",
  20324. mistyrose: "#ffe4e1",
  20325. moccasin: "#ffe4b5",
  20326. navajowhite: "#ffdead",
  20327. navy: "#000080",
  20328. oldlace: "#fdf5e6",
  20329. olive: "#808000",
  20330. olivedrab: "#6b8e23",
  20331. orange: "#ffa500",
  20332. orangered: "#ff4500",
  20333. orchid: "#da70d6",
  20334. palegoldenrod: "#eee8aa",
  20335. palegreen: "#98fb98",
  20336. paleturquoise: "#afeeee",
  20337. palevioletred: "#db7093",
  20338. papayawhip: "#ffefd5",
  20339. peachpuff: "#ffdab9",
  20340. peru: "#cd853f",
  20341. pink: "#ffc0cb",
  20342. plum: "#dda0dd",
  20343. powderblue: "#b0e0e6",
  20344. purple: "#800080",
  20345. red: "#ff0000",
  20346. rosybrown: "#bc8f8f",
  20347. royalblue: "#4169e1",
  20348. saddlebrown: "#8b4513",
  20349. salmon: "#fa8072",
  20350. sandybrown: "#f4a460",
  20351. seagreen: "#2e8b57",
  20352. seashell: "#fff5ee",
  20353. sienna: "#a0522d",
  20354. silver: "#c0c0c0",
  20355. skyblue: "#87ceeb",
  20356. slateblue: "#6a5acd",
  20357. slategray: "#708090",
  20358. slategrey: "#708090",
  20359. snow: "#fffafa",
  20360. springgreen: "#00ff7f",
  20361. steelblue: "#4682b4",
  20362. tan: "#d2b48c",
  20363. teal: "#008080",
  20364. thistle: "#d8bfd8",
  20365. tomato: "#ff6347",
  20366. turquoise: "#40e0d0",
  20367. violet: "#ee82ee",
  20368. wheat: "#f5deb3",
  20369. white: "#ffffff",
  20370. whitesmoke: "#f5f5f5",
  20371. yellow: "#ffff00"
  20372. },
  20373. //标准扩展
  20374. EXTEND_STANDARD: {}
  20375. }
  20376. };
  20377. //src/graphic/star.js
  20378. _p[65] = {
  20379. value: function(require, exports, module) {
  20380. /**
  20381. * @see http://www.jdawiseman.com/papers/easymath/surds_star_inner_radius.html
  20382. */
  20383. var defaultRatioForStar = {
  20384. "3": .2,
  20385. // yy
  20386. "5": .38196601125,
  20387. "6": .57735026919,
  20388. "8": .541196100146,
  20389. "10": .726542528005,
  20390. "12": .707106781187
  20391. };
  20392. var Point = _p.r(50);
  20393. return _p.r(11).createClass("Star", {
  20394. base: _p.r(46),
  20395. constructor: function(vertex, radius, shrink, offset, angleOffset) {
  20396. this.callBase();
  20397. this.vertex = vertex || 3;
  20398. this.radius = radius || 0;
  20399. this.shrink = shrink;
  20400. this.offset = offset || new Point(0, 0);
  20401. this.angleOffset = angleOffset || 0;
  20402. this.draw();
  20403. },
  20404. getVertex: function() {
  20405. return this.vertex;
  20406. },
  20407. setVertex: function(value) {
  20408. this.vertex = value;
  20409. return this.draw();
  20410. },
  20411. getRadius: function() {
  20412. return this.radius;
  20413. },
  20414. setRadius: function(value) {
  20415. this.radius = value;
  20416. return this.draw();
  20417. },
  20418. getShrink: function() {
  20419. return this.shrink;
  20420. },
  20421. setShrink: function(value) {
  20422. this.shrink = value;
  20423. return this.draw();
  20424. },
  20425. getOffset: function() {
  20426. return this.offset;
  20427. },
  20428. setOffset: function(value) {
  20429. this.offset = value;
  20430. return this.draw();
  20431. },
  20432. getAngleOffset: function() {
  20433. return this.angleOffset;
  20434. },
  20435. setAngleOffset: function(value) {
  20436. this.angleOffset = value;
  20437. return this.draw();
  20438. },
  20439. draw: function() {
  20440. var innerRadius = this.radius, outerRadius = this.radius * (this.shrink || defaultRatioForStar[this.vertex] || .5), vertex = this.vertex, offset = this.offset, angleStart = 90, angleStep = 180 / vertex, angleOffset = this.angleOffset, drawer = this.getDrawer(), i, angle;
  20441. drawer.clear();
  20442. drawer.moveTo(Point.fromPolar(outerRadius, angleStart));
  20443. for (i = 1; i <= vertex * 2; i++) {
  20444. angle = angleStart + angleStep * i;
  20445. // 绘制内点
  20446. if (i % 2) {
  20447. drawer.lineTo(Point.fromPolar(innerRadius, angle + angleOffset).offset(offset));
  20448. } else {
  20449. drawer.lineTo(Point.fromPolar(outerRadius, angle));
  20450. }
  20451. }
  20452. drawer.close();
  20453. }
  20454. });
  20455. }
  20456. };
  20457. //src/graphic/styled.js
  20458. _p[66] = {
  20459. value: function(require, exports, module) {
  20460. // polyfill for ie
  20461. var ClassList = _p.r(11).createClass("ClassList", {
  20462. constructor: function(node) {
  20463. this._node = node;
  20464. this._list = node.className.toString().split(" ");
  20465. },
  20466. _update: function() {
  20467. this._node.className = this._list.join(" ");
  20468. },
  20469. add: function(name) {
  20470. this._list.push(name);
  20471. this._update();
  20472. },
  20473. remove: function(name) {
  20474. var index = this._list.indexOf(name);
  20475. if (~index) {
  20476. this._list.splice(index, 1);
  20477. }
  20478. this._update();
  20479. },
  20480. contains: function(name) {
  20481. return !!~this._list.indexOf(name);
  20482. }
  20483. });
  20484. function getClassList(node) {
  20485. if (!node.classList) {
  20486. node.classList = new ClassList(node);
  20487. }
  20488. return node.classList;
  20489. }
  20490. return _p.r(11).createClass("Styled", {
  20491. addClass: function(name) {
  20492. getClassList(this.node).add(name);
  20493. return this;
  20494. },
  20495. removeClass: function(name) {
  20496. getClassList(this.node).remove(name);
  20497. return this;
  20498. },
  20499. hasClass: function(name) {
  20500. return getClassList(this.node).contains(name);
  20501. },
  20502. setStyle: function(styles) {
  20503. if (arguments.length == 2) {
  20504. this.node.style[arguments[0]] = arguments[1];
  20505. return this;
  20506. }
  20507. for (var name in styles) {
  20508. if (styles.hasOwnProperty(name)) {
  20509. this.node.style[name] = styles[name];
  20510. }
  20511. }
  20512. return this;
  20513. }
  20514. });
  20515. }
  20516. };
  20517. //src/graphic/svg.js
  20518. _p[67] = {
  20519. value: function(require, exports, module) {
  20520. var doc = document;
  20521. var id = 0;
  20522. var svg = {
  20523. createNode: function(name) {
  20524. var node = doc.createElementNS(svg.ns, name);
  20525. node.id = "kity_" + name + "_" + id++;
  20526. return node;
  20527. },
  20528. defaults: {
  20529. stroke: "none",
  20530. fill: "none"
  20531. },
  20532. xlink: "http://www.w3.org/1999/xlink",
  20533. ns: "http://www.w3.org/2000/svg"
  20534. };
  20535. return svg;
  20536. }
  20537. };
  20538. //src/graphic/sweep.js
  20539. _p[68] = {
  20540. value: function(require, exports, module) {
  20541. var Point = _p.r(50);
  20542. return _p.r(11).createClass("Sweep", {
  20543. base: _p.r(46),
  20544. constructor: function(sectionArray, angle, angleOffset) {
  20545. this.callBase();
  20546. this.sectionArray = sectionArray || [];
  20547. this.angle = angle || 0;
  20548. this.angleOffset = angleOffset || 0;
  20549. this.draw();
  20550. },
  20551. getSectionArray: function() {
  20552. return this.sectionArray;
  20553. },
  20554. setSectionArray: function(value) {
  20555. this.sectionArray = value;
  20556. return this.draw();
  20557. },
  20558. getAngle: function() {
  20559. return this.angle;
  20560. },
  20561. setAngle: function(value) {
  20562. this.angle = value;
  20563. return this.draw();
  20564. },
  20565. getAngleOffset: function() {
  20566. return this.angleOffset;
  20567. },
  20568. setAngleOffset: function(value) {
  20569. this.angleOffset = value;
  20570. return this.draw();
  20571. },
  20572. draw: function() {
  20573. var sectionArray = this.sectionArray, i;
  20574. for (i = 0; i < sectionArray.length; i += 2) {
  20575. this.drawSection(sectionArray[i], sectionArray[i + 1]);
  20576. }
  20577. return this;
  20578. },
  20579. drawSection: function(from, to) {
  20580. var angleLength = this.angle && (this.angle % 360 ? this.angle % 360 : 360), angleStart = this.angleOffset, angleHalf = angleStart + angleLength / 2, angleEnd = angleStart + angleLength, sweepFlag = angleLength < 0 ? 0 : 1, drawer = this.getDrawer();
  20581. drawer.redraw();
  20582. if (angleLength === 0) {
  20583. drawer.done();
  20584. return;
  20585. }
  20586. drawer.moveTo(Point.fromPolar(from, angleStart));
  20587. drawer.lineTo(Point.fromPolar(to, angleStart));
  20588. if (to) {
  20589. drawer.carcTo(to, 0, sweepFlag, Point.fromPolar(to, angleHalf));
  20590. drawer.carcTo(to, 0, sweepFlag, Point.fromPolar(to, angleEnd));
  20591. }
  20592. drawer.lineTo(Point.fromPolar(from, angleEnd));
  20593. if (from) {
  20594. drawer.carcTo(from, 0, sweepFlag, Point.fromPolar(from, angleHalf));
  20595. drawer.carcTo(from, 0, sweepFlag, Point.fromPolar(from, angleStart));
  20596. }
  20597. drawer.close();
  20598. drawer.done();
  20599. }
  20600. });
  20601. }
  20602. };
  20603. //src/graphic/text.js
  20604. _p[69] = {
  20605. value: function(require, exports, module) {
  20606. var TextContent = _p.r(70);
  20607. var ShapeContainer = _p.r(61);
  20608. var svg = _p.r(67);
  20609. var utils = _p.r(12);
  20610. var offsetHash = {};
  20611. function getTextBoundOffset(text) {
  20612. var font = text._cachedFontHash;
  20613. if (offsetHash[font]) {
  20614. return offsetHash[font];
  20615. }
  20616. var textContent = text.getContent();
  20617. text.setContent("百度Fex");
  20618. var bbox = text.getBoundaryBox(), y = text.getY();
  20619. var topOffset = y - bbox.y + +text.node.getAttribute("dy"), bottomOffset = topOffset - bbox.height;
  20620. text.setContent(textContent);
  20621. return offsetHash[font] = {
  20622. top: topOffset,
  20623. bottom: bottomOffset,
  20624. middle: (topOffset + bottomOffset) / 2
  20625. };
  20626. }
  20627. return _p.r(11).createClass("Text", {
  20628. base: TextContent,
  20629. mixins: [ ShapeContainer ],
  20630. constructor: function(content) {
  20631. this.callBase("text");
  20632. if (content !== undefined) {
  20633. this.setContent(content);
  20634. }
  20635. this._buildFontHash();
  20636. },
  20637. _buildFontHash: function() {
  20638. var style = window.getComputedStyle(this.node);
  20639. this._cachedFontHash = [ style.fontFamily, style.fontSize, style.fontStretch, style.fontStyle, style.fontVariant, style.fontWeight ].join("-");
  20640. },
  20641. _fontChanged: function(font) {
  20642. var last = this._lastFont;
  20643. var current = utils.extend({}, last, font);
  20644. if (!last) {
  20645. this._lastFont = font;
  20646. return true;
  20647. }
  20648. var changed = last.family != current.family || last.size != current.size || last.style != current.style || last.weight != current.weight;
  20649. this._lastFont = current;
  20650. return changed;
  20651. },
  20652. setX: function(x) {
  20653. this.node.setAttribute("x", x);
  20654. return this;
  20655. },
  20656. setPosition: function(x, y) {
  20657. return this.setX(x).setY(y);
  20658. },
  20659. setY: function(y) {
  20660. this.node.setAttribute("y", y);
  20661. return this;
  20662. },
  20663. getX: function() {
  20664. return +this.node.getAttribute("x") || 0;
  20665. },
  20666. getY: function() {
  20667. return +this.node.getAttribute("y") || 0;
  20668. },
  20669. setFont: function(font) {
  20670. this.callBase(font);
  20671. if (this._fontChanged(font)) {
  20672. this._buildFontHash();
  20673. this.setVerticalAlign(this.getVerticalAlign());
  20674. }
  20675. return this;
  20676. },
  20677. setTextAnchor: function(anchor) {
  20678. this.node.setAttribute("text-anchor", anchor);
  20679. return this;
  20680. },
  20681. getTextAnchor: function() {
  20682. return this.node.getAttribute("text-anchor") || "start";
  20683. },
  20684. // top/bottom/middle/baseline
  20685. setVerticalAlign: function(align) {
  20686. this.whenPaperReady(function() {
  20687. var dy;
  20688. switch (align) {
  20689. case "top":
  20690. dy = getTextBoundOffset(this).top;
  20691. break;
  20692. case "bottom":
  20693. dy = getTextBoundOffset(this).bottom;
  20694. break;
  20695. case "middle":
  20696. dy = getTextBoundOffset(this).middle;
  20697. break;
  20698. default:
  20699. dy = 0;
  20700. }
  20701. this.node.setAttribute("dy", dy);
  20702. });
  20703. this.verticalAlign = align;
  20704. return this;
  20705. },
  20706. getVerticalAlign: function() {
  20707. return this.verticalAlign || "baseline";
  20708. },
  20709. setStartOffset: function(offset) {
  20710. // only for text path
  20711. if (this.shapeNode != this.node) {
  20712. this.shapeNode.setAttribute("startOffset", offset * 100 + "%");
  20713. }
  20714. },
  20715. addSpan: function(span) {
  20716. this.addShape(span);
  20717. return this;
  20718. },
  20719. setPath: function(path) {
  20720. var textpath = this.shapeNode;
  20721. if (this.shapeNode == this.node) {
  20722. // 当前还不是 textpath
  20723. textpath = this.shapeNode = svg.createNode("textPath");
  20724. while (this.node.firstChild) {
  20725. this.shapeNode.appendChild(this.node.firstChild);
  20726. }
  20727. this.node.appendChild(textpath);
  20728. }
  20729. textpath.setAttributeNS(svg.xlink, "xlink:href", "#" + path.node.id);
  20730. this.setTextAnchor(this.getTextAnchor());
  20731. return this;
  20732. }
  20733. });
  20734. }
  20735. };
  20736. //src/graphic/textcontent.js
  20737. _p[70] = {
  20738. value: function(require, exports, module) {
  20739. var Shape = _p.r(60);
  20740. return _p.r(11).createClass("TextContent", {
  20741. base: Shape,
  20742. constructor: function(nodeType) {
  20743. // call shape constructor
  20744. this.callBase(nodeType);
  20745. this.shapeNode = this.shapeNode || this.node;
  20746. this.shapeNode.setAttribute("text-rendering", "geometricPrecision");
  20747. },
  20748. clearContent: function() {
  20749. while (this.shapeNode.firstChild) {
  20750. this.shapeNode.removeChild(this.shapeNode.firstChild);
  20751. }
  20752. return this;
  20753. },
  20754. setContent: function(content) {
  20755. this.shapeNode.textContent = content;
  20756. return this;
  20757. },
  20758. getContent: function() {
  20759. return this.shapeNode.textContent;
  20760. },
  20761. appendContent: function(content) {
  20762. this.shapeNode.textContent += content;
  20763. return this;
  20764. },
  20765. setSize: function(value) {
  20766. return this.setFontSize(value);
  20767. },
  20768. setFontSize: function(value) {
  20769. return this.setFont({
  20770. size: value
  20771. });
  20772. },
  20773. setFontFamily: function(value) {
  20774. return this.setFont({
  20775. family: value
  20776. });
  20777. },
  20778. setFontBold: function(bold) {
  20779. return this.setFont({
  20780. weight: bold ? "bold" : "normal"
  20781. });
  20782. },
  20783. setFontItalic: function(italic) {
  20784. return this.setFont({
  20785. style: italic ? "italic" : "normal"
  20786. });
  20787. },
  20788. setFont: function(font) {
  20789. var node = this.node;
  20790. [ "family", "size", "weight", "style" ].forEach(function(section) {
  20791. if (font[section] === null) {
  20792. node.removeAttribute("font-" + section);
  20793. } else if (font[section]) {
  20794. node.setAttribute("font-" + section, font[section]);
  20795. }
  20796. });
  20797. return this;
  20798. },
  20799. getExtentOfChar: function(index) {
  20800. return this.node.getExtentOfChar(index);
  20801. },
  20802. getRotationOfChar: function(index) {
  20803. return this.node.getRotationOfChar(index);
  20804. },
  20805. getCharNumAtPosition: function(x, y) {
  20806. return this.node.getCharNumAtPosition(this.node.viewportElement.createSVGPoint(x, y));
  20807. }
  20808. });
  20809. }
  20810. };
  20811. //src/graphic/textspan.js
  20812. _p[71] = {
  20813. value: function(require, exports, module) {
  20814. var TextContent = _p.r(70);
  20815. var Styled = _p.r(66);
  20816. return _p.r(11).createClass("TextSpan", {
  20817. base: TextContent,
  20818. mixins: [ Styled ],
  20819. constructor: function(content) {
  20820. this.callBase("tspan");
  20821. this.setContent(content);
  20822. }
  20823. });
  20824. }
  20825. };
  20826. //src/graphic/use.js
  20827. /*
  20828. * USE 功能
  20829. */
  20830. _p[72] = {
  20831. value: function(require, exports, module) {
  20832. var Svg = _p.r(67);
  20833. var Class = _p.r(11);
  20834. var Use = Class.createClass("Use", {
  20835. base: _p.r(60),
  20836. constructor: function(shape) {
  20837. this.callBase("use");
  20838. this.ref(shape);
  20839. },
  20840. ref: function(shape) {
  20841. if (!shape) {
  20842. this.node.removeAttributeNS(Svg.xlink, "xlink:href");
  20843. return this;
  20844. }
  20845. var shapeId = shape.getId();
  20846. if (shapeId) {
  20847. this.node.setAttributeNS(Svg.xlink, "xlink:href", "#" + shapeId);
  20848. }
  20849. // by techird
  20850. // 作为 Use 的图形,如果没有 fill 和 stroke,移除默认的 'none' 值,用于 Use 覆盖
  20851. if (shape.node.getAttribute("fill") === "none") {
  20852. shape.node.removeAttribute("fill");
  20853. }
  20854. if (shape.node.getAttribute("stroke") === "none") {
  20855. shape.node.removeAttribute("stroke");
  20856. }
  20857. return this;
  20858. }
  20859. });
  20860. var Shape = _p.r(60);
  20861. Class.extendClass(Shape, {
  20862. // fast-use
  20863. use: function() {
  20864. return new Use(this);
  20865. }
  20866. });
  20867. return Use;
  20868. }
  20869. };
  20870. //src/graphic/vector.js
  20871. _p[73] = {
  20872. value: function(require, exports, module) {
  20873. var Point = _p.r(50);
  20874. var Matrix = _p.r(43);
  20875. var Vector = _p.r(11).createClass("Vector", {
  20876. base: Point,
  20877. constructor: function(x, y) {
  20878. this.callBase(x, y);
  20879. },
  20880. square: function() {
  20881. return this.x * this.x + this.y * this.y;
  20882. },
  20883. length: function() {
  20884. return Math.sqrt(this.square());
  20885. },
  20886. add: function(q) {
  20887. return new Vector(this.x + q.x, this.y + q.y);
  20888. },
  20889. minus: function(q) {
  20890. return new Vector(this.x - q.x, this.y - q.y);
  20891. },
  20892. dot: function(q) {
  20893. return this.x * q.x + this.y * q.y;
  20894. },
  20895. project: function(q) {
  20896. return q.multipy(this.dot(q) / q.square());
  20897. },
  20898. normalize: function(length) {
  20899. if (length === undefined) {
  20900. length = 1;
  20901. }
  20902. return this.multipy(length / this.length());
  20903. },
  20904. multipy: function(scale) {
  20905. return new Vector(this.x * scale, this.y * scale);
  20906. },
  20907. rotate: function(angle, unit) {
  20908. if (unit == "rad") {
  20909. angle = angle / Math.PI * 180;
  20910. }
  20911. var p = new Matrix().rotate(angle).transformPoint(this);
  20912. return new Vector(p.x, p.y);
  20913. },
  20914. vertical: function() {
  20915. return new Vector(this.y, -this.x);
  20916. },
  20917. reverse: function() {
  20918. return this.multipy(-1);
  20919. },
  20920. getAngle: function() {
  20921. var length = this.length();
  20922. if (length === 0) return 0;
  20923. var rad = Math.acos(this.x / length);
  20924. var sign = this.y > 0 ? 1 : -1;
  20925. return sign * 180 * rad / Math.PI;
  20926. }
  20927. });
  20928. Vector.fromPoints = function(p1, p2) {
  20929. return new Vector(p2.x - p1.x, p2.y - p1.y);
  20930. };
  20931. Vector.fromPolar = function() {
  20932. var p = Point.fromPolar.apply(Point, arguments);
  20933. return new Vector(p.x, p.y);
  20934. };
  20935. _p.r(11).extendClass(Point, {
  20936. asVector: function() {
  20937. return new Vector(this.x, this.y);
  20938. }
  20939. });
  20940. return Vector;
  20941. }
  20942. };
  20943. //src/graphic/view.js
  20944. _p[74] = {
  20945. value: function(require, exports, module) {
  20946. var ShapeContainer = _p.r(61);
  20947. var ViewBox = _p.r(75);
  20948. return _p.r(11).createClass("View", {
  20949. mixins: [ ShapeContainer, ViewBox ],
  20950. base: _p.r(74),
  20951. constructor: function() {
  20952. this.callBase("view");
  20953. }
  20954. });
  20955. }
  20956. };
  20957. //src/graphic/viewbox.js
  20958. _p[75] = {
  20959. value: function(require, exports, module) {
  20960. return _p.r(11).createClass("ViewBox", {
  20961. getViewBox: function() {
  20962. var attr = this.node.getAttribute("viewBox");
  20963. if (attr === null) {
  20964. // firefox:
  20965. // 1. viewBox 没有设置过的时候获得的是 null
  20966. // 2. svg 标签没有指定绝对大小的时候 clientWidth 和 clientHeigt 为 0,需要在父容器上查找
  20967. // TODO: 第 2 条取得的不准确(假如有 padding 之类的)
  20968. return {
  20969. x: 0,
  20970. y: 0,
  20971. width: this.node.clientWidth || this.node.parentNode.clientWidth,
  20972. height: this.node.clientHeight || this.node.parentNode.clientHeight
  20973. };
  20974. } else {
  20975. attr = attr.split(" ");
  20976. return {
  20977. x: +attr[0],
  20978. y: +attr[1],
  20979. width: +attr[2],
  20980. height: +attr[3]
  20981. };
  20982. }
  20983. },
  20984. setViewBox: function(x, y, width, height) {
  20985. this.node.setAttribute("viewBox", [ x, y, width, height ].join(" "));
  20986. return this;
  20987. }
  20988. });
  20989. }
  20990. };
  20991. //src/kity.js
  20992. /**
  20993. * @fileOverview kity 暴露的方法或对象
  20994. */
  20995. _p[76] = {
  20996. value: function(require, exports, module) {
  20997. var kity = {}, utils = _p.r(12);
  20998. kity.version = "2.0.0";
  20999. utils.extend(kity, {
  21000. // core
  21001. createClass: _p.r(11).createClass,
  21002. extendClass: _p.r(11).extendClass,
  21003. Utils: utils,
  21004. Browser: _p.r(10),
  21005. // shape
  21006. Box: _p.r(25),
  21007. Bezier: _p.r(23),
  21008. BezierPoint: _p.r(24),
  21009. Circle: _p.r(26),
  21010. Clip: _p.r(27),
  21011. Color: _p.r(28),
  21012. Container: _p.r(29),
  21013. Curve: _p.r(30),
  21014. Ellipse: _p.r(32),
  21015. Group: _p.r(36),
  21016. Gradient: _p.r(35),
  21017. HyperLink: _p.r(37),
  21018. Image: _p.r(38),
  21019. Line: _p.r(39),
  21020. LinearGradient: _p.r(40),
  21021. Mask: _p.r(42),
  21022. Matrix: _p.r(43),
  21023. Marker: _p.r(41),
  21024. Palette: _p.r(44),
  21025. Paper: _p.r(45),
  21026. Path: _p.r(46),
  21027. Pattern: _p.r(47),
  21028. Pen: _p.r(48),
  21029. Point: _p.r(50),
  21030. PointContainer: _p.r(51),
  21031. Polygon: _p.r(53),
  21032. Polyline: _p.r(54),
  21033. Pie: _p.r(49),
  21034. RadialGradient: _p.r(55),
  21035. Resource: _p.r(58),
  21036. Rect: _p.r(56),
  21037. RegularPolygon: _p.r(57),
  21038. Ring: _p.r(59),
  21039. Shape: _p.r(60),
  21040. ShapePoint: _p.r(63),
  21041. ShapeContainer: _p.r(61),
  21042. Sweep: _p.r(68),
  21043. Star: _p.r(65),
  21044. Text: _p.r(69),
  21045. TextSpan: _p.r(71),
  21046. Use: _p.r(72),
  21047. Vector: _p.r(73),
  21048. g: _p.r(34),
  21049. // animate
  21050. Animator: _p.r(0),
  21051. Easing: _p.r(1),
  21052. OpacityAnimator: _p.r(4),
  21053. RotateAnimator: _p.r(6),
  21054. ScaleAnimator: _p.r(7),
  21055. Timeline: _p.r(8),
  21056. TranslateAnimator: _p.r(9),
  21057. PathAnimator: _p.r(5),
  21058. MotionAnimator: _p.r(3),
  21059. requestFrame: _p.r(2).requestFrame,
  21060. releaseFrame: _p.r(2).releaseFrame,
  21061. // filter
  21062. Filter: _p.r(20),
  21063. GaussianblurFilter: _p.r(21),
  21064. ProjectionFilter: _p.r(22),
  21065. // effect
  21066. ColorMatrixEffect: _p.r(13),
  21067. CompositeEffect: _p.r(14),
  21068. ConvolveMatrixEffect: _p.r(15),
  21069. Effect: _p.r(16),
  21070. GaussianblurEffect: _p.r(17),
  21071. OffsetEffect: _p.r(18)
  21072. });
  21073. return window.kity = kity;
  21074. }
  21075. };
  21076. var moduleMapping = {
  21077. kity: 76
  21078. };
  21079. function use(name) {
  21080. _p.r([ moduleMapping[name] ]);
  21081. }
  21082. /* global use, inc: true */
  21083. /**
  21084. * 模块暴露
  21085. */
  21086. use('kity');
  21087. })();
  21088. var KityMinder = window.KM = window.KityMinder = function() {
  21089. var instanceMap = {},
  21090. instanceId = 0,
  21091. uuidMap = {};
  21092. return {
  21093. version: '1.3.5',
  21094. uuid: function(name) {
  21095. name = name || 'unknown';
  21096. uuidMap[name] = uuidMap[name] || 0;
  21097. ++uuidMap[name];
  21098. return name + '_' + uuidMap[name];
  21099. },
  21100. createMinder: function(renderTarget, options) {
  21101. options = options || {};
  21102. options.renderTo = Utils.isString(renderTarget) ? document.getElementById(renderTarget) : renderTarget;
  21103. var minder = new Minder(options);
  21104. this.addMinder(options.renderTo, minder);
  21105. return minder;
  21106. },
  21107. addMinder: function(target, minder) {
  21108. var id;
  21109. if (typeof(target) === 'string') {
  21110. id = target;
  21111. } else {
  21112. id = target.id || ("KM_INSTANCE_" + instanceId++);
  21113. }
  21114. instanceMap[id] = minder;
  21115. },
  21116. getMinder: function(target, options) {
  21117. var id;
  21118. if (typeof(target) === 'string') {
  21119. id = target;
  21120. } else {
  21121. id = target.id || ("KM_INSTANCE_" + instanceId++);
  21122. }
  21123. return instanceMap[id] || this.createMinder(target, options);
  21124. },
  21125. //挂接多语言
  21126. LANG: {}
  21127. };
  21128. }();
  21129. var utils = Utils = KityMinder.Utils = {
  21130. extend: kity.Utils.extend.bind(kity.Utils),
  21131. listen: function(element, type, handler) {
  21132. var types = utils.isArray(type) ? type : utils.trim(type).split(/\s+/),
  21133. k = types.length;
  21134. if (k)
  21135. while (k--) {
  21136. type = types[k];
  21137. if (element.addEventListener) {
  21138. element.addEventListener(type, handler, false);
  21139. } else {
  21140. if (!handler._d) {
  21141. handler._d = {
  21142. els: []
  21143. };
  21144. }
  21145. var key = type + handler.toString(),
  21146. index = utils.indexOf(handler._d.els, element);
  21147. if (!handler._d[key] || index == -1) {
  21148. if (index == -1) {
  21149. handler._d.els.push(element);
  21150. }
  21151. if (!handler._d[key]) {
  21152. handler._d[key] = function(evt) {
  21153. return handler.call(evt.srcElement, evt || window.event);
  21154. };
  21155. }
  21156. element.attachEvent('on' + type, handler._d[key]);
  21157. }
  21158. }
  21159. }
  21160. element = null;
  21161. },
  21162. trim: function(str) {
  21163. return str.replace(/(^[ \t\n\r]+)|([ \t\n\r]+$)/g, '');
  21164. },
  21165. each: function(obj, iterator, context) {
  21166. if (obj == null) return;
  21167. if (obj.length === +obj.length) {
  21168. for (var i = 0, l = obj.length; i < l; i++) {
  21169. if (iterator.call(context, i, obj[i], obj) === false)
  21170. return false;
  21171. }
  21172. } else {
  21173. for (var key in obj) {
  21174. if (obj.hasOwnProperty(key)) {
  21175. if (iterator.call(context, key, obj[key], obj) === false)
  21176. return false;
  21177. }
  21178. }
  21179. }
  21180. },
  21181. addCssRule: function(key, style, doc) {
  21182. var head, node;
  21183. if (style === undefined || style && style.nodeType && style.nodeType == 9) {
  21184. //获取样式
  21185. doc = style && style.nodeType && style.nodeType == 9 ? style : (doc || document);
  21186. node = doc.getElementById(key);
  21187. return node ? node.innerHTML : undefined;
  21188. }
  21189. doc = doc || document;
  21190. node = doc.getElementById(key);
  21191. //清除样式
  21192. if (style === '') {
  21193. if (node) {
  21194. node.parentNode.removeChild(node);
  21195. return true
  21196. }
  21197. return false;
  21198. }
  21199. //添加样式
  21200. if (node) {
  21201. node.innerHTML = style;
  21202. } else {
  21203. node = doc.createElement('style');
  21204. node.id = key;
  21205. node.innerHTML = style;
  21206. doc.getElementsByTagName('head')[0].appendChild(node);
  21207. }
  21208. },
  21209. keys: function(plain) {
  21210. var keys = [];
  21211. for (var key in plain) {
  21212. if (plain.hasOwnProperty(key)) {
  21213. keys.push(key);
  21214. }
  21215. }
  21216. return keys;
  21217. },
  21218. proxy: function(fn, context) {
  21219. return function() {
  21220. return fn.apply(context, arguments);
  21221. };
  21222. },
  21223. indexOf: function(array, item, start) {
  21224. var index = -1;
  21225. start = this.isNumber(start) ? start : 0;
  21226. this.each(array, function(v, i) {
  21227. if (i >= start && v === item) {
  21228. index = i;
  21229. return false;
  21230. }
  21231. });
  21232. return index;
  21233. },
  21234. argsToArray: function(args, index) {
  21235. return Array.prototype.slice.call(args, index || 0);
  21236. },
  21237. clonePlainObject: function(source, target) {
  21238. var tmp;
  21239. target = target || {};
  21240. for (var i in source) {
  21241. if (source.hasOwnProperty(i)) {
  21242. tmp = source[i];
  21243. if (utils.isObject(tmp) || utils.isArray(tmp)) {
  21244. target[i] = utils.isArray(tmp) ? [] : {};
  21245. utils.clonePlainObject(source[i], target[i])
  21246. } else {
  21247. target[i] = tmp;
  21248. }
  21249. }
  21250. }
  21251. return target;
  21252. },
  21253. compareObject: function(source, target) {
  21254. var tmp;
  21255. if (this.isEmptyObject(source) !== this.isEmptyObject(target)) {
  21256. return false
  21257. }
  21258. if (this.getObjectLength(source) != this.getObjectLength(target)) {
  21259. return false;
  21260. }
  21261. for (var p in source) {
  21262. if (source.hasOwnProperty(p)) {
  21263. tmp = source[p];
  21264. if (target[p] === undefined) {
  21265. return false;
  21266. }
  21267. if (this.isObject(tmp) || this.isArray(tmp)) {
  21268. if (this.isObject(target[p]) !== this.isObject(tmp)) {
  21269. return false;
  21270. }
  21271. if (this.isArray(tmp) !== this.isArray(target[p])) {
  21272. return false;
  21273. }
  21274. if (this.compareObject(tmp, target[p]) === false) {
  21275. return false
  21276. }
  21277. } else {
  21278. if (tmp != target[p]) {
  21279. return false
  21280. }
  21281. }
  21282. }
  21283. }
  21284. return true;
  21285. },
  21286. getObjectLength: function(obj) {
  21287. if (this.isArray(obj) || this.isString(obj)) return obj.length;
  21288. var count = 0;
  21289. for (var key in obj)
  21290. if (obj.hasOwnProperty(key)) count++;
  21291. return count;
  21292. },
  21293. isEmptyObject: function(obj) {
  21294. if (obj == null) return true;
  21295. if (this.isArray(obj) || this.isString(obj)) return obj.length === 0;
  21296. for (var key in obj)
  21297. if (obj.hasOwnProperty(key)) return false;
  21298. return true;
  21299. },
  21300. loadFile: function() {
  21301. var tmpList = [];
  21302. function getItem(doc, obj) {
  21303. try {
  21304. for (var i = 0, ci; ci = tmpList[i++];) {
  21305. if (ci.doc === doc && ci.url == (obj.src || obj.href)) {
  21306. return ci;
  21307. }
  21308. }
  21309. } catch (e) {
  21310. return null;
  21311. }
  21312. }
  21313. return function(doc, obj, fn) {
  21314. var item = getItem(doc, obj);
  21315. if (item) {
  21316. if (item.ready) {
  21317. fn && fn();
  21318. } else {
  21319. item.funs.push(fn)
  21320. }
  21321. return;
  21322. }
  21323. tmpList.push({
  21324. doc: doc,
  21325. url: obj.src || obj.href,
  21326. funs: [fn]
  21327. });
  21328. if (!doc.body) {
  21329. var html = [];
  21330. for (var p in obj) {
  21331. if (p == 'tag') continue;
  21332. html.push(p + '="' + obj[p] + '"')
  21333. }
  21334. doc.write('<' + obj.tag + ' ' + html.join(' ') + ' ></' + obj.tag + '>');
  21335. return;
  21336. }
  21337. if (obj.id && doc.getElementById(obj.id)) {
  21338. return;
  21339. }
  21340. var element = doc.createElement(obj.tag);
  21341. delete obj.tag;
  21342. for (var p in obj) {
  21343. element.setAttribute(p, obj[p]);
  21344. }
  21345. element.onload = element.onreadystatechange = function() {
  21346. if (!this.readyState || /loaded|complete/.test(this.readyState)) {
  21347. item = getItem(doc, obj);
  21348. if (item.funs.length > 0) {
  21349. item.ready = 1;
  21350. for (var fi; fi = item.funs.pop();) {
  21351. fi();
  21352. }
  21353. }
  21354. element.onload = element.onreadystatechange = null;
  21355. }
  21356. };
  21357. // element.onerror = function () {
  21358. // throw Error('The load ' + (obj.href || obj.src) + ' fails,check the url settings of file ')
  21359. // };
  21360. doc.getElementsByTagName("head")[0].appendChild(element);
  21361. }
  21362. }(),
  21363. clone: function(source, target) {
  21364. var tmp;
  21365. target = target || {};
  21366. for (var i in source) {
  21367. if (source.hasOwnProperty(i)) {
  21368. tmp = source[i];
  21369. if (typeof tmp == 'object') {
  21370. target[i] = utils.isArray(tmp) ? [] : {};
  21371. utils.clone(source[i], target[i])
  21372. } else {
  21373. target[i] = tmp;
  21374. }
  21375. }
  21376. }
  21377. return target;
  21378. },
  21379. unhtml: function(str, reg) {
  21380. return str ? str.replace(reg || /[&<">'](?:(amp|lt|quot|gt|#39|nbsp);)?/g, function(a, b) {
  21381. if (b) {
  21382. return a;
  21383. } else {
  21384. return {
  21385. '<': '&lt;',
  21386. '&': '&amp;',
  21387. '"': '&quot;',
  21388. '>': '&gt;',
  21389. "'": '&#39;'
  21390. }[a]
  21391. }
  21392. }) : '';
  21393. },
  21394. cloneArr:function(arr){
  21395. return [].concat(arr);
  21396. },
  21397. clearWhitespace:function(str){
  21398. return str.replace(/[\u200b\t\r\n]/g, '');
  21399. },
  21400. getValueByIndex:function(data,index){
  21401. var initIndex = 0,result = 0;
  21402. utils.each(data,function(i,arr){
  21403. if(initIndex + arr.length >= index){
  21404. if(index - initIndex == arr.length){
  21405. if(arr.length == 1 && arr[0].width === 0){
  21406. initIndex++;
  21407. return;
  21408. }
  21409. result = {
  21410. x: arr[arr.length - 1].x + arr[arr.length - 1].width,
  21411. y: arr[arr.length - 1].y
  21412. };
  21413. }else{
  21414. result = arr[index - initIndex];
  21415. }
  21416. return false;
  21417. }else{
  21418. initIndex += arr.length + (arr.length == 1 && arr[0].width === 0 ? 0 : 1);
  21419. }
  21420. });
  21421. return result;
  21422. },
  21423. getNodeIndex:function (node, ignoreTextNode) {
  21424. var preNode = node,
  21425. i = 0;
  21426. while (preNode = preNode.previousSibling) {
  21427. if (ignoreTextNode && preNode.nodeType == 3) {
  21428. if(preNode.nodeType != preNode.nextSibling.nodeType ){
  21429. i++;
  21430. }
  21431. continue;
  21432. }
  21433. i++;
  21434. }
  21435. return i;
  21436. }
  21437. };
  21438. Utils.each(['String', 'Function', 'Array', 'Number', 'RegExp', 'Object'], function(i, v) {
  21439. KityMinder.Utils['is' + v] = function(obj) {
  21440. return Object.prototype.toString.apply(obj) == '[object ' + v + ']';
  21441. }
  21442. });
  21443. /**
  21444. * 提供浏览器检测的模块
  21445. * @unfile
  21446. * @module KM.browser
  21447. */
  21448. var browser = KityMinder.browser = function(){
  21449. var agent = navigator.userAgent.toLowerCase(),
  21450. opera = window.opera,
  21451. browser = {
  21452. /**
  21453. * @property {boolean} ie 检测当前浏览器是否为IE
  21454. * @example
  21455. * ```javascript
  21456. * if ( UE.browser.ie ) {
  21457. * console.log( '当前浏览器是IE' );
  21458. * }
  21459. * ```
  21460. */
  21461. ie : /(msie\s|trident.*rv:)([\w.]+)/.test(agent),
  21462. /**
  21463. * @property {boolean} opera 检测当前浏览器是否为Opera
  21464. * @example
  21465. * ```javascript
  21466. * if ( UE.browser.opera ) {
  21467. * console.log( '当前浏览器是Opera' );
  21468. * }
  21469. * ```
  21470. */
  21471. opera : ( !!opera && opera.version ),
  21472. /**
  21473. * @property {boolean} webkit 检测当前浏览器是否是webkit内核的浏览器
  21474. * @example
  21475. * ```javascript
  21476. * if ( UE.browser.webkit ) {
  21477. * console.log( '当前浏览器是webkit内核浏览器' );
  21478. * }
  21479. * ```
  21480. */
  21481. webkit : ( agent.indexOf( ' applewebkit/' ) > -1 ),
  21482. /**
  21483. * @property {boolean} mac 检测当前浏览器是否是运行在mac平台下
  21484. * @example
  21485. * ```javascript
  21486. * if ( UE.browser.mac ) {
  21487. * console.log( '当前浏览器运行在mac平台下' );
  21488. * }
  21489. * ```
  21490. */
  21491. mac : ( agent.indexOf( 'macintosh' ) > -1 ),
  21492. /**
  21493. * @property {boolean} quirks 检测当前浏览器是否处于“怪异模式”下
  21494. * @example
  21495. * ```javascript
  21496. * if ( UE.browser.quirks ) {
  21497. * console.log( '当前浏览器运行处于“怪异模式”' );
  21498. * }
  21499. * ```
  21500. */
  21501. quirks : ( document.compatMode == 'BackCompat' ),
  21502. ipad : ( agent.indexOf( 'ipad' ) > -1 )
  21503. };
  21504. /**
  21505. * @property {boolean} gecko 检测当前浏览器内核是否是gecko内核
  21506. * @example
  21507. * ```javascript
  21508. * if ( UE.browser.gecko ) {
  21509. * console.log( '当前浏览器内核是gecko内核' );
  21510. * }
  21511. * ```
  21512. */
  21513. browser.gecko =( navigator.product == 'Gecko' && !browser.webkit && !browser.opera && !browser.ie);
  21514. var version = 0;
  21515. // Internet Explorer 6.0+
  21516. if ( browser.ie ){
  21517. var v1 = agent.match(/(?:msie\s([\w.]+))/);
  21518. var v2 = agent.match(/(?:trident.*rv:([\w.]+))/);
  21519. if(v1 && v2 && v1[1] && v2[1]){
  21520. version = Math.max(v1[1]*1,v2[1]*1);
  21521. }else if(v1 && v1[1]){
  21522. version = v1[1]*1;
  21523. }else if(v2 && v2[1]){
  21524. version = v2[1]*1;
  21525. }else{
  21526. version = 0;
  21527. }
  21528. browser.ie11Compat = document.documentMode == 11;
  21529. /**
  21530. * @property { boolean } ie9Compat 检测浏览器模式是否为 IE9 兼容模式
  21531. * @warning 如果浏览器不是IE, 则该值为undefined
  21532. * @example
  21533. * ```javascript
  21534. * if ( UE.browser.ie9Compat ) {
  21535. * console.log( '当前浏览器运行在IE9兼容模式下' );
  21536. * }
  21537. * ```
  21538. */
  21539. browser.ie9Compat = document.documentMode == 9;
  21540. /**
  21541. * @property { boolean } ie8 检测浏览器是否是IE8浏览器
  21542. * @warning 如果浏览器不是IE, 则该值为undefined
  21543. * @example
  21544. * ```javascript
  21545. * if ( UE.browser.ie8 ) {
  21546. * console.log( '当前浏览器是IE8浏览器' );
  21547. * }
  21548. * ```
  21549. */
  21550. browser.ie8 = !!document.documentMode;
  21551. /**
  21552. * @property { boolean } ie8Compat 检测浏览器模式是否为 IE8 兼容模式
  21553. * @warning 如果浏览器不是IE, 则该值为undefined
  21554. * @example
  21555. * ```javascript
  21556. * if ( UE.browser.ie8Compat ) {
  21557. * console.log( '当前浏览器运行在IE8兼容模式下' );
  21558. * }
  21559. * ```
  21560. */
  21561. browser.ie8Compat = document.documentMode == 8;
  21562. /**
  21563. * @property { boolean } ie7Compat 检测浏览器模式是否为 IE7 兼容模式
  21564. * @warning 如果浏览器不是IE, 则该值为undefined
  21565. * @example
  21566. * ```javascript
  21567. * if ( UE.browser.ie7Compat ) {
  21568. * console.log( '当前浏览器运行在IE7兼容模式下' );
  21569. * }
  21570. * ```
  21571. */
  21572. browser.ie7Compat = ( ( version == 7 && !document.documentMode )
  21573. || document.documentMode == 7 );
  21574. /**
  21575. * @property { boolean } ie6Compat 检测浏览器模式是否为 IE6 模式 或者怪异模式
  21576. * @warning 如果浏览器不是IE, 则该值为undefined
  21577. * @example
  21578. * ```javascript
  21579. * if ( UE.browser.ie6Compat ) {
  21580. * console.log( '当前浏览器运行在IE6模式或者怪异模式下' );
  21581. * }
  21582. * ```
  21583. */
  21584. browser.ie6Compat = ( version < 7 || browser.quirks );
  21585. browser.ie9above = version > 8;
  21586. browser.ie9below = version < 9;
  21587. }
  21588. // Gecko.
  21589. if ( browser.gecko ){
  21590. var geckoRelease = agent.match( /rv:([\d\.]+)/ );
  21591. if ( geckoRelease )
  21592. {
  21593. geckoRelease = geckoRelease[1].split( '.' );
  21594. version = geckoRelease[0] * 10000 + ( geckoRelease[1] || 0 ) * 100 + ( geckoRelease[2] || 0 ) * 1;
  21595. }
  21596. }
  21597. /**
  21598. * @property { Number } chrome 检测当前浏览器是否为Chrome, 如果是,则返回Chrome的大版本号
  21599. * @warning 如果浏览器不是chrome, 则该值为undefined
  21600. * @example
  21601. * ```javascript
  21602. * if ( UE.browser.chrome ) {
  21603. * console.log( '当前浏览器是Chrome' );
  21604. * }
  21605. * ```
  21606. */
  21607. if (/chrome\/(\d+\.\d)/i.test(agent)) {
  21608. browser.chrome = + RegExp['\x241'];
  21609. }
  21610. /**
  21611. * @property { Number } safari 检测当前浏览器是否为Safari, 如果是,则返回Safari的大版本号
  21612. * @warning 如果浏览器不是safari, 则该值为undefined
  21613. * @example
  21614. * ```javascript
  21615. * if ( UE.browser.safari ) {
  21616. * console.log( '当前浏览器是Safari' );
  21617. * }
  21618. * ```
  21619. */
  21620. if(/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(agent) && !/chrome/i.test(agent)){
  21621. browser.safari = + (RegExp['\x241'] || RegExp['\x242']);
  21622. }
  21623. // Opera 9.50+
  21624. if ( browser.opera )
  21625. version = parseFloat( opera.version() );
  21626. // WebKit 522+ (Safari 3+)
  21627. if ( browser.webkit )
  21628. version = parseFloat( agent.match( / applewebkit\/(\d+)/ )[1] );
  21629. /**
  21630. * @property { Number } version 检测当前浏览器版本号
  21631. * @remind
  21632. * <ul>
  21633. * <li>IE系列返回值为5,6,7,8,9,10等</li>
  21634. * <li>gecko系列会返回10900,158900等</li>
  21635. * <li>webkit系列会返回其build号 (如 522等)</li>
  21636. * </ul>
  21637. * @example
  21638. * ```javascript
  21639. * console.log( '当前浏览器版本号是: ' + UE.browser.version );
  21640. * ```
  21641. */
  21642. browser.version = version;
  21643. /**
  21644. * @property { boolean } isCompatible 检测当前浏览器是否能够与UEditor良好兼容
  21645. * @example
  21646. * ```javascript
  21647. * if ( UE.browser.isCompatible ) {
  21648. * console.log( '浏览器与UEditor能够良好兼容' );
  21649. * }
  21650. * ```
  21651. */
  21652. browser.isCompatible =
  21653. !browser.mobile && (
  21654. ( browser.ie && version >= 6 ) ||
  21655. ( browser.gecko && version >= 10801 ) ||
  21656. ( browser.opera && version >= 9.5 ) ||
  21657. ( browser.air && version >= 1 ) ||
  21658. ( browser.webkit && version >= 522 ) ||
  21659. false );
  21660. return browser;
  21661. }();
  21662. //快捷方式
  21663. var ie = browser.ie,
  21664. webkit = browser.webkit,
  21665. gecko = browser.gecko,
  21666. opera = browser.opera;
  21667. /* jshint -W079 */
  21668. var Minder = KityMinder.Minder = kity.createClass('KityMinder', {
  21669. constructor: function(options) {
  21670. this._options = Utils.extend(window.KITYMINDER_CONFIG || {}, options);
  21671. var initQueue = Minder._initFnQueue.slice();
  21672. // @see option.js
  21673. // @see event.js
  21674. // @see status.js
  21675. // @see paper.js
  21676. // @see select.js
  21677. // @see key.js
  21678. // @see contextmenu.js
  21679. // @see module.js
  21680. // @see data.js
  21681. // @see readonly.js
  21682. // @see layout.js
  21683. // @see theme.js
  21684. while (initQueue.length) initQueue.shift().call(this, options);
  21685. this.fire('ready');
  21686. }
  21687. });
  21688. /* jshint +W079 */
  21689. Minder._initFnQueue = [];
  21690. Minder.registerInit = function(fn) {
  21691. Minder._initFnQueue.push(fn);
  21692. };
  21693. var Command = kity.createClass( "Command", {
  21694. constructor: function () {
  21695. this._isContentChange = true;
  21696. this._isSelectionChange = false;
  21697. },
  21698. execute: function ( minder, args ) {
  21699. },
  21700. setContentChanged: function ( val ) {
  21701. this._isContentChange = !! val;
  21702. },
  21703. isContentChanged: function () {
  21704. return this._isContentChange;
  21705. },
  21706. setSelectionChanged: function ( val ) {
  21707. this._isSelectionChange = !! val;
  21708. },
  21709. isSelectionChanged: function () {
  21710. return this._isContentChange;
  21711. },
  21712. queryState: function ( km ) {
  21713. return 0;
  21714. },
  21715. queryValue: function ( km ) {
  21716. return 0;
  21717. },
  21718. isNeedUndo: function () {
  21719. return true;
  21720. }
  21721. } );
  21722. kity.extendClass(Minder, {
  21723. _getCommand: function (name) {
  21724. return this._commands[name.toLowerCase()];
  21725. },
  21726. _queryCommand: function (name, type, args) {
  21727. var cmd = this._getCommand(name);
  21728. if (cmd) {
  21729. var queryCmd = cmd['query' + type];
  21730. if (queryCmd)
  21731. return queryCmd.apply(cmd, [this].concat(args));
  21732. }
  21733. return 0;
  21734. },
  21735. queryCommandState: function (name) {
  21736. return this._queryCommand(name, "State", Utils.argsToArray(1));
  21737. },
  21738. queryCommandValue: function (name) {
  21739. return this._queryCommand(name, "Value", Utils.argsToArray(1));
  21740. },
  21741. execCommand: function (name) {
  21742. name = name.toLowerCase();
  21743. var cmdArgs = Utils.argsToArray(arguments, 1),
  21744. cmd, stoped, result, eventParams;
  21745. var me = this;
  21746. cmd = this._getCommand(name);
  21747. eventParams = {
  21748. command: cmd,
  21749. commandName: name.toLowerCase(),
  21750. commandArgs: cmdArgs
  21751. };
  21752. if (!cmd || !~this.queryCommandState(name)) {
  21753. return false;
  21754. }
  21755. if (!this._hasEnterExecCommand && cmd.isNeedUndo()) {
  21756. this._hasEnterExecCommand = true;
  21757. stoped = this._fire(new MinderEvent('beforeExecCommand', eventParams, true));
  21758. if (!stoped) {
  21759. //保存场景
  21760. this._fire(new MinderEvent('saveScene'));
  21761. this._fire(new MinderEvent("preExecCommand", eventParams, false));
  21762. result = cmd.execute.apply(cmd, [me].concat(cmdArgs));
  21763. this._fire(new MinderEvent('execCommand', eventParams, false));
  21764. //保存场景
  21765. this._fire(new MinderEvent('saveScene'));
  21766. if (cmd.isContentChanged()) {
  21767. this._firePharse(new MinderEvent('contentchange'));
  21768. }
  21769. this._interactChange();
  21770. }
  21771. this._hasEnterExecCommand = false;
  21772. } else {
  21773. result = cmd.execute.apply(cmd, [me].concat(cmdArgs));
  21774. if (!this._hasEnterExecCommand) {
  21775. this._interactChange();
  21776. }
  21777. }
  21778. return result === undefined ? null : result;
  21779. }
  21780. });
  21781. /* jshint -W079 */
  21782. var MinderNode = KityMinder.MinderNode = kity.createClass('MinderNode', {
  21783. /* jshint +W079 */
  21784. /**
  21785. * 创建一个节点
  21786. *
  21787. * @param {KityMinder} minder
  21788. * 节点绑定的脑图的实例
  21789. *
  21790. * @param {String|Object} unknown
  21791. * 节点的初始数据或文本
  21792. */
  21793. constructor: function(unknown) {
  21794. this.parent = null;
  21795. this.root = this;
  21796. this.children = [];
  21797. this.data = {};
  21798. this.tmpData = {};
  21799. this.initContainers();
  21800. if (Utils.isString(unknown)) {
  21801. this.setText(unknown);
  21802. } else {
  21803. this.setData(unknown);
  21804. }
  21805. },
  21806. initContainers: function() {
  21807. this.rc = new kity.Group().setId(KityMinder.uuid('minder_node'));
  21808. this.rc.minderNode = this;
  21809. },
  21810. /**
  21811. * 判断节点是否根节点
  21812. */
  21813. isRoot: function() {
  21814. return this.root === this;
  21815. },
  21816. /**
  21817. * 判断节点是否叶子
  21818. */
  21819. isLeaf: function() {
  21820. return this.children.length === 0;
  21821. },
  21822. /**
  21823. * 获取节点的根节点
  21824. */
  21825. getRoot: function() {
  21826. return this.root || this;
  21827. },
  21828. /**
  21829. * 获得节点的父节点
  21830. */
  21831. getParent: function() {
  21832. return this.parent;
  21833. },
  21834. /**
  21835. * 获得节点的深度
  21836. */
  21837. getLevel: function() {
  21838. var level = 0,
  21839. parent = this.parent;
  21840. while (parent) {
  21841. level++;
  21842. parent = parent.parent;
  21843. }
  21844. return level;
  21845. },
  21846. /**
  21847. * 获得节点的复杂度(即子树中节点的数量)
  21848. */
  21849. getComplex: function() {
  21850. var complex = 0;
  21851. this.traverse(function() {
  21852. complex++;
  21853. });
  21854. return complex;
  21855. },
  21856. /**
  21857. * 获得节点的类型(root|main|sub)
  21858. */
  21859. getType: function(type) {
  21860. this.type = ['root', 'main', 'sub'][Math.min(this.getLevel(), 2)];
  21861. return this.type;
  21862. },
  21863. /**
  21864. * 判断当前节点是否被测试节点的祖先
  21865. * @param {MinderNode} test 被测试的节点
  21866. */
  21867. isAncestorOf: function(test) {
  21868. var p = test.parent;
  21869. while (p) {
  21870. if (p == this) return true;
  21871. p = p.parent;
  21872. }
  21873. return false;
  21874. },
  21875. /**
  21876. * 设置节点的文本数据
  21877. * @param {String} text 文本数据
  21878. */
  21879. setText: function(text) {
  21880. if(utils.isArray(text)){
  21881. text = text.join('\n');
  21882. }
  21883. return this.setData('text', text);
  21884. },
  21885. /**
  21886. * 获取节点的文本数据
  21887. * @return {String}
  21888. */
  21889. getText: function(str2arr) {
  21890. var text = this.getData('text') || '';
  21891. if(str2arr){
  21892. text = text.split('\n');
  21893. }
  21894. return text;
  21895. },
  21896. /**
  21897. * 先序遍历当前节点树
  21898. * @param {Function} fn 遍历函数
  21899. */
  21900. preTraverse: function(fn, excludeThis) {
  21901. var children = this.getChildren();
  21902. if (!excludeThis) fn(this);
  21903. for (var i = 0; i < children.length; i++) {
  21904. children[i].preTraverse(fn);
  21905. }
  21906. },
  21907. /**
  21908. * 后序遍历当前节点树
  21909. * @param {Function} fn 遍历函数
  21910. */
  21911. postTraverse: function(fn, excludeThis) {
  21912. var children = this.getChildren();
  21913. for (var i = 0; i < children.length; i++) {
  21914. children[i].postTraverse(fn);
  21915. }
  21916. if (!excludeThis) fn(this);
  21917. },
  21918. traverse: function(fn, excludeThis) {
  21919. return this.postTraverse(fn, excludeThis);
  21920. },
  21921. getChildren: function() {
  21922. return this.children;
  21923. },
  21924. getIndex: function() {
  21925. return this.parent ? this.parent.children.indexOf(this) : -1;
  21926. },
  21927. insertChild: function(node, index) {
  21928. if (index === undefined) {
  21929. index = this.children.length;
  21930. }
  21931. if (node.parent) {
  21932. node.parent.removeChild(node);
  21933. }
  21934. node.parent = this;
  21935. node.root = this.root;
  21936. this.children.splice(index, 0, node);
  21937. },
  21938. appendChild: function(node) {
  21939. return this.insertChild(node);
  21940. },
  21941. prependChild: function(node) {
  21942. return this.insertChild(node, 0);
  21943. },
  21944. removeChild: function(elem) {
  21945. var index = elem,
  21946. removed;
  21947. if (elem instanceof MinderNode) {
  21948. index = this.children.indexOf(elem);
  21949. }
  21950. if (index >= 0) {
  21951. removed = this.children.splice(index, 1)[0];
  21952. removed.parent = null;
  21953. removed.root = removed;
  21954. }
  21955. },
  21956. getChild: function(index) {
  21957. return this.children[index];
  21958. },
  21959. getFirstChild: function() {
  21960. return this.children[0];
  21961. },
  21962. getLastChild: function() {
  21963. return this.children[this.children.length - 1];
  21964. },
  21965. getData: function(name) {
  21966. if (name === undefined) {
  21967. return this.data;
  21968. }
  21969. return this.data[name];
  21970. },
  21971. setData: function(name, value) {
  21972. if (name === undefined) {
  21973. this.data = {};
  21974. } else if (utils.isObject(name)) {
  21975. Utils.extend(this.data, name);
  21976. } else {
  21977. if (value === undefined) {
  21978. this.data[name] = null;
  21979. delete this.data[name];
  21980. } else {
  21981. this.data[name] = value;
  21982. }
  21983. }
  21984. return this;
  21985. },
  21986. getRenderContainer: function() {
  21987. return this.rc;
  21988. },
  21989. getCommonAncestor: function(node) {
  21990. return Utils.getNodeCommonAncestor(this, node);
  21991. },
  21992. contains: function(node) {
  21993. return this == node || this.isAncestorOf(node);
  21994. },
  21995. clone: function() {
  21996. function cloneNode(parent, isClonedNode) {
  21997. var cloned = new KM.MinderNode();
  21998. cloned.data = Utils.clonePlainObject(isClonedNode.getData());
  21999. cloned.tmpData = Utils.clonePlainObject(isClonedNode.getTmpData());
  22000. if (parent) {
  22001. parent.appendChild(cloned);
  22002. }
  22003. for (var i = 0, ci;
  22004. (ci = isClonedNode.children[i++]);) {
  22005. cloneNode(cloned, ci);
  22006. }
  22007. return cloned;
  22008. }
  22009. return cloneNode(null, this);
  22010. },
  22011. equals: function(node,ignoreSelected) {
  22012. var me = this;
  22013. function restoreSelected(){
  22014. if(isSelectedA){
  22015. me.setSelectedFlag();
  22016. }
  22017. if(isSelectedB){
  22018. node.setSelectedFlag();
  22019. }
  22020. }
  22021. if(ignoreSelected){
  22022. var isSelectedA = false;
  22023. var isSelectedB = false;
  22024. if(me.isSelected()){
  22025. isSelectedA = true;
  22026. me.clearSelectedFlag();
  22027. }
  22028. if(node.isSelected()){
  22029. isSelectedB = true;
  22030. node.clearSelectedFlag();
  22031. }
  22032. }
  22033. if (node.children.length != this.children.length) {
  22034. restoreSelected();
  22035. return false;
  22036. }
  22037. if (utils.compareObject(node.getData(), me.getData()) === false) {
  22038. restoreSelected();
  22039. return false;
  22040. }
  22041. if (utils.compareObject(node.getTmpData(), me.getTmpData()) === false) {
  22042. restoreSelected();
  22043. return false;
  22044. }
  22045. for (var i = 0, ci;
  22046. (ci = me.children[i]); i++) {
  22047. if (ci.equals(node.children[i],ignoreSelected) === false) {
  22048. restoreSelected();
  22049. return false;
  22050. }
  22051. }
  22052. restoreSelected();
  22053. return true;
  22054. },
  22055. clearChildren: function() {
  22056. this.children = [];
  22057. },
  22058. setTmpData: function(a, v) {
  22059. var me = this;
  22060. if (utils.isObject(a)) {
  22061. utils.each(a, function(key, val) {
  22062. me.setTmpData(key, val);
  22063. });
  22064. }
  22065. if (v === undefined || v === null || v === '') {
  22066. delete this.tmpData[a];
  22067. } else {
  22068. this.tmpData[a] = v;
  22069. }
  22070. },
  22071. getTmpData: function(a) {
  22072. if (a === undefined) {
  22073. return this.tmpData;
  22074. }
  22075. return this.tmpData[a];
  22076. },
  22077. setValue: function(node) {
  22078. this.data = {};
  22079. this.setData(utils.clonePlainObject(node.getData()));
  22080. this.tmpData = {};
  22081. this.setTmpData(utils.clonePlainObject(node.getTmpData()));
  22082. return this;
  22083. }
  22084. });
  22085. MinderNode.getCommonAncestor = function(nodeA, nodeB) {
  22086. if (nodeA instanceof Array) {
  22087. return MinderNode.getCommonAncestor.apply(this, nodeA);
  22088. }
  22089. switch (arguments.length) {
  22090. case 1:
  22091. return nodeA.parent || nodeA;
  22092. case 2:
  22093. if (nodeA.isAncestorOf(nodeB)) {
  22094. return nodeA;
  22095. }
  22096. if (nodeB.isAncestorOf(nodeA)) {
  22097. return nodeB;
  22098. }
  22099. var ancestor = nodeA.parent;
  22100. while (ancestor && !ancestor.isAncestorOf(nodeB)) {
  22101. ancestor = ancestor.parent;
  22102. }
  22103. return ancestor;
  22104. default:
  22105. return Array.prototype.reduce.call(arguments, function(prev, current) {
  22106. return MinderNode.getCommonAncestor(prev, current);
  22107. }, nodeA);
  22108. }
  22109. };
  22110. kity.extendClass(Minder, {
  22111. getRoot: function() {
  22112. return this._root;
  22113. },
  22114. setRoot: function(root) {
  22115. this._root = root;
  22116. root.minder = this;
  22117. },
  22118. createNode: function(unknown, parent, index) {
  22119. var node = new MinderNode(unknown);
  22120. this.fire('nodecreate', { node: node, parent: parent, index: index });
  22121. this.appendNode(node, parent, index);
  22122. return node;
  22123. },
  22124. appendNode: function(node, parent, index) {
  22125. if (parent) parent.insertChild(node, index);
  22126. this.attachNode(node);
  22127. return this;
  22128. },
  22129. removeNode: function(node) {
  22130. if (node.parent) {
  22131. node.parent.removeChild(node);
  22132. this.detachNode(node);
  22133. this.fire('noderemove', { node: node });
  22134. }
  22135. },
  22136. attachNode: function(node) {
  22137. var rc = this._rc;
  22138. node.traverse(function(current) {
  22139. current.attached = true;
  22140. rc.addShape(current.getRenderContainer());
  22141. });
  22142. rc.addShape(node.getRenderContainer());
  22143. this.fire('nodeattach', {
  22144. node: node
  22145. });
  22146. },
  22147. detachNode: function(node) {
  22148. var rc = this._rc;
  22149. node.traverse(function(current) {
  22150. current.attached = false;
  22151. rc.removeShape(current.getRenderContainer());
  22152. });
  22153. this.fire('nodedetach', {
  22154. node: node
  22155. });
  22156. },
  22157. getMinderTitle: function() {
  22158. return this.getRoot().getText();
  22159. }
  22160. });
  22161. kity.extendClass(MinderNode, {
  22162. getMinder: function() {
  22163. return this.getRoot().minder;
  22164. }
  22165. });
  22166. /**
  22167. * @fileOverview
  22168. *
  22169. * 提供脑图选项支持
  22170. *
  22171. * @author: techird
  22172. * @copyright: Baidu FEX, 2014
  22173. */
  22174. kity.extendClass(Minder, {
  22175. getOptions: function(key) {
  22176. var val;
  22177. if (key) {
  22178. val = this.getPreferences(key);
  22179. return val && val[key] || this._options[key];
  22180. } else {
  22181. val = this.getPreferences();
  22182. return utils.extend(val, this._options, true);
  22183. }
  22184. },
  22185. setDefaultOptions: function(key, val, cover) {
  22186. var obj = {};
  22187. if (Utils.isString(key)) {
  22188. obj[key] = val;
  22189. } else {
  22190. obj = key;
  22191. }
  22192. utils.extend(this._options, obj, !cover);
  22193. },
  22194. setOptions: function(key, val) {
  22195. this.setPreferences(key, val);
  22196. }
  22197. });
  22198. Minder.registerInit(function(option) {
  22199. this.setDefaultOptions(KM.defaultOptions);
  22200. });
  22201. var MinderEvent = kity.createClass('MindEvent', {
  22202. constructor: function(type, params, canstop) {
  22203. params = params || {};
  22204. if (params.getType && params.getType() == 'ShapeEvent') {
  22205. this.kityEvent = params;
  22206. this.originEvent = params.originEvent;
  22207. this.getPosition = params.getPosition.bind(params);
  22208. } else if (params.target && params.preventDefault) {
  22209. this.originEvent = params;
  22210. } else {
  22211. kity.Utils.extend(this, params);
  22212. }
  22213. this.type = type;
  22214. this._canstop = canstop || false;
  22215. },
  22216. getTargetNode: function() {
  22217. var findShape = this.kityEvent && this.kityEvent.targetShape;
  22218. if (!findShape) return null;
  22219. while (!findShape.minderNode && findShape.container) {
  22220. findShape = findShape.container;
  22221. }
  22222. var node = findShape.minderNode;
  22223. if (node && findShape.getOpacity() < 1) return null;
  22224. return node || null;
  22225. },
  22226. stopPropagation: function() {
  22227. this._stoped = true;
  22228. },
  22229. stopPropagationImmediately: function() {
  22230. this._immediatelyStoped = true;
  22231. this._stoped = true;
  22232. },
  22233. shouldStopPropagation: function() {
  22234. return this._canstop && this._stoped;
  22235. },
  22236. shouldStopPropagationImmediately: function() {
  22237. return this._canstop && this._immediatelyStoped;
  22238. },
  22239. preventDefault: function() {
  22240. this.originEvent.preventDefault();
  22241. },
  22242. isRightMB: function() {
  22243. var isRightMB = false;
  22244. if (!this.originEvent) {
  22245. return false;
  22246. }
  22247. if ("which" in this.originEvent)
  22248. isRightMB = this.originEvent.which == 3;
  22249. else if ("button" in this.originEvent)
  22250. isRightMB = this.originEvent.button == 2;
  22251. return isRightMB;
  22252. },
  22253. getKeyCode: function(){
  22254. var evt = this.originEvent;
  22255. return evt.keyCode || evt.which;
  22256. }
  22257. });
  22258. Minder.registerInit(function() {
  22259. this._initEvents();
  22260. });
  22261. // 事件机制
  22262. kity.extendClass(Minder, {
  22263. _initEvents: function() {
  22264. this._eventCallbacks = {};
  22265. },
  22266. _bindEvents: function() {
  22267. this._bindPaperEvents();
  22268. this._bindKeyboardEvents();
  22269. },
  22270. _resetEvents: function() {
  22271. this._initEvents();
  22272. this._bindEvents();
  22273. },
  22274. // TODO: mousemove lazy bind
  22275. _bindPaperEvents: function() {
  22276. this._paper.on('click dblclick mousedown contextmenu mouseup mousemove mouseover mousewheel DOMMouseScroll touchstart touchmove touchend dragenter dragleave drop', this._firePharse.bind(this));
  22277. if (window) {
  22278. window.addEventListener('resize', this._firePharse.bind(this));
  22279. window.addEventListener('blur', this._firePharse.bind(this));
  22280. }
  22281. },
  22282. _bindKeyboardEvents: function() {
  22283. if ((navigator.userAgent.indexOf('iPhone') == -1) && (navigator.userAgent.indexOf('iPod') == -1) && (navigator.userAgent.indexOf('iPad') == -1)) {
  22284. //只能在这里做,要不无法触发
  22285. Utils.listen(document.body, 'keydown keyup keypress paste', this._firePharse.bind(this));
  22286. }
  22287. },
  22288. _firePharse: function(e) {
  22289. // //只读模式下强了所有的事件操作
  22290. // if(this.readOnly === true){
  22291. // return false;
  22292. // }
  22293. var beforeEvent, preEvent, executeEvent;
  22294. if (e.type == 'DOMMouseScroll') {
  22295. e.type = 'mousewheel';
  22296. e.wheelDelta = e.originEvent.wheelDelta = e.originEvent.detail * -10;
  22297. e.wheelDeltaX = e.originEvent.mozMovementX;
  22298. e.wheelDeltaY = e.originEvent.mozMovementY;
  22299. }
  22300. beforeEvent = new MinderEvent('before' + e.type, e, true);
  22301. if (this._fire(beforeEvent)) {
  22302. return;
  22303. }
  22304. preEvent = new MinderEvent('pre' + e.type, e, true);
  22305. executeEvent = new MinderEvent(e.type, e, true);
  22306. if (this._fire(preEvent) ||
  22307. this._fire(executeEvent))
  22308. this._fire(new MinderEvent('after' + e.type, e, false));
  22309. },
  22310. _interactChange: function(e) {
  22311. var me = this;
  22312. if (me._interactScheduled) return;
  22313. setTimeout(function() {
  22314. me._fire(new MinderEvent('interactchange'));
  22315. me._interactScheduled = false;
  22316. }, 100);
  22317. me._interactScheduled = true;
  22318. },
  22319. _listen: function(type, callback) {
  22320. var callbacks = this._eventCallbacks[type] || (this._eventCallbacks[type] = []);
  22321. callbacks.push(callback);
  22322. },
  22323. _fire: function(e) {
  22324. var status = this.getStatus();
  22325. var callbacks = this._eventCallbacks[e.type.toLowerCase()] || [];
  22326. if (status) {
  22327. callbacks = callbacks.concat(this._eventCallbacks[status + '.' + e.type.toLowerCase()] || []);
  22328. }
  22329. if (callbacks.length === 0) {
  22330. return;
  22331. }
  22332. var lastStatus = this.getStatus();
  22333. for (var i = 0; i < callbacks.length; i++) {
  22334. callbacks[i].call(this, e);
  22335. /* this.getStatus() != lastStatus ||*/
  22336. if (e.shouldStopPropagationImmediately()) {
  22337. break;
  22338. }
  22339. }
  22340. return e.shouldStopPropagation();
  22341. },
  22342. on: function(name, callback) {
  22343. var km = this;
  22344. utils.each(name.split(/\s+/), function(i, n) {
  22345. km._listen(n.toLowerCase(), callback);
  22346. });
  22347. return this;
  22348. },
  22349. off: function(name, callback) {
  22350. var types = name.split(/\s+/);
  22351. var i, j, callbacks, removeIndex;
  22352. for (i = 0; i < types.length; i++) {
  22353. callbacks = this._eventCallbacks[types[i].toLowerCase()];
  22354. if (callbacks) {
  22355. removeIndex = null;
  22356. for (j = 0; j < callbacks.length; j++) {
  22357. if (callbacks[j] == callback) {
  22358. removeIndex = j;
  22359. }
  22360. }
  22361. if (removeIndex !== null) {
  22362. callbacks.splice(removeIndex, 1);
  22363. }
  22364. }
  22365. }
  22366. },
  22367. fire: function(type, params) {
  22368. var e = new MinderEvent(type, params);
  22369. this._fire(e);
  22370. return this;
  22371. }
  22372. });
  22373. /**
  22374. * @fileOverview
  22375. *
  22376. * 状态切换控制
  22377. *
  22378. * @author: techird
  22379. * @copyright: Baidu FEX, 2014
  22380. */
  22381. Minder.registerInit(function() {
  22382. this._initStatus();
  22383. });
  22384. kity.extendClass(Minder, {
  22385. _initStatus: function() {
  22386. this._status = 'normal';
  22387. this._rollbackStatus = 'normal';
  22388. },
  22389. setStatus: (function() {
  22390. var sf = ~window.location.href.indexOf('status');
  22391. var tf = ~window.location.href.indexOf('trace');
  22392. // 在 readonly 模式下,只有 force 为 true 才能切换回来
  22393. return function(status, force) {
  22394. if (this._status == 'readonly' && !force) return this;
  22395. if (status != this._status) {
  22396. this._rollbackStatus = this._status;
  22397. this._status = status;
  22398. this.fire('statuschange', {
  22399. lastStatus: this._rollbackStatus,
  22400. currentStatus: this._status
  22401. });
  22402. if (sf) {
  22403. console.log(window.event.type, this._rollbackStatus, '->', this._status);
  22404. if (tf) {
  22405. console.trace();
  22406. }
  22407. }
  22408. }
  22409. return this;
  22410. };
  22411. })(),
  22412. rollbackStatus: function() {
  22413. this.setStatus(this._rollbackStatus);
  22414. },
  22415. getRollbackStatus:function(){
  22416. return this._rollbackStatus;
  22417. },
  22418. getStatus: function() {
  22419. return this._status;
  22420. }
  22421. });
  22422. /**
  22423. * @fileOverview
  22424. *
  22425. * 初始化渲染容器
  22426. *
  22427. * @author: techird
  22428. * @copyright: Baidu FEX, 2014
  22429. */
  22430. Minder.registerInit(function() {
  22431. this._initPaper();
  22432. });
  22433. kity.extendClass(Minder, {
  22434. _initPaper: function() {
  22435. this._paper = new kity.Paper();
  22436. this._paper.getNode().setAttribute('contenteditable', true);
  22437. this._paper.getNode().ondragstart = function(e) {
  22438. e.preventDefault();
  22439. };
  22440. this._paper.shapeNode.setAttribute('transform', 'translate(0.5, 0.5)');
  22441. this._addRenderContainer();
  22442. this.setRoot(this.createNode(this.getLang().maintopic));
  22443. if (this._options.renderTo) {
  22444. this.renderTo(this._options.renderTo);
  22445. }
  22446. },
  22447. _addRenderContainer: function() {
  22448. this._rc = new kity.Group().setId(KityMinder.uuid('minder'));
  22449. this._paper.addShape(this._rc);
  22450. },
  22451. renderTo: function(target) {
  22452. this._paper.renderTo(this._renderTarget = target);
  22453. this._bindEvents();
  22454. },
  22455. getRenderContainer: function() {
  22456. return this._rc;
  22457. },
  22458. getPaper: function() {
  22459. return this._paper;
  22460. },
  22461. getRenderTarget: function() {
  22462. return this._renderTarget;
  22463. },
  22464. });
  22465. Minder.registerInit(function() {
  22466. this._initSelection();
  22467. });
  22468. // 选区管理
  22469. kity.extendClass(Minder, {
  22470. _initSelection: function() {
  22471. this._selectedNodes = [];
  22472. },
  22473. renderChangedSelection: function(last) {
  22474. var current = this.getSelectedNodes();
  22475. var changed = [];
  22476. var i = 0;
  22477. current.forEach(function(node) {
  22478. if (last.indexOf(node) == -1) {
  22479. changed.push(node);
  22480. node.setTmpData('selected', true);
  22481. }
  22482. });
  22483. last.forEach(function(node) {
  22484. if (current.indexOf(node) == -1) {
  22485. changed.push(node);
  22486. node.setTmpData('selected', false);
  22487. }
  22488. });
  22489. if (changed.length) {
  22490. this._interactChange();
  22491. this.fire('selectionchange');
  22492. }
  22493. while (i < changed.length) changed[i++].render();
  22494. },
  22495. getSelectedNodes: function() {
  22496. //不能克隆返回,会对当前选区操作,从而影响querycommand
  22497. return this._selectedNodes;
  22498. },
  22499. getSelectedNode: function() {
  22500. return this.getSelectedNodes()[0] || null;
  22501. },
  22502. removeAllSelectedNodes: function() {
  22503. var me = this;
  22504. var last = this._selectedNodes.splice(0);
  22505. this._selectedNodes = [];
  22506. this.renderChangedSelection(last);
  22507. return this.fire('selectionclear');
  22508. },
  22509. removeSelectedNodes: function(nodes) {
  22510. var me = this;
  22511. var last = this._selectedNodes.slice(0);
  22512. nodes = Utils.isArray(nodes) ? nodes : [nodes];
  22513. Utils.each(nodes, function(i, n) {
  22514. var index;
  22515. if ((index = me._selectedNodes.indexOf(n)) === -1) return;
  22516. me._selectedNodes.splice(index, 1);
  22517. });
  22518. this.renderChangedSelection(last);
  22519. return this;
  22520. },
  22521. select: function(nodes, isSingleSelect) {
  22522. var lastSelect = this.getSelectedNodes().slice(0);
  22523. if (isSingleSelect) {
  22524. this._selectedNodes = [];
  22525. }
  22526. var me = this;
  22527. nodes = Utils.isArray(nodes) ? nodes : [nodes];
  22528. Utils.each(nodes, function(i, n) {
  22529. if (me._selectedNodes.indexOf(n) !== -1) return;
  22530. me._selectedNodes.push(n);
  22531. });
  22532. this.renderChangedSelection(lastSelect);
  22533. return this;
  22534. },
  22535. //当前选区中的节点在给定的节点范围内的保留选中状态,
  22536. //没在给定范围的取消选中,给定范围中的但没在当前选中范围的也做选中效果
  22537. toggleSelect: function(node) {
  22538. if (Utils.isArray(node)) {
  22539. node.forEach(this.toggleSelect.bind(this));
  22540. } else {
  22541. if (node.isSelected()) this.removeSelectedNodes(node);
  22542. else this.select(node);
  22543. }
  22544. return this;
  22545. },
  22546. isSingleSelect: function() {
  22547. return this._selectedNodes.length == 1;
  22548. },
  22549. getSelectedAncestors: function(includeRoot) {
  22550. var nodes = this.getSelectedNodes().slice(0),
  22551. ancestors = [],
  22552. judge;
  22553. // 根节点不参与计算
  22554. var rootIndex = nodes.indexOf(this.getRoot());
  22555. if (~rootIndex && !includeRoot) {
  22556. nodes.splice(rootIndex, 1);
  22557. }
  22558. // 判断 nodes 列表中是否存在 judge 的祖先
  22559. function hasAncestor(nodes, judge) {
  22560. for (var i = nodes.length - 1; i >= 0; --i) {
  22561. if (nodes[i].isAncestorOf(judge)) return true;
  22562. }
  22563. return false;
  22564. }
  22565. // 按照拓扑排序
  22566. nodes.sort(function(node1, node2) {
  22567. return node1.getLevel() - node2.getLevel();
  22568. });
  22569. // 因为是拓扑有序的,所以只需往上查找
  22570. while ((judge = nodes.pop())) {
  22571. if (!hasAncestor(nodes, judge)) {
  22572. ancestors.push(judge);
  22573. }
  22574. }
  22575. return ancestors;
  22576. }
  22577. });
  22578. kity.extendClass(MinderNode, {
  22579. isSelected: function() {
  22580. return this.getTmpData('selected');
  22581. },
  22582. clearSelectedFlag:function(){
  22583. this.setTmpData('selected');
  22584. },
  22585. setSelectedFlag:function(){
  22586. this.setTmpData('selected',true);
  22587. }
  22588. });
  22589. /**
  22590. * @fileOverview
  22591. *
  22592. * 添加快捷键支持
  22593. *
  22594. * @author: techird
  22595. * @copyright: Baidu FEX, 2014
  22596. */
  22597. /**
  22598. * 计算包含 meta 键的 keycode
  22599. *
  22600. * @param {String|KeyEvent} unknown
  22601. */
  22602. function getMetaKeyCode(unknown) {
  22603. var CTRL_MASK = 0x1000;
  22604. var ALT_MASK = 0x2000;
  22605. var SHIFT_MASK = 0x4000;
  22606. var metaKeyCode = 0;
  22607. if (typeof(unknown) == 'string') {
  22608. // unknown as string
  22609. unknown.toLowerCase().split(/\+\s*/).forEach(function(name) {
  22610. switch(name) {
  22611. case 'ctrl':
  22612. case 'cmd':
  22613. metaKeyCode |= CTRL_MASK;
  22614. break;
  22615. case 'alt':
  22616. metaKeyCode |= ALT_MASK;
  22617. break;
  22618. case 'shift':
  22619. metaKeyCode |= SHIFT_MASK;
  22620. break;
  22621. default:
  22622. metaKeyCode |= keymap[name];
  22623. }
  22624. });
  22625. } else {
  22626. // unknown as key event
  22627. if (unknown.ctrlKey || unknown.metaKey) {
  22628. metaKeyCode |= CTRL_MASK;
  22629. }
  22630. if (unknown.altKey) {
  22631. metaKeyCode |= ALT_MASK;
  22632. }
  22633. if (unknown.shiftKey) {
  22634. metaKeyCode |= SHIFT_MASK;
  22635. }
  22636. metaKeyCode |= unknown.keyCode;
  22637. }
  22638. return metaKeyCode;
  22639. }
  22640. kity.extendClass(MinderEvent, {
  22641. isShortcutKey: function(keyCombine) {
  22642. var keyEvent = this.originEvent;
  22643. if (!keyEvent) return false;
  22644. return getMetaKeyCode(keyCombine) == getMetaKeyCode(keyEvent);
  22645. }
  22646. });
  22647. Minder.registerInit(function() {
  22648. this._initShortcutKey();
  22649. });
  22650. kity.extendClass(Minder, {
  22651. _initShortcutKey: function() {
  22652. this._bindShortcutKeys();
  22653. },
  22654. _bindShortcutKeys: function() {
  22655. var map = this._shortcutKeys = {};
  22656. var has = 'hasOwnProperty';
  22657. this.on('keydown', function(e) {
  22658. for (var keys in map) {
  22659. if (!map[has](keys)) continue;
  22660. if (e.isShortcutKey(keys)) {
  22661. var fn = map[keys];
  22662. if (fn.__statusCondition && fn.__statusCondition != this.getStatus()) return;
  22663. fn();
  22664. e.preventDefault();
  22665. }
  22666. }
  22667. });
  22668. },
  22669. addShortcut: function(keys, fn) {
  22670. var binds = this._shortcutKeys;
  22671. keys.split(/\|\s*/).forEach(function(combine) {
  22672. var parts = combine.split('::');
  22673. var status;
  22674. if (parts.length > 1) {
  22675. combine = parts[1];
  22676. status = parts[0];
  22677. fn.__statusCondition = status;
  22678. }
  22679. binds[combine] = fn;
  22680. });
  22681. },
  22682. addCommandShortcutKeys: function(cmd, keys) {
  22683. var binds = this._commandShortcutKeys || (this._commandShortcutKeys = {});
  22684. var obj = {},
  22685. km = this;
  22686. if (keys) {
  22687. obj[cmd] = keys;
  22688. } else {
  22689. obj = cmd;
  22690. }
  22691. var minder = this;
  22692. utils.each(obj, function(command, keys) {
  22693. binds[command] = keys;
  22694. minder.addShortcut(keys, function execCommandByShortcut() {
  22695. if (minder.queryCommandState(command) === 0) {
  22696. minder.execCommand(command);
  22697. }
  22698. });
  22699. });
  22700. },
  22701. getCommandShortcutKey: function(cmd) {
  22702. var binds = this._commandShortcutKeys;
  22703. return binds && binds[cmd] || null;
  22704. }
  22705. });
  22706. /**
  22707. * @fileOverview
  22708. *
  22709. * 添加模块上下文菜单支持
  22710. *
  22711. * @author: techird
  22712. * @copyright: Baidu FEX, 2014
  22713. */
  22714. Minder.registerInit(function() {
  22715. this._initContextMenu();
  22716. });
  22717. kity.extendClass(Minder, {
  22718. _initContextMenu: function() {
  22719. this.contextmenus = [];
  22720. },
  22721. addContextMenu: function(item) {
  22722. if (utils.isArray(item)) {
  22723. this.contextmenus = this.contextmenus.concat(item);
  22724. } else {
  22725. this.contextmenus.push(item);
  22726. }
  22727. return this;
  22728. },
  22729. getContextMenu: function() {
  22730. return this.contextmenus;
  22731. }
  22732. });
  22733. //模块注册&暴露模块接口
  22734. ( function () {
  22735. var _modules;
  22736. KityMinder.registerModule = function ( name, module ) {
  22737. //初始化模块列表
  22738. if ( !_modules ) {
  22739. _modules = {};
  22740. }
  22741. _modules[ name ] = module;
  22742. };
  22743. KityMinder.getModules = function () {
  22744. return _modules;
  22745. };
  22746. } )();
  22747. Minder.registerInit(function() {
  22748. this._initModules();
  22749. });
  22750. // 模块声明周期维护
  22751. kity.extendClass(Minder, {
  22752. _initModules: function() {
  22753. var modulesPool = KityMinder.getModules();
  22754. var modulesToLoad = this._options.modules || Utils.keys(modulesPool);
  22755. this._commands = {};
  22756. this._query = {};
  22757. this._modules = {};
  22758. this._rendererClasses = {};
  22759. var i, name, type, module, moduleDeals,
  22760. dealCommands, dealEvents, dealRenderers;
  22761. var me = this;
  22762. for (i = 0; i < modulesToLoad.length; i++) {
  22763. name = modulesToLoad[i];
  22764. if (!modulesPool[name]) continue;
  22765. // 执行模块初始化,抛出后续处理对象
  22766. if (typeof(modulesPool[name]) == 'function') {
  22767. moduleDeals = modulesPool[name].call(me);
  22768. } else {
  22769. moduleDeals = modulesPool[name];
  22770. }
  22771. this._modules[name] = moduleDeals;
  22772. if (!moduleDeals) continue;
  22773. if (moduleDeals.init) {
  22774. moduleDeals.init.call(me, this._options);
  22775. }
  22776. // command加入命令池子
  22777. dealCommands = moduleDeals.commands;
  22778. for (name in dealCommands) {
  22779. this._commands[name.toLowerCase()] = new dealCommands[name]();
  22780. }
  22781. // 绑定事件
  22782. dealEvents = moduleDeals.events;
  22783. if (dealEvents) {
  22784. for (type in dealEvents) {
  22785. me.on(type, dealEvents[type]);
  22786. }
  22787. }
  22788. // 渲染器
  22789. dealRenderers = moduleDeals.renderers;
  22790. if (dealRenderers) {
  22791. for (type in dealRenderers) {
  22792. this._rendererClasses[type] = this._rendererClasses[type] || [];
  22793. if (Utils.isArray(dealRenderers[type])) {
  22794. this._rendererClasses[type] = this._rendererClasses[type].concat(dealRenderers[type]);
  22795. } else {
  22796. this._rendererClasses[type].push(dealRenderers[type]);
  22797. }
  22798. }
  22799. }
  22800. if (moduleDeals.defaultOptions) {
  22801. this.setDefaultOptions(moduleDeals.defaultOptions);
  22802. }
  22803. //添加模块的快捷键
  22804. if (moduleDeals.commandShortcutKeys) {
  22805. this.addCommandShortcutKeys(moduleDeals.commandShortcutKeys);
  22806. }
  22807. //添加邮件菜单
  22808. if (moduleDeals.contextmenu) {
  22809. this.addContextMenu(moduleDeals.contextmenu);
  22810. }
  22811. }
  22812. },
  22813. _garbage: function() {
  22814. this.clearSelect();
  22815. while (this._root.getChildren().length) {
  22816. this._root.removeChild(0);
  22817. }
  22818. },
  22819. destroy: function() {
  22820. var modules = this._modules;
  22821. this._resetEvents();
  22822. this._garbage();
  22823. for (var key in modules) {
  22824. if (!modules[key].destroy) continue;
  22825. modules[key].destroy.call(this);
  22826. }
  22827. },
  22828. reset: function() {
  22829. var modules = this._modules;
  22830. this._garbage();
  22831. for (var key in modules) {
  22832. if (!modules[key].reset) continue;
  22833. modules[key].reset.call(this);
  22834. }
  22835. }
  22836. });
  22837. Utils.extend(KityMinder, {
  22838. _protocols: {},
  22839. registerProtocol: function(name, protocolDeal) {
  22840. KityMinder._protocols[name] = protocolDeal;
  22841. }
  22842. });
  22843. var DEFAULT_TEXT = {
  22844. 'root': 'maintopic',
  22845. 'main': 'topic',
  22846. 'sub': 'topic'
  22847. };
  22848. Minder.registerInit(function() {
  22849. this._initProtocols();
  22850. });
  22851. // 导入导出
  22852. kity.extendClass(Minder, {
  22853. _initProtocols: function(options) {
  22854. var protocols = this._protocols = {};
  22855. var pool = KityMinder._protocols;
  22856. for (var name in pool) {
  22857. if (pool.hasOwnProperty(name))
  22858. protocols[name] = pool[name](this);
  22859. protocols[name].name = name;
  22860. }
  22861. },
  22862. getProtocol: function(name) {
  22863. return this._protocols[name] || null;
  22864. },
  22865. getSupportedProtocols: function() {
  22866. var protocols = this._protocols;
  22867. return Utils.keys(protocols).map(function(name) {
  22868. return protocols[name];
  22869. });
  22870. },
  22871. exportJson: function() {
  22872. /* 导出 node 上整棵树的数据为 JSON */
  22873. function exportNode(node) {
  22874. var exported = {};
  22875. exported.data = node.getData();
  22876. var childNodes = node.getChildren();
  22877. if (childNodes.length) {
  22878. exported.children = [];
  22879. for (var i = 0; i < childNodes.length; i++) {
  22880. exported.children.push(exportNode(childNodes[i]));
  22881. }
  22882. }
  22883. return exported;
  22884. }
  22885. var json = exportNode(this.getRoot());
  22886. json.template = this.getTemplate();
  22887. json.theme = this.getTheme();
  22888. json.version = KityMinder.version;
  22889. return json;
  22890. },
  22891. importJson: function(json, params) {
  22892. function importNode(node, json, km) {
  22893. var data = json.data;
  22894. node.data = {};
  22895. for (var field in data) {
  22896. node.setData(field, data[field]);
  22897. }
  22898. node.setData('text', data.text || km.getLang(DEFAULT_TEXT[node.getType()]));
  22899. var childrenTreeData = json.children || [];
  22900. for (var i = 0; i < childrenTreeData.length; i++) {
  22901. var childNode = km.createNode(null, node);
  22902. importNode(childNode, childrenTreeData[i], km);
  22903. }
  22904. return node;
  22905. }
  22906. if (!json) return;
  22907. this._fire(new MinderEvent('preimport', params, false));
  22908. // 删除当前所有节点
  22909. while (this._root.getChildren().length) {
  22910. this.removeNode(this._root.getChildren()[0]);
  22911. }
  22912. json = KityMinder.compatibility(json);
  22913. importNode(this._root, json, this);
  22914. this.setTemplate(json.template || 'default');
  22915. this.setTheme(json.theme || null);
  22916. this.refresh();
  22917. this.fire('import', params);
  22918. this._firePharse({
  22919. type: 'contentchange'
  22920. });
  22921. this._interactChange();
  22922. },
  22923. exportData: function(protocolName, options) {
  22924. var json, protocol;
  22925. json = this.exportJson();
  22926. // 指定了协议进行导出,需要检测协议是否支持
  22927. if (protocolName) {
  22928. protocol = this.getProtocol(protocolName);
  22929. if (!protocol || !protocol.encode) {
  22930. return Promise.reject(new Error('Not supported protocol:' + protocolName));
  22931. }
  22932. }
  22933. // 导出前抛个事件
  22934. this._fire(new MinderEvent('beforeexport', {
  22935. json: json,
  22936. protocolName: protocolName,
  22937. protocol: protocol
  22938. }));
  22939. if (protocol) {
  22940. return Promise.resolve(protocol.encode(json, this, options));
  22941. } else {
  22942. return Promise.resolve(json);
  22943. }
  22944. },
  22945. importData: function(local, protocolName) {
  22946. var json, protocol;
  22947. var minder = this;
  22948. // 指定了协议进行导入,需要检测协议是否支持
  22949. if (protocolName) {
  22950. protocol = this.getProtocol(protocolName);
  22951. if (!protocol || !protocol.decode) {
  22952. return Promise.reject(new Error('Not supported protocol:' + protocolName));
  22953. }
  22954. }
  22955. var params = {
  22956. local: local,
  22957. protocolName: protocolName,
  22958. protocol: protocol
  22959. };
  22960. // 导入前抛事件
  22961. this._fire(new MinderEvent('beforeimport', params));
  22962. return new Promise(function(resolve, reject) {
  22963. resolve(protocol ? protocol.decode(local) : local);
  22964. }).then(function(json) {
  22965. minder.importJson(json, params);
  22966. return json;
  22967. });
  22968. }
  22969. });
  22970. /**
  22971. * @fileOverview
  22972. *
  22973. *
  22974. *
  22975. * @author: techird
  22976. * @copyright: Baidu FEX, 2014
  22977. */
  22978. Minder.registerInit(function(options) {
  22979. if (options.readOnly) {
  22980. this.setDisabled();
  22981. }
  22982. });
  22983. kity.extendClass(Minder, {
  22984. disable: function() {
  22985. var me = this;
  22986. //禁用命令
  22987. me.bkqueryCommandState = me.queryCommandState;
  22988. me.bkqueryCommandValue = me.queryCommandValue;
  22989. me.queryCommandState = function(type) {
  22990. var cmd = this._getCommand(type);
  22991. if (cmd && cmd.enableReadOnly) {
  22992. return me.bkqueryCommandState.apply(me, arguments);
  22993. }
  22994. return -1;
  22995. };
  22996. me.queryCommandValue = function(type) {
  22997. var cmd = this._getCommand(type);
  22998. if (cmd && cmd.enableReadOnly) {
  22999. return me.bkqueryCommandValue.apply(me, arguments);
  23000. }
  23001. return null;
  23002. };
  23003. this.setStatus('readonly');
  23004. me._interactChange();
  23005. },
  23006. enable: function() {
  23007. var me = this;
  23008. if (me.bkqueryCommandState) {
  23009. me.queryCommandState = me.bkqueryCommandState;
  23010. delete me.bkqueryCommandState;
  23011. }
  23012. if (me.bkqueryCommandValue) {
  23013. me.queryCommandValue = me.bkqueryCommandValue;
  23014. delete me.bkqueryCommandValue;
  23015. }
  23016. this.setStatus('normal');
  23017. me._interactChange();
  23018. }
  23019. });
  23020. /**
  23021. * 布局支持池子管理
  23022. */
  23023. Utils.extend(KityMinder, {
  23024. _layout: {},
  23025. registerLayout: function(name, layout) {
  23026. KityMinder._layout[name] = layout;
  23027. if (!KityMinder._defaultLayout) {
  23028. KityMinder._defaultLayout = name;
  23029. }
  23030. },
  23031. getLayoutList: function() {
  23032. return this._layout;
  23033. },
  23034. getLayoutInstance: function(name) {
  23035. var LayoutClass = KityMinder._layout[name];
  23036. if (!LayoutClass) throw new Error('Missing Layout: ' + name);
  23037. var layout = new LayoutClass();
  23038. return layout;
  23039. }
  23040. });
  23041. /**
  23042. * MinderNode 上的布局支持
  23043. */
  23044. kity.extendClass(MinderNode, {
  23045. /**
  23046. * 获得当前节点的布局名称
  23047. *
  23048. * @return {String}
  23049. */
  23050. getLayout: function() {
  23051. var layout = this.getData('layout');
  23052. layout = layout || (this.isRoot() ? KityMinder._defaultLayout : this.parent.getLayout());
  23053. return layout;
  23054. },
  23055. setLayout: function(name) {
  23056. if (name) {
  23057. if (name == 'inherit') {
  23058. this.setData('layout');
  23059. } else {
  23060. this.setData('layout', name);
  23061. }
  23062. }
  23063. return this;
  23064. },
  23065. layout: function(name, duration) {
  23066. this.setLayout(name).getMinder().layout(duration);
  23067. return this;
  23068. },
  23069. getLayoutInstance: function() {
  23070. return KityMinder.getLayoutInstance(this.getLayout());
  23071. },
  23072. getOrderHint: function(refer) {
  23073. return this.parent.getLayoutInstance().getOrderHint(this);
  23074. },
  23075. getExpandPosition: function() {
  23076. return this.getLayoutInstance().getExpandPosition();
  23077. },
  23078. /**
  23079. * 获取当前节点相对于父节点的布局变换
  23080. */
  23081. getLayoutTransform: function() {
  23082. return this._layoutTransform || new kity.Matrix();
  23083. },
  23084. /**
  23085. * 第一轮布局计算后,获得的全局布局位置
  23086. *
  23087. * @return {[type]} [description]
  23088. */
  23089. getGlobalLayoutTransformPreview: function() {
  23090. var pMatrix = this.parent ? this.parent.getLayoutTransform() : new kity.Matrix();
  23091. var matrix = this.getLayoutTransform();
  23092. var offset = this.getLayoutOffset();
  23093. if (offset) {
  23094. matrix.translate(offset.x, offset.y);
  23095. }
  23096. return pMatrix.merge(matrix);
  23097. },
  23098. getLayoutPointPreview: function() {
  23099. return this.getGlobalLayoutTransformPreview().transformPoint(new kity.Point());
  23100. },
  23101. /**
  23102. * 获取节点相对于全局的布局变换
  23103. */
  23104. getGlobalLayoutTransform: function() {
  23105. if (this._globalLayoutTransform) {
  23106. return this._globalLayoutTransform;
  23107. } else if (this.parent) {
  23108. return this.parent.getGlobalLayoutTransform();
  23109. } else {
  23110. return new kity.Matrix();
  23111. }
  23112. },
  23113. /**
  23114. * 设置当前节点相对于父节点的布局变换
  23115. */
  23116. setLayoutTransform: function(matrix) {
  23117. this._layoutTransform = matrix;
  23118. return this;
  23119. },
  23120. /**
  23121. * 设置当前节点相对于全局的布局变换(冗余优化)
  23122. */
  23123. setGlobalLayoutTransform: function(matrix) {
  23124. this.getRenderContainer().setMatrix(this._globalLayoutTransform = matrix);
  23125. return this;
  23126. },
  23127. setVertexIn: function(p) {
  23128. this._vertexIn = p;
  23129. },
  23130. setVertexOut: function(p) {
  23131. this._vertexOut = p;
  23132. },
  23133. getVertexIn: function() {
  23134. return this._vertexIn || new kity.Point();
  23135. },
  23136. getVertexOut: function() {
  23137. return this._vertexOut || new kity.Point();
  23138. },
  23139. getLayoutVertexIn: function() {
  23140. return this.getGlobalLayoutTransform().transformPoint(this.getVertexIn());
  23141. },
  23142. getLayoutVertexOut: function() {
  23143. return this.getGlobalLayoutTransform().transformPoint(this.getVertexOut());
  23144. },
  23145. setLayoutVectorIn: function(v) {
  23146. this._layoutVectorIn = v;
  23147. return this;
  23148. },
  23149. setLayoutVectorOut: function(v) {
  23150. this._layoutVectorOut = v;
  23151. return this;
  23152. },
  23153. getLayoutVectorIn: function() {
  23154. return this._layoutVectorIn || new kity.Vector();
  23155. },
  23156. getLayoutVectorOut: function() {
  23157. return this._layoutVectorOut || new kity.Vector();
  23158. },
  23159. getLayoutBox: function() {
  23160. var matrix = this.getGlobalLayoutTransform();
  23161. return matrix.transformBox(this.getContentBox());
  23162. },
  23163. getLayoutPoint: function() {
  23164. var matrix = this.getGlobalLayoutTransform();
  23165. return matrix.transformPoint(new kity.Point());
  23166. },
  23167. getLayoutOffset: function() {
  23168. if (!this.parent) return new kity.Point();
  23169. // 影响当前节点位置的是父节点的布局
  23170. var data = this.getData('layout_' + this.parent.getLayout() + '_offset');
  23171. if (data) return new kity.Point(data.x, data.y);
  23172. return new kity.Point();
  23173. },
  23174. setLayoutOffset: function(p) {
  23175. if (!this.parent) return this;
  23176. if (p && !this.hasLayoutOffset()) {
  23177. var m = this.getLayoutTransform().m;
  23178. p = p.offset(m.e, m.f);
  23179. this.setLayoutTransform(null);
  23180. }
  23181. this.setData('layout_' + this.parent.getLayout() + '_offset', p ? {
  23182. x: p.x,
  23183. y: p.y
  23184. } : null);
  23185. return this;
  23186. },
  23187. hasLayoutOffset: function() {
  23188. return !!this.getData('layout_' + this.parent.getLayout() + '_offset');
  23189. },
  23190. resetLayoutOffset: function() {
  23191. return this.setLayoutOffset(null);
  23192. },
  23193. getLayoutRoot: function() {
  23194. if (this.isLayoutRoot()) {
  23195. return this;
  23196. }
  23197. return this.parent.getLayoutRoot();
  23198. },
  23199. isLayoutRoot: function() {
  23200. return this.getData('layout') || this.isRoot();
  23201. }
  23202. });
  23203. Minder.registerInit(function(options) {
  23204. this.refresh();
  23205. });
  23206. kity.extendClass(Minder, {
  23207. layout: function(duration) {
  23208. this.getRoot().traverse(function(node) {
  23209. // clear last results
  23210. node.setLayoutTransform(null);
  23211. });
  23212. function layoutNode(node, round) {
  23213. // layout all children first
  23214. // 剪枝:收起的节点无需计算
  23215. if (node.isExpanded() || true) {
  23216. node.children.forEach(function(child) {
  23217. layoutNode(child, round);
  23218. });
  23219. }
  23220. var layout = node.getLayoutInstance();
  23221. var childrenInFlow = node.getChildren().filter(function(child) {
  23222. return !child.hasLayoutOffset();
  23223. });
  23224. layout.doLayout(node, childrenInFlow, round);
  23225. }
  23226. // 第一轮布局
  23227. layoutNode(this.getRoot(), 1);
  23228. // 第二轮布局
  23229. layoutNode(this.getRoot(), 2);
  23230. duration = duration ? 300 : 0;
  23231. var minder = this;
  23232. this.applyLayoutResult(this.getRoot(), duration).then(function() {
  23233. minder.fire('layoutallfinish');
  23234. });
  23235. return this.fire('layout');
  23236. },
  23237. refresh: function(duration) {
  23238. this.getRoot().renderTree();
  23239. this.layout(duration).fire('contentchange')._interactChange();
  23240. return this;
  23241. },
  23242. applyLayoutResult: function(root, duration) {
  23243. root = root || this.getRoot();
  23244. var me = this;
  23245. var deffered = {};
  23246. var promise = new Promise(function(resolve, reject) {
  23247. deffered.resolve = resolve;
  23248. deffered.reject = reject;
  23249. });
  23250. var complex = root.getComplex();
  23251. function consume() {
  23252. if (!--complex) {
  23253. deffered.resolve();
  23254. }
  23255. }
  23256. // 节点复杂度大于 100,关闭动画
  23257. if (complex > 200) duration = 0;
  23258. function applyMatrix(node, matrix) {
  23259. node.setGlobalLayoutTransform(matrix);
  23260. me.fire('layoutapply', {
  23261. node: node,
  23262. matrix: matrix
  23263. });
  23264. }
  23265. function apply(node, pMatrix) {
  23266. var matrix = node.getLayoutTransform().merge(pMatrix);
  23267. var lastMatrix = node.getGlobalLayoutTransform() || new kity.Matrix();
  23268. var offset = node.getLayoutOffset();
  23269. matrix.translate(offset.x, offset.y);
  23270. matrix.m.e = Math.round(matrix.m.e);
  23271. matrix.m.f = Math.round(matrix.m.f);
  23272. // 如果当前有动画,停止动画
  23273. if (node._layoutTimeline) {
  23274. node._layoutTimeline.stop();
  23275. node._layoutTimeline = null;
  23276. }
  23277. // 如果要求以动画形式来更新,创建动画
  23278. if (duration) {
  23279. node._layoutTimeline = new kity.Animator(lastMatrix, matrix, applyMatrix)
  23280. .start(node, duration, 'ease')
  23281. .on('finish', function() {
  23282. //可能性能低的时候会丢帧,手动添加一帧
  23283. setTimeout(function() {
  23284. applyMatrix(node, matrix);
  23285. me.fire('layoutfinish', {
  23286. node: node,
  23287. matrix: matrix
  23288. });
  23289. consume();
  23290. }, 150);
  23291. });
  23292. }
  23293. // 否则直接更新
  23294. else {
  23295. applyMatrix(node, matrix);
  23296. me.fire('layoutfinish', {
  23297. node: node,
  23298. matrix: matrix
  23299. });
  23300. consume();
  23301. }
  23302. for (var i = 0; i < node.children.length; i++) {
  23303. apply(node.children[i], matrix);
  23304. }
  23305. }
  23306. apply(root, root.parent ? root.parent.getGlobalLayoutTransform() : new kity.Matrix());
  23307. return promise;
  23308. },
  23309. });
  23310. /**
  23311. * @class Layout 布局基类,具体布局需要从该类派生
  23312. */
  23313. var Layout = kity.createClass('Layout', {
  23314. /**
  23315. * @abstract
  23316. *
  23317. * 子类需要实现的布局算法,该算法输入一个节点,排布该节点的子节点(相对父节点的变换)
  23318. *
  23319. * @param {MinderNode} node 需要布局的节点
  23320. *
  23321. * @example
  23322. *
  23323. * doLayout: function(node) {
  23324. * var children = node.getChildren();
  23325. * // layout calculation
  23326. * children[i].setLayoutTransform(new kity.Matrix().translate(x, y));
  23327. * }
  23328. */
  23329. doLayout: function(node) {
  23330. throw new Error('Not Implement: Layout.doLayout()');
  23331. },
  23332. /**
  23333. * 对齐指定的节点
  23334. *
  23335. * @param {Array<MinderNode>} nodes 要对齐的节点
  23336. * @param {string} border 对齐边界,允许取值 left, right, top, bottom
  23337. *
  23338. */
  23339. align: function(nodes, border, offset) {
  23340. var me = this;
  23341. offset = offset || 0;
  23342. nodes.forEach(function(node) {
  23343. var tbox = me.getTreeBox([node]);
  23344. var matrix = node.getLayoutTransform();
  23345. switch (border) {
  23346. case 'left':
  23347. return matrix.translate(offset - tbox.left, 0);
  23348. case 'right':
  23349. return matrix.translate(offset - tbox.right, 0);
  23350. case 'top':
  23351. return matrix.translate(0, offset - tbox.top);
  23352. case 'bottom':
  23353. return matrix.translate(0, offset - tbox.bottom);
  23354. }
  23355. });
  23356. },
  23357. stack: function(nodes, axis, distance) {
  23358. var me = this;
  23359. var position = 0;
  23360. distance = distance || function(node, next, axis) {
  23361. return node.getStyle({
  23362. x: 'margin-right',
  23363. y: 'margin-bottom'
  23364. }[axis]) + next.getStyle({
  23365. x: 'margin-left',
  23366. y: 'margin-top'
  23367. }[axis]);
  23368. };
  23369. nodes.forEach(function(node, index, nodes) {
  23370. var tbox = me.getTreeBox([node]);
  23371. var size = {
  23372. x: tbox.width,
  23373. y: tbox.height
  23374. }[axis];
  23375. var offset = {
  23376. x: tbox.left,
  23377. y: tbox.top
  23378. }[axis];
  23379. var matrix = node.getLayoutTransform();
  23380. if (axis == 'x') {
  23381. matrix.translate(position - offset, 0);
  23382. } else {
  23383. matrix.translate(0, position - offset);
  23384. }
  23385. position += size;
  23386. if (nodes[index + 1])
  23387. position += distance(node, nodes[index + 1], axis);
  23388. });
  23389. return position;
  23390. },
  23391. move: function(nodes, dx, dy) {
  23392. nodes.forEach(function(node) {
  23393. node.getLayoutTransform().translate(dx, dy);
  23394. });
  23395. },
  23396. /**
  23397. * 工具方法:获取给点的节点所占的布局区域
  23398. *
  23399. * @param {MinderNode[]} nodes 需要计算的节点
  23400. *
  23401. * @return {Box} 计算结果
  23402. */
  23403. getBranchBox: function(nodes) {
  23404. var box = new kity.Box();
  23405. var i, node, matrix, contentBox;
  23406. for (i = 0; i < nodes.length; i++) {
  23407. node = nodes[i];
  23408. matrix = node.getLayoutTransform();
  23409. contentBox = node.getContentBox();
  23410. box = box.merge(matrix.transformBox(contentBox));
  23411. }
  23412. return box;
  23413. },
  23414. /**
  23415. * 工具方法:计算给定的节点的子树所占的布局区域
  23416. *
  23417. * @param {MinderNode} nodes 需要计算的节点
  23418. *
  23419. * @return {Box} 计算的结果
  23420. */
  23421. getTreeBox: function(nodes) {
  23422. var i, node, matrix, treeBox;
  23423. var g = KityMinder.Geometry;
  23424. var box = {
  23425. x: 0,
  23426. y: 0,
  23427. height: 0,
  23428. width: 0
  23429. };
  23430. if (!(nodes instanceof Array)) nodes = [nodes];
  23431. for (i = 0; i < nodes.length; i++) {
  23432. node = nodes[i];
  23433. matrix = node.getLayoutTransform();
  23434. treeBox = node.getContentBox();
  23435. if (node.isExpanded() && node.children.length) {
  23436. treeBox = g.mergeBox(treeBox, this.getTreeBox(node.children));
  23437. }
  23438. box = g.mergeBox(box, matrix.transformBox(treeBox));
  23439. }
  23440. return box;
  23441. },
  23442. getOrderHint: function(node) {
  23443. return [];
  23444. }
  23445. });
  23446. var LayoutCommand = kity.createClass('LayoutCommand', {
  23447. base: Command,
  23448. execute: function(minder, name) {
  23449. var nodes = minder.getSelectedNodes();
  23450. nodes.forEach(function(node) {
  23451. node.layout(name);
  23452. });
  23453. },
  23454. queryValue: function(minder) {
  23455. var node = minder.getSelectedNode();
  23456. if (node) {
  23457. return node.getData('layout');
  23458. }
  23459. },
  23460. queryState: function(minder) {
  23461. return minder.getSelectedNode() ? 0 : -1;
  23462. }
  23463. });
  23464. var ResetLayoutCommand = kity.createClass('ResetLayoutCommand', {
  23465. base: Command,
  23466. execute: function(minder, name) {
  23467. var nodes = minder.getSelectedNodes();
  23468. if (!nodes.length) nodes = [minder.getRoot()];
  23469. nodes.forEach(function(node) {
  23470. node.traverse(function(child) {
  23471. child.resetLayoutOffset();
  23472. if (!child.isRoot()) {
  23473. child.setData('layout', null);
  23474. }
  23475. });
  23476. });
  23477. minder.layout(300);
  23478. },
  23479. enableReadOnly: true
  23480. });
  23481. KityMinder.registerModule('LayoutModule', {
  23482. commands: {
  23483. 'layout': LayoutCommand,
  23484. 'resetlayout': ResetLayoutCommand
  23485. },
  23486. contextmenu: [{
  23487. command: 'resetlayout'
  23488. }, {
  23489. divider: true
  23490. }],
  23491. commandShortcutKeys: {
  23492. 'resetlayout': 'Ctrl+Shift+L'
  23493. }
  23494. });
  23495. var cssLikeValueMatcher = {
  23496. left: function(value) {
  23497. return 3 in value && value[3] ||
  23498. 1 in value && value[1] ||
  23499. value[0];
  23500. },
  23501. right: function(value) {
  23502. return 1 in value && value[1] || value[0];
  23503. },
  23504. top: function(value) {
  23505. return value[0];
  23506. },
  23507. bottom: function(value) {
  23508. return 2 in value && value[2] || value[0];
  23509. }
  23510. };
  23511. Utils.extend(KityMinder, {
  23512. _themes: {},
  23513. /**
  23514. * 注册一个主题
  23515. *
  23516. * @param {String} name 主题的名称
  23517. * @param {Plain} theme 主题的样式描述
  23518. *
  23519. * @example
  23520. * KityMinder.registerTheme('default', {
  23521. * 'root-color': 'red',
  23522. * 'root-stroke': 'none',
  23523. * 'root-padding': [10, 20]
  23524. * });
  23525. */
  23526. registerTheme: function(name, theme) {
  23527. KityMinder._themes[name] = theme;
  23528. },
  23529. getThemeList: function() {
  23530. return KityMinder._themes;
  23531. }
  23532. });
  23533. kity.extendClass(Minder, {
  23534. /**
  23535. * 切换脑图实例上的主题
  23536. * @param {String} name 要使用的主题的名称
  23537. */
  23538. useTheme: function(name) {
  23539. this.setTheme(name);
  23540. this.refresh(800);
  23541. return true;
  23542. },
  23543. setTheme: function(name) {
  23544. this._theme = name || null;
  23545. this.getRenderTarget().style.background = this.getStyle('background');
  23546. this.fire('themechange', {
  23547. theme: name
  23548. });
  23549. },
  23550. /**
  23551. * 获取脑图实例上的当前主题
  23552. * @return {[type]} [description]
  23553. */
  23554. getTheme: function(node) {
  23555. return this._theme || this.getOptions('defaultTheme');
  23556. },
  23557. getThemeItems: function(node) {
  23558. var theme = this.getTheme(node);
  23559. return KityMinder._themes[this.getTheme(node)];
  23560. },
  23561. /**
  23562. * 获得脑图实例上的样式
  23563. * @param {String} item 样式名称
  23564. */
  23565. getStyle: function(item, node) {
  23566. var items = this.getThemeItems(node);
  23567. var segment, dir, selector, value, matcher;
  23568. if (item in items) return items[item];
  23569. // 尝试匹配 CSS 数组形式的值
  23570. // 比如 item 为 'pading-left'
  23571. // theme 里有 {'padding': [10, 20]} 的定义,则可以返回 20
  23572. segment = item.split('-');
  23573. if (segment.length < 2) return null;
  23574. dir = segment.pop();
  23575. item = segment.join('-');
  23576. if (item in items) {
  23577. value = items[item];
  23578. if (Utils.isArray(value) && (matcher = cssLikeValueMatcher[dir])) {
  23579. return matcher(value);
  23580. }
  23581. if (!isNaN(value)) return value;
  23582. }
  23583. return null;
  23584. },
  23585. /**
  23586. * 获取指定节点的样式
  23587. * @param {String} name 样式名称,可以不加节点类型的前缀
  23588. */
  23589. getNodeStyle: function(node, name) {
  23590. var value = this.getStyle(node.getType() + '-' + name, node);
  23591. return value !== null ? value : this.getStyle(name, node);
  23592. }
  23593. });
  23594. kity.extendClass(MinderNode, {
  23595. getStyle: function(name) {
  23596. return this.getMinder().getNodeStyle(this, name);
  23597. }
  23598. });
  23599. KityMinder.registerModule('Theme', {
  23600. defaultOptions: {
  23601. defaultTheme: 'fresh-blue'
  23602. },
  23603. commands: {
  23604. 'theme': kity.createClass('ThemeCommand', {
  23605. base: Command,
  23606. execute: function(km, name) {
  23607. return km.useTheme(name);
  23608. },
  23609. queryValue: function(km) {
  23610. return km.getTheme() || 'default';
  23611. }
  23612. })
  23613. }
  23614. });
  23615. Minder.registerInit(function() {
  23616. this.setTheme();
  23617. });
  23618. Utils.extend(KityMinder, {
  23619. compatibility: function(json) {
  23620. var version = json.version || '1.1.3';
  23621. function traverse(node, fn) {
  23622. fn(node);
  23623. if (node.children) node.children.forEach(function(child) {
  23624. traverse(child, fn);
  23625. });
  23626. }
  23627. /* 脑图数据升级 */
  23628. function c_120_130(json) {
  23629. traverse(json, function(node) {
  23630. var data = node.data;
  23631. delete data.layout_bottom_offset;
  23632. delete data.layout_default_offset;
  23633. delete data.layout_filetree_offset;
  23634. });
  23635. }
  23636. /**
  23637. * 脑图数据升级
  23638. * v1.1.3 => v1.2.0
  23639. * */
  23640. function c_113_120(json) {
  23641. // 原本的布局风格
  23642. var ocs = json.data.currentstyle;
  23643. delete json.data.currentstyle;
  23644. // 为 1.2 选择模板,同时保留老版本文件的皮肤
  23645. if (ocs == 'bottom') {
  23646. json.template = 'structure';
  23647. json.theme = 'snow';
  23648. } else if (ocs == 'default') {
  23649. json.template = 'default';
  23650. json.theme = 'classic';
  23651. }
  23652. traverse(json, function(node) {
  23653. var data = node.data;
  23654. // 升级优先级、进度图标
  23655. if ('PriorityIcon' in data) {
  23656. data.priority = data.PriorityIcon;
  23657. delete data.PriorityIcon;
  23658. }
  23659. if ('ProgressIcon' in data) {
  23660. data.progress = 1 + ((data.ProgressIcon - 1) << 1);
  23661. delete data.ProgressIcon;
  23662. }
  23663. // 删除过时属性
  23664. delete data.point;
  23665. delete data.layout;
  23666. });
  23667. }
  23668. switch (version) {
  23669. case '1.1.3':
  23670. c_113_120(json);
  23671. case '1.2.0':
  23672. case '1.2.1':
  23673. c_120_130(json);
  23674. }
  23675. return json;
  23676. }
  23677. });
  23678. var Renderer = KityMinder.Renderer = kity.createClass('Renderer', {
  23679. constructor: function(node) {
  23680. this.node = node;
  23681. },
  23682. create: function(node) {
  23683. throw new Error('Not implement: Renderer.create()');
  23684. },
  23685. shouldRender: function(node) {
  23686. return true;
  23687. },
  23688. watchChange: function(data) {
  23689. var changed;
  23690. if (this.watchingData === undefined) {
  23691. changed = true;
  23692. } else if (this.watchingData != data) {
  23693. changed = true;
  23694. } else {
  23695. changed = false;
  23696. }
  23697. this.watchingData = data;
  23698. },
  23699. shouldDraw: function(node) {
  23700. return true;
  23701. },
  23702. update: function(shape, node, box) {
  23703. if (this.shouldDraw()) this.draw(shape, node);
  23704. return this.place(shape, node, box);
  23705. },
  23706. draw: function(shape, node) {
  23707. throw new Error('Not implement: Renderer.draw()');
  23708. },
  23709. place: function(shape, node, box) {
  23710. throw new Error('Not implement: Renderer.place()');
  23711. },
  23712. getRenderShape: function() {
  23713. return this._renderShape || null;
  23714. },
  23715. setRenderShape: function(shape) {
  23716. this._renderShape = shape;
  23717. }
  23718. });
  23719. kity.extendClass(Minder, (function() {
  23720. function createRendererForNode(node, registered) {
  23721. var renderers = [];
  23722. ['center', 'left', 'right', 'top', 'bottom', 'outline', 'outside'].forEach(function(section) {
  23723. var before = 'before' + section;
  23724. var after = 'after' + section;
  23725. if (registered[before]) {
  23726. renderers = renderers.concat(registered[before]);
  23727. }
  23728. if (registered[section]) {
  23729. renderers = renderers.concat(registered[section]);
  23730. }
  23731. if (registered[after]) {
  23732. renderers = renderers.concat(registered[after]);
  23733. }
  23734. });
  23735. node._renderers = renderers.map(function(Renderer) {
  23736. return new Renderer(node);
  23737. });
  23738. }
  23739. return {
  23740. renderNodeBatch: function(nodes) {
  23741. var rendererClasses = this._rendererClasses;
  23742. var lastBoxes = [];
  23743. var rendererCount = 0;
  23744. var i, j, renderer, node;
  23745. if (!nodes.length) return;
  23746. for (j = 0; j < nodes.length; j++) {
  23747. node = nodes[j];
  23748. if (!node._renderers) {
  23749. createRendererForNode(node, rendererClasses);
  23750. }
  23751. node._contentBox = new kity.Box();
  23752. this.fire('beforerender', {
  23753. node: node
  23754. });
  23755. }
  23756. // 所有节点渲染器数量是一致的
  23757. rendererCount = nodes[0]._renderers.length;
  23758. for (i = 0; i < rendererCount; i++) {
  23759. // 获取延迟盒子数据
  23760. for (j = 0; j < nodes.length; j++) {
  23761. if (typeof(lastBoxes[j]) == 'function') {
  23762. lastBoxes[j] = lastBoxes[j]();
  23763. }
  23764. if (!(lastBoxes[j] instanceof kity.Box)) {
  23765. lastBoxes[j] = new kity.Box(lastBoxes[j]);
  23766. }
  23767. }
  23768. for (j = 0; j < nodes.length; j++) {
  23769. node = nodes[j];
  23770. renderer = node._renderers[i];
  23771. // 合并盒子
  23772. if (lastBoxes[j]) {
  23773. node._contentBox = node._contentBox.merge(lastBoxes[j]);
  23774. }
  23775. // 判断当前上下文是否应该渲染
  23776. if (renderer.shouldRender(node)) {
  23777. // 应该渲染,但是渲染图形没创建过,需要创建
  23778. if (!renderer.getRenderShape()) {
  23779. renderer.setRenderShape(renderer.create(node));
  23780. if (renderer.bringToBack) {
  23781. node.getRenderContainer().prependShape(renderer.getRenderShape());
  23782. } else {
  23783. node.getRenderContainer().appendShape(renderer.getRenderShape());
  23784. }
  23785. }
  23786. // 强制让渲染图形显示
  23787. renderer.getRenderShape().setVisible(true);
  23788. // 更新渲染图形
  23789. lastBoxes[j] = renderer.update(renderer.getRenderShape(), node, node._contentBox);
  23790. }
  23791. // 如果不应该渲染,但是渲染图形创建过了,需要隐藏起来
  23792. else if (renderer.getRenderShape()) {
  23793. renderer.getRenderShape().setVisible(false);
  23794. lastBoxes[j] = null;
  23795. }
  23796. }
  23797. }
  23798. for (j = 0; j < nodes.length; j++) {
  23799. this.fire('noderender', {
  23800. node: nodes[j]
  23801. });
  23802. }
  23803. },
  23804. renderNode: function(node) {
  23805. var rendererClasses = this._rendererClasses;
  23806. var g = KityMinder.Geometry;
  23807. var i, latestBox, renderer;
  23808. if (!node._renderers) {
  23809. createRendererForNode(node, rendererClasses);
  23810. }
  23811. this.fire('beforerender', {
  23812. node: node
  23813. });
  23814. node._contentBox = new kity.Box();
  23815. node._renderers.forEach(function(renderer) {
  23816. // 判断当前上下文是否应该渲染
  23817. if (renderer.shouldRender(node)) {
  23818. // 应该渲染,但是渲染图形没创建过,需要创建
  23819. if (!renderer.getRenderShape()) {
  23820. renderer.setRenderShape(renderer.create(node));
  23821. if (renderer.bringToBack) {
  23822. node.getRenderContainer().prependShape(renderer.getRenderShape());
  23823. } else {
  23824. node.getRenderContainer().appendShape(renderer.getRenderShape());
  23825. }
  23826. }
  23827. // 强制让渲染图形显示
  23828. renderer.getRenderShape().setVisible(true);
  23829. // 更新渲染图形
  23830. latestBox = renderer.update(renderer.getRenderShape(), node, node._contentBox);
  23831. if (typeof(latestBox) == 'function') latestBox = latestBox();
  23832. // 合并渲染区域
  23833. if (latestBox) {
  23834. node._contentBox = node._contentBox.merge(latestBox);
  23835. }
  23836. }
  23837. // 如果不应该渲染,但是渲染图形创建过了,需要隐藏起来
  23838. else if (renderer.getRenderShape()) {
  23839. renderer.getRenderShape().setVisible(false);
  23840. }
  23841. });
  23842. this.fire('noderender', {
  23843. node: node
  23844. });
  23845. }
  23846. };
  23847. })());
  23848. kity.extendClass(MinderNode, {
  23849. render: function() {
  23850. if (!this.attached) return;
  23851. this.getMinder().renderNode(this);
  23852. return this;
  23853. },
  23854. renderTree: function() {
  23855. if (!this.attached) return;
  23856. var list = [];
  23857. this.traverse(function(node) {
  23858. list.push(node);
  23859. });
  23860. this.getMinder().renderNodeBatch(list);
  23861. return this;
  23862. },
  23863. getRenderer: function(type) {
  23864. var rs = this._renderers;
  23865. for (var i = 0; i < rs.length; i++) {
  23866. if (rs[i].getType() == type) return rs[i];
  23867. }
  23868. return null;
  23869. },
  23870. getContentBox: function() {
  23871. //if (!this._contentBox) this.render();
  23872. return this.parent && this.parent.isCollapsed() ? new kity.Box() : (this._contentBox || new kity.Box());
  23873. }
  23874. });
  23875. /* global Renderer: true */
  23876. utils.extend(KityMinder, {
  23877. _connectProviders: {},
  23878. _defaultConnectProvider: function(node, parent, connection) {
  23879. connection.setPathData([
  23880. 'M', parent.getLayoutVertexOut(),
  23881. 'L', node.getLayoutVertexIn()
  23882. ]);
  23883. },
  23884. registerConnectProvider: function(name, provider) {
  23885. KityMinder._connectProviders[name] = provider;
  23886. },
  23887. getConnectProvider: function(name) {
  23888. return KityMinder._connectProviders[name] || KityMinder._defaultConnectProvider;
  23889. }
  23890. });
  23891. kity.extendClass(MinderNode, {
  23892. getConnectProvider: function() {
  23893. return KityMinder.getConnectProvider(this.getConnect());
  23894. },
  23895. getConnect: function() {
  23896. return null;
  23897. },
  23898. getConnection: function() {
  23899. return this._connection || null;
  23900. }
  23901. });
  23902. kity.extendClass(Minder, {
  23903. getConnectContainer: function() {
  23904. return this._connectContainer;
  23905. },
  23906. createConnect: function(node) {
  23907. if (node.isRoot()) return;
  23908. var connection = new kity.Path();
  23909. node._connection = connection;
  23910. this._connectContainer.addShape(connection);
  23911. this.updateConnect(node);
  23912. },
  23913. removeConnect: function(node) {
  23914. var me = this;
  23915. node.traverse(function(node) {
  23916. me._connectContainer.removeShape(node._connection);
  23917. node._connection = null;
  23918. });
  23919. },
  23920. updateConnect: function(node) {
  23921. var connection = node._connection;
  23922. var parent = node.parent;
  23923. if (!parent || !connection) return;
  23924. if (parent.isCollapsed()) {
  23925. connection.setVisible(false);
  23926. return;
  23927. }
  23928. connection.setVisible(true);
  23929. var provider = node.getConnectProvider();
  23930. var strokeColor = node.getStyle('connect-color') || 'white',
  23931. strokeWidth = node.getStyle('connect-width') || 2;
  23932. connection.stroke(strokeColor, strokeWidth);
  23933. provider(node, parent, connection, strokeWidth, strokeColor);
  23934. if (strokeWidth % 2 === 0) {
  23935. connection.setTranslate(0.5, 0.5);
  23936. } else {
  23937. connection.setTranslate(0, 0);
  23938. }
  23939. }
  23940. });
  23941. KityMinder.registerModule('Connect', {
  23942. init: function() {
  23943. this._connectContainer = new kity.Group().setId(KityMinder.uuid('minder_connect_group'));
  23944. this.getRenderContainer().prependShape(this._connectContainer);
  23945. },
  23946. events: {
  23947. 'nodeattach': function(e) {
  23948. this.createConnect(e.node);
  23949. },
  23950. 'nodedetach': function(e) {
  23951. this.removeConnect(e.node);
  23952. },
  23953. 'layoutapply layoutfinish noderender': function(e) {
  23954. this.updateConnect(e.node);
  23955. }
  23956. }
  23957. });
  23958. utils.extend(KityMinder, {
  23959. _templates: {},
  23960. registerTemplate: function(name, supports) {
  23961. KityMinder._templates[name] = supports;
  23962. },
  23963. getTemplateList: function() {
  23964. return KityMinder._templates;
  23965. }
  23966. });
  23967. kity.extendClass(Minder, (function() {
  23968. var originGetTheme = Minder.prototype.getTheme;
  23969. return {
  23970. useTemplate: function(name, duration) {
  23971. this.setTemplate(name);
  23972. this.refresh(duration || 800);
  23973. },
  23974. getTemplate: function() {
  23975. return this._template || 'default';
  23976. },
  23977. setTemplate: function(name) {
  23978. this._template = name || null;
  23979. },
  23980. getTemplateSupport: function(method) {
  23981. var supports = KityMinder._templates[this.getTemplate()];
  23982. return supports && supports[method];
  23983. },
  23984. getTheme: function(node) {
  23985. var support = this.getTemplateSupport('getTheme') || originGetTheme;
  23986. return support.call(this, node);
  23987. }
  23988. };
  23989. })());
  23990. kity.extendClass(MinderNode, (function() {
  23991. var originGetLayout = MinderNode.prototype.getLayout;
  23992. var originGetConnect = MinderNode.prototype.getConnect;
  23993. return {
  23994. getLayout: function() {
  23995. var support = this.getMinder().getTemplateSupport('getLayout') || originGetLayout;
  23996. return support.call(this, this);
  23997. },
  23998. getConnect: function() {
  23999. var support = this.getMinder().getTemplateSupport('getConnect') || originGetConnect;
  24000. return support.call(this, this);
  24001. }
  24002. };
  24003. })());
  24004. KityMinder.registerModule('TemplateModule', {
  24005. commands: {
  24006. 'template': kity.createClass('TemplateCommand', {
  24007. base: Command,
  24008. execute: function(minder, name) {
  24009. minder.useTemplate(name);
  24010. minder.execCommand('camera');
  24011. },
  24012. queryValue: function(minder) {
  24013. return minder.getTemplate() || 'default';
  24014. }
  24015. })
  24016. }
  24017. });
  24018. //添加多语言模块
  24019. kity.extendClass( Minder, {
  24020. getLang: function ( path ) {
  24021. var lang = KM.LANG[ this.getOptions( 'lang' ) ];
  24022. if ( !lang ) {
  24023. throw Error( "not import language file" );
  24024. }
  24025. path = ( path || "" ).split( "." );
  24026. for ( var i = 0, ci; ci = path[ i++ ]; ) {
  24027. lang = lang[ ci ];
  24028. if ( !lang ) break;
  24029. }
  24030. if (typeof(lang) == 'string') {
  24031. var args = arguments;
  24032. return lang.replace(/\{(\d+)\}/ig, function(match, gindex) {
  24033. return args[+gindex + 1] != undefined && args[+gindex + 1].toString() || match;
  24034. });
  24035. }
  24036. return lang;
  24037. }
  24038. } );
  24039. //这里只放不是由模块产生的默认参数
  24040. KM.defaultOptions = {
  24041. zIndex : 1000,
  24042. lang:'zh-cn',
  24043. readyOnly:false
  24044. };
  24045. kity.extendClass( Minder, function(){
  24046. var ROOTKEY = 'kityminder_preference';
  24047. //创建存储机制
  24048. var LocalStorage = ( function () {
  24049. var storage = window.localStorage,
  24050. LOCAL_FILE = "localStorage";
  24051. return {
  24052. saveLocalData: function ( key, data ) {
  24053. if ( storage && data) {
  24054. storage.setItem( key, data );
  24055. return true;
  24056. }
  24057. return false;
  24058. },
  24059. getLocalData: function ( key ) {
  24060. if ( storage ) {
  24061. return storage.getItem( key );
  24062. }
  24063. return null;
  24064. },
  24065. removeItem: function ( key ) {
  24066. if (storage) storage.removeItem( key );
  24067. }
  24068. };
  24069. } )();
  24070. return {
  24071. setPreferences: function(key,value){
  24072. var obj = {};
  24073. if ( Utils.isString( key ) ) {
  24074. obj[ key ] = value;
  24075. } else {
  24076. obj = key;
  24077. }
  24078. var data = LocalStorage.getLocalData(ROOTKEY);
  24079. if(data){
  24080. data = JSON.parse(data);
  24081. utils.extend(data, obj);
  24082. }else{
  24083. data = obj;
  24084. }
  24085. LocalStorage.saveLocalData(ROOTKEY,JSON.stringify(data));
  24086. },
  24087. getPreferences: function(key){
  24088. var data = LocalStorage.getLocalData(ROOTKEY);
  24089. if(data){
  24090. data = JSON.parse(data);
  24091. return key ? data[key] : data;
  24092. }
  24093. return {};
  24094. },
  24095. resetPreferences: function(pres){
  24096. var str = pres ? JSON.stringify(pres) : '';
  24097. LocalStorage.saveLocalData(str);
  24098. }
  24099. };
  24100. }() );
  24101. var keymap = KityMinder.keymap = (function(origin) {
  24102. var ret = {};
  24103. for (var key in origin) {
  24104. if (origin.hasOwnProperty(key)) {
  24105. ret[key] = origin[key];
  24106. ret[key.toLowerCase()] = origin[key];
  24107. }
  24108. }
  24109. var aKeyCode = 65;
  24110. var aCharCode = 'a'.charCodeAt(0);
  24111. // letters
  24112. 'abcdefghijklmnopqrstuvwxyz'.split('').forEach(function(letter) {
  24113. ret[letter] = aKeyCode + (letter.charCodeAt(0) - aCharCode);
  24114. });
  24115. // numbers
  24116. var n = 9;
  24117. do {
  24118. ret[n.toString()] = n + 48;
  24119. } while(--n);
  24120. return ret;
  24121. })({
  24122. 'Backspace': 8,
  24123. 'Tab': 9,
  24124. 'Enter': 13,
  24125. 'Shift': 16,
  24126. 'Control': 17,
  24127. 'Alt': 18,
  24128. 'CapsLock': 20,
  24129. 'Esc': 27,
  24130. 'Spacebar': 32,
  24131. 'PageUp': 33,
  24132. 'PageDown': 34,
  24133. 'End': 35,
  24134. 'Home': 36,
  24135. 'Insert': 45,
  24136. 'Left': 37,
  24137. 'Up': 38,
  24138. 'Right': 39,
  24139. 'Down': 40,
  24140. 'direction': {
  24141. 37: 1,
  24142. 38: 1,
  24143. 39: 1,
  24144. 40: 1
  24145. },
  24146. 'Del': 46,
  24147. 'NumLock': 144,
  24148. 'Cmd': 91,
  24149. 'CmdFF': 224,
  24150. 'F1': 112,
  24151. 'F2': 113,
  24152. 'F3': 114,
  24153. 'F4': 115,
  24154. 'F5': 116,
  24155. 'F6': 117,
  24156. 'F7': 118,
  24157. 'F8': 119,
  24158. 'F9': 120,
  24159. 'F10': 121,
  24160. 'F11': 122,
  24161. 'F12': 123,
  24162. '`': 192,
  24163. '=': 187,
  24164. '-': 189,
  24165. '/': 191,
  24166. '.': 190,
  24167. controlKeys: {
  24168. 16: 1,
  24169. 17: 1,
  24170. 18: 1,
  24171. 20: 1,
  24172. 91: 1,
  24173. 224: 1
  24174. },
  24175. 'notContentChange': {
  24176. 13: 1,
  24177. 9: 1,
  24178. 33: 1,
  24179. 34: 1,
  24180. 35: 1,
  24181. 36: 1,
  24182. 16: 1,
  24183. 17: 1,
  24184. 18: 1,
  24185. 20: 1,
  24186. 91: 1,
  24187. //上下左右
  24188. 37: 1,
  24189. 38: 1,
  24190. 39: 1,
  24191. 40: 1,
  24192. 113: 1,
  24193. 114: 1,
  24194. 115: 1,
  24195. 144: 1,
  24196. 27: 1
  24197. },
  24198. 'isSelectedNodeKey': {
  24199. //上下左右
  24200. 37: 1,
  24201. 38: 1,
  24202. 39: 1,
  24203. 40: 1,
  24204. 13: 1,
  24205. 9: 1
  24206. }
  24207. });
  24208. /* global Layout:true */
  24209. KityMinder.registerLayout('mind', kity.createClass({
  24210. base: Layout,
  24211. doLayout: function(node, children) {
  24212. var layout = this;
  24213. var half = Math.ceil(node.children.length / 2);
  24214. var right = [];
  24215. var left = [];
  24216. children.forEach(function(child) {
  24217. if (child.getIndex() < half) right.push(child);
  24218. else left.push(child);
  24219. });
  24220. var leftLayout = KityMinder.getLayoutInstance('left');
  24221. var rightLayout = KityMinder.getLayoutInstance('right');
  24222. leftLayout.doLayout(node, left);
  24223. rightLayout.doLayout(node, right);
  24224. var box = node.getContentBox();
  24225. node.setVertexOut(new kity.Point(box.cx, box.cy));
  24226. node.setLayoutVectorOut(new kity.Vector(0, 0));
  24227. },
  24228. getOrderHint: function(node) {
  24229. var hint = [];
  24230. var box = node.getLayoutBox();
  24231. var offset = 5;
  24232. hint.push({
  24233. type: 'up',
  24234. node: node,
  24235. area: {
  24236. x: box.x,
  24237. y: box.top - node.getStyle('margin-top') - offset,
  24238. width: box.width,
  24239. height: node.getStyle('margin-top')
  24240. },
  24241. path: ['M', box.x, box.top - offset, 'L', box.right, box.top - offset]
  24242. });
  24243. hint.push({
  24244. type: 'down',
  24245. node: node,
  24246. area: {
  24247. x: box.x,
  24248. y: box.bottom + offset,
  24249. width: box.width,
  24250. height: node.getStyle('margin-bottom')
  24251. },
  24252. path: ['M', box.x, box.bottom + offset, 'L', box.right, box.bottom + offset]
  24253. });
  24254. return hint;
  24255. }
  24256. }));
  24257. /* global Layout:true */
  24258. [-1, 1].forEach(function (dir) {
  24259. var name = 'filetree-' + (dir > 0 ? 'down' : 'up');
  24260. KityMinder.registerLayout(name, kity.createClass({
  24261. base: Layout,
  24262. doLayout: function(parent, children, round) {
  24263. var pBox = parent.getContentBox();
  24264. var indent = 20;
  24265. parent.setVertexOut(new kity.Point(pBox.left + indent, dir > 0 ? pBox.bottom : pBox.top));
  24266. parent.setLayoutVectorOut(new kity.Vector(0, dir));
  24267. if (!children.length) return;
  24268. children.forEach(function(child) {
  24269. var cbox = child.getContentBox();
  24270. child.setLayoutTransform(new kity.Matrix());
  24271. child.setVertexIn(new kity.Point(cbox.left, cbox.cy));
  24272. child.setLayoutVectorIn(new kity.Vector(1, 0));
  24273. });
  24274. this.align(children, 'left');
  24275. this.stack(children, 'y');
  24276. var xAdjust = 0;
  24277. xAdjust += pBox.left;
  24278. xAdjust += indent;
  24279. xAdjust += children[0].getStyle('margin-left');
  24280. var yAdjust = 0;
  24281. if (dir > 0) {
  24282. yAdjust += pBox.bottom;
  24283. yAdjust += parent.getStyle('margin-bottom');
  24284. yAdjust += children[0].getStyle('margin-top');
  24285. } else {
  24286. yAdjust -= this.getTreeBox(children).bottom;
  24287. yAdjust += pBox.top;
  24288. yAdjust -= parent.getStyle('margin-top');
  24289. yAdjust -= children[0].getStyle('margin-bottom');
  24290. }
  24291. this.move(children, xAdjust, yAdjust);
  24292. },
  24293. getOrderHint: function(node) {
  24294. var hint = [];
  24295. var box = node.getLayoutBox();
  24296. var offset = node.getLevel() > 1 ? 3 : 5;
  24297. hint.push({
  24298. type: 'up',
  24299. node: node,
  24300. area: {
  24301. x: box.x,
  24302. y: box.top - node.getStyle('margin-top') - offset,
  24303. width: box.width,
  24304. height: node.getStyle('margin-top')
  24305. },
  24306. path: ['M', box.x, box.top - offset, 'L', box.right, box.top - offset]
  24307. });
  24308. hint.push({
  24309. type: 'down',
  24310. node: node,
  24311. area: {
  24312. x: box.x,
  24313. y: box.bottom + offset,
  24314. width: box.width,
  24315. height: node.getStyle('margin-bottom')
  24316. },
  24317. path: ['M', box.x, box.bottom + offset, 'L', box.right, box.bottom + offset]
  24318. });
  24319. return hint;
  24320. }
  24321. }));
  24322. });
  24323. /* global Layout:true */
  24324. var layouts = ['left', 'right', 'top', 'bottom'];
  24325. layouts.forEach(function(name) {
  24326. var axis = (name == 'left' || name == 'right') ? 'x' : 'y';
  24327. var dir = (name == 'left' || name == 'top') ? -1 : 1;
  24328. var oppsite = {
  24329. 'left': 'right',
  24330. 'right': 'left',
  24331. 'top': 'bottom',
  24332. 'bottom': 'top',
  24333. 'x': 'y',
  24334. 'y': 'x'
  24335. };
  24336. function getOrderHint(node) {
  24337. var hint = [];
  24338. var box = node.getLayoutBox();
  24339. var offset = 5;
  24340. if (axis == 'x') {
  24341. hint.push({
  24342. type: 'up',
  24343. node: node,
  24344. area: {
  24345. x: box.x,
  24346. y: box.top - node.getStyle('margin-top') - offset,
  24347. width: box.width,
  24348. height: node.getStyle('margin-top')
  24349. },
  24350. path: ['M', box.x, box.top - offset, 'L', box.right, box.top - offset]
  24351. });
  24352. hint.push({
  24353. type: 'down',
  24354. node: node,
  24355. area: {
  24356. x: box.x,
  24357. y: box.bottom + offset,
  24358. width: box.width,
  24359. height: node.getStyle('margin-bottom')
  24360. },
  24361. path: ['M', box.x, box.bottom + offset, 'L', box.right, box.bottom + offset]
  24362. });
  24363. } else {
  24364. hint.push({
  24365. type: 'up',
  24366. node: node,
  24367. area: {
  24368. x: box.left - node.getStyle('margin-left') - offset,
  24369. y: box.top,
  24370. width: node.getStyle('margin-left'),
  24371. height: box.height
  24372. },
  24373. path: ['M', box.left - offset, box.top, 'L', box.left - offset, box.bottom]
  24374. });
  24375. hint.push({
  24376. type: 'down',
  24377. node: node,
  24378. area: {
  24379. x: box.right + offset,
  24380. y: box.top,
  24381. width: node.getStyle('margin-right'),
  24382. height: box.height
  24383. },
  24384. path: ['M', box.right + offset, box.top, 'L', box.right + offset, box.bottom]
  24385. });
  24386. }
  24387. return hint;
  24388. }
  24389. KityMinder.registerLayout(name, kity.createClass({
  24390. base: Layout,
  24391. doLayout: function(parent, children) {
  24392. var pbox = parent.getContentBox();
  24393. if (axis == 'x') {
  24394. parent.setVertexOut(new kity.Point(pbox[name], pbox.cy));
  24395. parent.setLayoutVectorOut(new kity.Vector(dir, 0));
  24396. } else {
  24397. parent.setVertexOut(new kity.Point(pbox.cx, pbox[name]));
  24398. parent.setLayoutVectorOut(new kity.Vector(0, dir));
  24399. }
  24400. if (!children.length) {
  24401. return false;
  24402. }
  24403. children.forEach(function(child) {
  24404. var cbox = child.getContentBox();
  24405. child.setLayoutTransform(new kity.Matrix());
  24406. if (axis == 'x') {
  24407. child.setVertexIn(new kity.Point(cbox[oppsite[name]], cbox.cy));
  24408. child.setLayoutVectorIn(new kity.Vector(dir, 0));
  24409. } else {
  24410. child.setVertexIn(new kity.Point(cbox.cx, cbox[oppsite[name]]));
  24411. child.setLayoutVectorIn(new kity.Vector(0, dir));
  24412. }
  24413. });
  24414. this.align(children, oppsite[name]);
  24415. this.stack(children, oppsite[axis]);
  24416. var bbox = this.getBranchBox(children);
  24417. var xAdjust, yAdjust;
  24418. if (axis == 'x') {
  24419. xAdjust = pbox[name];
  24420. xAdjust += dir * parent.getStyle('margin-' + name);
  24421. xAdjust += dir * children[0].getStyle('margin-' + oppsite[name]);
  24422. yAdjust = pbox.bottom;
  24423. yAdjust -= pbox.height / 2;
  24424. yAdjust -= bbox.height / 2;
  24425. yAdjust -= bbox.y;
  24426. } else {
  24427. xAdjust = pbox.right;
  24428. xAdjust -= pbox.width / 2;
  24429. xAdjust -= bbox.width / 2;
  24430. xAdjust -= bbox.x;
  24431. yAdjust = pbox[name];
  24432. yAdjust += dir * parent.getStyle('margin-' + name);
  24433. yAdjust += dir * children[0].getStyle('margin-' + oppsite[name]);
  24434. }
  24435. this.move(children, xAdjust, yAdjust);
  24436. },
  24437. getOrderHint: getOrderHint
  24438. }));
  24439. });
  24440. /**
  24441. * @fileOverview
  24442. *
  24443. * 鱼骨图主骨架布局
  24444. *
  24445. * @author: techird
  24446. * @copyright: Baidu FEX, 2014
  24447. */
  24448. /* global Layout:true */
  24449. KityMinder.registerLayout('fish-bone-master', kity.createClass('FishBoneMasterLayout', {
  24450. base: Layout,
  24451. doLayout: function(parent, children, round) {
  24452. var upPart = [],
  24453. downPart = [];
  24454. var child = children[0];
  24455. var pBox = parent.getContentBox();
  24456. parent.setVertexOut(new kity.Point(pBox.right, pBox.cy));
  24457. parent.setLayoutVectorOut(new kity.Vector(1, 0));
  24458. if (!child) return;
  24459. var cBox = child.getContentBox();
  24460. var pMarginRight = parent.getStyle('margin-right');
  24461. var cMarginLeft = child.getStyle('margin-left');
  24462. var cMarginTop = child.getStyle('margin-top');
  24463. var cMarginBottom = child.getStyle('margin-bottom');
  24464. children.forEach(function(child, index) {
  24465. child.setLayoutTransform(new kity.Matrix());
  24466. var cBox = child.getContentBox();
  24467. if (index % 2) {
  24468. downPart.push(child);
  24469. child.setVertexIn(new kity.Point(cBox.left, cBox.top));
  24470. child.setLayoutVectorIn(new kity.Vector(1, 1));
  24471. }
  24472. else {
  24473. upPart.push(child);
  24474. child.setVertexIn(new kity.Point(cBox.left, cBox.bottom));
  24475. child.setLayoutVectorIn(new kity.Vector(1, -1));
  24476. }
  24477. });
  24478. this.stack(upPart, 'x');
  24479. this.stack(downPart, 'x');
  24480. this.align(upPart, 'bottom');
  24481. this.align(downPart, 'top');
  24482. var xAdjust = pBox.right + pMarginRight + cMarginLeft;
  24483. var yAdjustUp = pBox.cy - cMarginBottom - parent.getStyle('margin-top');
  24484. var yAdjustDown = pBox.cy + cMarginTop + parent.getStyle('margin-bottom');
  24485. this.move(upPart, xAdjust, yAdjustUp);
  24486. this.move(downPart, xAdjust + cMarginLeft, yAdjustDown);
  24487. // children.forEach(function(child, index) {
  24488. // var matrix = child.getLayoutTransform();
  24489. // var dx, dy;
  24490. // dx = matrix.getMatrix().e;
  24491. // dy = matrix.getMatrix().f;
  24492. // matrix.translate(-dx, -dy);
  24493. // matrix.rotate(index % 2 ? 45 : -45);
  24494. // matrix.translate(dx, dy);
  24495. // });
  24496. }
  24497. }));
  24498. /**
  24499. * @fileOverview
  24500. *
  24501. *
  24502. *
  24503. * @author: techird
  24504. * @copyright: Baidu FEX, 2014
  24505. */
  24506. /* global Layout: true */
  24507. KityMinder.registerLayout('fish-bone-slave', kity.createClass('FishBoneSlaveLayout', {
  24508. base: Layout,
  24509. doLayout: function (parent, children, round) {
  24510. var layout = this;
  24511. var abs = Math.abs;
  24512. var GOLD_CUT = 1 - 0.618;
  24513. var pBox = parent.getContentBox();
  24514. var vi = parent.getLayoutVectorIn();
  24515. parent.setLayoutVectorOut(vi);
  24516. var goldX = pBox.left + pBox.width * GOLD_CUT;
  24517. var pout = new kity.Point(goldX, vi.y > 0 ? pBox.bottom : pBox.top);
  24518. parent.setVertexOut(pout);
  24519. var child = children[0];
  24520. if (!child) return;
  24521. var cBox = child.getContentBox();
  24522. children.forEach(function(child, index) {
  24523. child.setLayoutTransform(new kity.Matrix());
  24524. child.setLayoutVectorIn(new kity.Vector(1, 0));
  24525. child.setVertexIn(new kity.Point(cBox.left, cBox.cy));
  24526. });
  24527. this.stack(children, 'y');
  24528. this.align(children, 'left');
  24529. var xAdjust = 0, yAdjust = 0;
  24530. xAdjust += pout.x;
  24531. if (parent.getLayoutVectorOut().y < 0) {
  24532. yAdjust -= this.getTreeBox(children).bottom;
  24533. yAdjust += parent.getContentBox().top;
  24534. yAdjust -= parent.getStyle('margin-top');
  24535. yAdjust -= child.getStyle('margin-bottom');
  24536. } else {
  24537. yAdjust += parent.getContentBox().bottom;
  24538. yAdjust += parent.getStyle('margin-bottom');
  24539. yAdjust += child.getStyle('margin-top');
  24540. }
  24541. this.move(children, xAdjust, yAdjust);
  24542. if (round == 2) {
  24543. children.forEach(function(child) {
  24544. var m = child.getLayoutTransform();
  24545. var cbox = child.getContentBox();
  24546. var pin = m.transformPoint(new kity.Point(cbox.left, 0));
  24547. layout.move([child], abs(pin.y - pout.y), 0);
  24548. });
  24549. }
  24550. }
  24551. }));
  24552. /**
  24553. * @fileOverview
  24554. *
  24555. * 天盘模板
  24556. *
  24557. * @author: along
  24558. * @copyright: bpd729@163.com, 2015
  24559. */
  24560. KityMinder.registerLayout('tianpan', kity.createClass({
  24561. base: Layout,
  24562. doLayout: function (parent, children) {
  24563. if (children.length == 0) return;
  24564. var layout = this;
  24565. var pbox = parent.getContentBox();
  24566. var x, y,box;
  24567. var _theta = 5;
  24568. var _r = Math.max(pbox.width, 50);
  24569. children.forEach(function (child, index) {
  24570. child.setLayoutTransform(new kity.Matrix());
  24571. box = layout.getTreeBox(child);
  24572. _r = Math.max(Math.max(box.width, box.height), _r);
  24573. })
  24574. _r = _r / 1.5 / Math.PI;
  24575. children.forEach(function (child, index) {
  24576. x = _r * (Math.cos(_theta) + Math.sin(_theta) * _theta);
  24577. y = _r * (Math.sin(_theta) - Math.cos(_theta) * _theta);
  24578. _theta += (0.9 - index * 0.02);
  24579. child.setLayoutVectorIn(new kity.Vector(1, 0));
  24580. child.setVertexIn(new kity.Point(pbox.cx, pbox.cy));
  24581. child.setLayoutTransform(new kity.Matrix());
  24582. layout.move([child], x, y);
  24583. });
  24584. },
  24585. getOrderHint: function (node) {
  24586. var hint = [];
  24587. var box = node.getLayoutBox();
  24588. var offset = 5;
  24589. hint.push({
  24590. type: 'up',
  24591. node: node,
  24592. area: {
  24593. x: box.x,
  24594. y: box.top - node.getStyle('margin-top') - offset,
  24595. width: box.width,
  24596. height: node.getStyle('margin-top')
  24597. },
  24598. path: ['M', box.x, box.top - offset, 'L', box.right, box.top - offset]
  24599. });
  24600. hint.push({
  24601. type: 'down',
  24602. node: node,
  24603. area: {
  24604. x: box.x,
  24605. y: box.bottom + offset,
  24606. width: box.width,
  24607. height: node.getStyle('margin-bottom')
  24608. },
  24609. path: ['M', box.x, box.bottom + offset, 'L', box.right, box.bottom + offset]
  24610. });
  24611. return hint;
  24612. }
  24613. }));
  24614. /**
  24615. * @fileOverview
  24616. *
  24617. * 提供折线相连的方法
  24618. *
  24619. * @author: techird
  24620. * @copyright: Baidu FEX, 2014
  24621. */
  24622. KityMinder.registerConnectProvider('bezier', function(node, parent, connection) {
  24623. // 连线起点和终点
  24624. var po = parent.getLayoutVertexOut(),
  24625. pi = node.getLayoutVertexIn();
  24626. // 连线矢量和方向
  24627. var v = parent.getLayoutVectorOut().normalize();
  24628. var r = Math.round;
  24629. var abs = Math.abs;
  24630. var pathData = [];
  24631. pathData.push('M', r(po.x), r(po.y));
  24632. if (abs(v.x) > abs(v.y)) {
  24633. // x - direction
  24634. var hx = (pi.x + po.x) / 2;
  24635. pathData.push('C', hx, po.y, hx, pi.y, pi.x, pi.y);
  24636. } else {
  24637. // y - direction
  24638. var hy = (pi.y + po.y) / 2;
  24639. pathData.push('C', po.x, hy, pi.x, hy, pi.x, pi.y);
  24640. }
  24641. connection.setMarker(null);
  24642. connection.setPathData(pathData);
  24643. });
  24644. /**
  24645. * @fileOverview
  24646. *
  24647. * 提供折线相连的方法
  24648. *
  24649. * @author: techird
  24650. * @copyright: Baidu FEX, 2014
  24651. */
  24652. KityMinder.registerConnectProvider('poly', function(node, parent, connection, width) {
  24653. // 连线起点和终点
  24654. var po = parent.getLayoutVertexOut(),
  24655. pi = node.getLayoutVertexIn();
  24656. // 连线矢量和方向
  24657. var v = parent.getLayoutVectorOut().normalize();
  24658. var r = Math.round;
  24659. var abs = Math.abs;
  24660. var pathData = [];
  24661. pathData.push('M', r(po.x), r(po.y));
  24662. switch (true) {
  24663. case abs(v.x) > abs(v.y) && v.x < 0:
  24664. // left
  24665. pathData.push('h', -parent.getStyle('margin-left'));
  24666. pathData.push('v', pi.y - po.y);
  24667. pathData.push('H', pi.x);
  24668. break;
  24669. case abs(v.x) > abs(v.y) && v.x >= 0:
  24670. // right
  24671. pathData.push('h', parent.getStyle('margin-right'));
  24672. pathData.push('v', pi.y - po.y);
  24673. pathData.push('H', pi.x);
  24674. break;
  24675. case abs(v.x) <= abs(v.y) && v.y < 0:
  24676. // top
  24677. pathData.push('v', -parent.getStyle('margin-top'));
  24678. pathData.push('h', pi.x - po.x);
  24679. pathData.push('V', pi.y);
  24680. break;
  24681. case abs(v.x) <= abs(v.y) && v.y >= 0:
  24682. // bottom
  24683. pathData.push('v', parent.getStyle('margin-bottom'));
  24684. pathData.push('h', pi.x - po.x);
  24685. pathData.push('V', pi.y);
  24686. break;
  24687. }
  24688. connection.setMarker(null);
  24689. connection.setPathData(pathData);
  24690. });
  24691. /**
  24692. * @fileOverview
  24693. *
  24694. * 圆弧连线
  24695. *
  24696. * @author: techird
  24697. * @copyright: Baidu FEX, 2014
  24698. */
  24699. var connectMarker = new kity.Marker().pipe(function() {
  24700. var r = 7;
  24701. var dot = new kity.Circle(r - 1);
  24702. this.addShape(dot);
  24703. this.setRef(r - 1, 0).setViewBox(-r, -r, r + r, r + r).setWidth(r).setHeight(r);
  24704. this.dot = dot;
  24705. this.node.setAttribute('markerUnits', 'userSpaceOnUse');
  24706. });
  24707. KityMinder.registerConnectProvider('arc', function(node, parent, connection, width, color) {
  24708. var box = node.getLayoutBox(),
  24709. pBox = parent.getLayoutBox();
  24710. var start, end, vector;
  24711. var abs = Math.abs;
  24712. var pathData = [];
  24713. var side = box.x > pBox.x ? 'right' : 'left';
  24714. node.getMinder().getPaper().addResource(connectMarker);
  24715. start = new kity.Point(pBox.cx, pBox.cy);
  24716. end = side == 'left' ?
  24717. new kity.Point(box.right + 2, box.cy) :
  24718. new kity.Point(box.left - 2, box.cy);
  24719. vector = kity.Vector.fromPoints(start, end);
  24720. pathData.push('M', start);
  24721. pathData.push('A', abs(vector.x), abs(vector.y), 0, 0, (vector.x * vector.y > 0 ? 0 : 1), end);
  24722. connection.setMarker(connectMarker);
  24723. connectMarker.dot.fill(color);
  24724. connection.setPathData(pathData);
  24725. });
  24726. /**
  24727. * @fileOverview
  24728. *
  24729. * 下划线连线
  24730. *
  24731. * @author: techird
  24732. * @copyright: Baidu FEX, 2014
  24733. */
  24734. KityMinder.registerConnectProvider('under', function(node, parent, connection, width, color) {
  24735. var box = node.getLayoutBox(),
  24736. pBox = parent.getLayoutBox();
  24737. var start, end, vector;
  24738. var abs = Math.abs;
  24739. var pathData = [];
  24740. var side = box.x > pBox.x ? 'right' : 'left';
  24741. var radius = node.getStyle('connect-radius');
  24742. var underY = box.bottom + 3;
  24743. var startY = parent.getType() == 'sub' ? pBox.bottom + 3 : pBox.cy;
  24744. var p1, p2, p3, mx;
  24745. if (side == 'right') {
  24746. p1 = new kity.Point(pBox.right, startY);
  24747. p2 = new kity.Point(box.left - 10, underY);
  24748. p3 = new kity.Point(box.right, underY);
  24749. } else {
  24750. p1 = new kity.Point(pBox.left, startY);
  24751. p2 = new kity.Point(box.right + 10, underY);
  24752. p3 = new kity.Point(box.left, underY);
  24753. }
  24754. mx = (p1.x + p2.x) / 2;
  24755. pathData.push('M', p1);
  24756. pathData.push('C', mx, p1.y, mx, p2.y, p2);
  24757. pathData.push('L', p3);
  24758. connection.setMarker(null);
  24759. connection.setPathData(pathData);
  24760. });
  24761. /**
  24762. * @fileOverview
  24763. *
  24764. * "L" 连线
  24765. *
  24766. * @author: techird
  24767. * @copyright: Baidu FEX, 2014
  24768. */
  24769. KityMinder.registerConnectProvider('l', function(node, parent, connection) {
  24770. var po = parent.getLayoutVertexOut();
  24771. var pi = node.getLayoutVertexIn();
  24772. var vo = parent.getLayoutVectorOut();
  24773. var pathData = [];
  24774. var r = Math.round,
  24775. abs = Math.abs;
  24776. pathData.push('M', po.round());
  24777. if (abs(vo.x) > abs(vo.y)) {
  24778. pathData.push('H', r(pi.x));
  24779. } else {
  24780. pathData.push('V', pi.y);
  24781. }
  24782. pathData.push('L', pi);
  24783. connection.setPathData(pathData);
  24784. });
  24785. /**
  24786. * @fileOverview
  24787. *
  24788. * 鱼骨头主干连线
  24789. *
  24790. * @author: techird
  24791. * @copyright: Baidu FEX, 2014
  24792. */
  24793. KityMinder.registerConnectProvider('fish-bone-master', function(node, parent, connection) {
  24794. var pout = parent.getLayoutVertexOut(),
  24795. pin = node.getLayoutVertexIn();
  24796. var abs = Math.abs;
  24797. var dy = abs(pout.y - pin.y),
  24798. dx = abs(pout.x - pin.x);
  24799. var pathData = [];
  24800. pathData.push('M', pout.x, pout.y);
  24801. pathData.push('h', dx - dy);
  24802. pathData.push('L', pin.x, pin.y);
  24803. connection.setMarker(null);
  24804. connection.setPathData(pathData);
  24805. });
  24806. /**
  24807. *
  24808. * 圆弧连线
  24809. *
  24810. * @author: along
  24811. * @copyright: bpd729@163.com , 2015
  24812. */
  24813. var connectMarker = new kity.Marker().pipe(function () {
  24814. var r = 7;
  24815. var dot = new kity.Circle(r - 1);
  24816. this.addShape(dot);
  24817. this.setRef(r - 1, 0).setViewBox(-r, -r, r + r, r + r).setWidth(r).setHeight(r);
  24818. this.dot = dot;
  24819. this.node.setAttribute('markerUnits', 'userSpaceOnUse');
  24820. });
  24821. KityMinder.registerConnectProvider('arc_tp', function (node, parent, connection, width, color) {
  24822. var end_box = node.getLayoutBox(),
  24823. start_box = parent.getLayoutBox();
  24824. if (node.getIndex() > 0) {
  24825. var index = node.getIndex();
  24826. start_box = parent.getChildren()[index - 1].getLayoutBox();
  24827. }
  24828. var start, end, vector;
  24829. var abs = Math.abs;
  24830. var pathData = [];
  24831. var side = end_box.x > start_box.x ? 'right' : 'left';
  24832. node.getMinder().getPaper().addResource(connectMarker);
  24833. start = new kity.Point(start_box.cx, start_box.cy);
  24834. end = new kity.Point(end_box.cx, end_box.cy);
  24835. var jl = Math.sqrt(Math.abs(start.x - end.x) * Math.abs(start.x - end.x) + Math.abs(start.y - end.y) * Math.abs(start.y - end.y)); //两圆中心点距离
  24836. jl = node.getIndex() == 0 ? jl * 0.4 : jl;
  24837. vector = kity.Vector.fromPoints(start, end);
  24838. pathData.push('M', start);
  24839. pathData.push('A', jl, jl, 0, 0, 1, end);
  24840. connection.setMarker(connectMarker);
  24841. connectMarker.dot.fill(color);
  24842. connection.setPathData(pathData);
  24843. });
  24844. ['classic', 'classic-compact'].forEach(function(name) {
  24845. var compact = name == 'classic-compact';
  24846. KityMinder.registerTheme(name, {
  24847. 'background': '#3A4144 url(ui/theme/default/images/grid.png) repeat',
  24848. 'root-color': '#430',
  24849. 'root-background': '#e9df98',
  24850. 'root-stroke': '#e9df98',
  24851. 'root-font-size': 24,
  24852. 'root-padding': compact ? [10, 25] : [15, 25],
  24853. 'root-margin': compact ? [15, 25] : [30, 100],
  24854. 'root-radius': 30,
  24855. 'root-space': 10,
  24856. 'root-shadow': 'rgba(0, 0, 0, .25)',
  24857. 'main-color': '#333',
  24858. 'main-background': '#a4c5c0',
  24859. 'main-stroke': '#a4c5c0',
  24860. 'main-font-size': 16,
  24861. 'main-padding': compact ? [5, 15] : [6, 20],
  24862. 'main-margin': compact ? [5, 10] : 20,
  24863. 'main-radius': 10,
  24864. 'main-space': 5,
  24865. 'main-shadow': 'rgba(0, 0, 0, .25)',
  24866. 'sub-color': 'white',
  24867. 'sub-background': 'transparent',
  24868. 'sub-stroke': 'none',
  24869. 'sub-font-size': 12,
  24870. 'sub-padding': [5, 10],
  24871. 'sub-margin': compact ? [5, 10] : [15, 20],
  24872. 'sub-tree-margin': 30,
  24873. 'sub-radius': 5,
  24874. 'sub-space': 5,
  24875. 'connect-color': 'white',
  24876. 'connect-width': 2,
  24877. 'main-connect-width': 3,
  24878. 'connect-radius': 5,
  24879. 'selected-background': 'rgb(254, 219, 0)',
  24880. 'selected-stroke': 'rgb(254, 219, 0)',
  24881. 'selected-color': 'black',
  24882. 'marquee-background': 'rgba(255,255,255,.3)',
  24883. 'marquee-stroke': 'white',
  24884. 'drop-hint-color': 'yellow',
  24885. 'sub-drop-hint-width': 2,
  24886. 'main-drop-hint-width': 4,
  24887. 'root-drop-hint-width': 4,
  24888. 'order-hint-area-color': 'rgba(0, 255, 0, .5)',
  24889. 'order-hint-path-color': '#0f0',
  24890. 'order-hint-path-width': 1,
  24891. 'text-selection-color': 'rgb(27,171,255)',
  24892. 'line-height':1.5
  24893. });
  24894. });
  24895. ['snow', 'snow-compact'].forEach(function(name) {
  24896. var compact = name == 'snow-compact';
  24897. KityMinder.registerTheme(name, {
  24898. 'background': '#3A4144 url(ui/theme/default/images/grid.png) repeat',
  24899. 'root-color': '#430',
  24900. 'root-background': '#e9df98',
  24901. 'root-stroke': '#e9df98',
  24902. 'root-font-size': 24,
  24903. 'root-padding': compact ? [5, 10] : [15, 25],
  24904. 'root-margin': compact ? 15 : 30,
  24905. 'root-radius': 5,
  24906. 'root-space': 10,
  24907. 'root-shadow': 'rgba(0, 0, 0, .25)',
  24908. 'main-color': '#333',
  24909. 'main-background': '#a4c5c0',
  24910. 'main-stroke': '#a4c5c0',
  24911. 'main-font-size': 16,
  24912. 'main-padding': compact ? [4, 10] : [6, 20],
  24913. 'main-margin': compact ? [5, 10] : [20, 40],
  24914. 'main-radius': 5,
  24915. 'main-space': 5,
  24916. 'main-shadow': 'rgba(0, 0, 0, .25)',
  24917. 'sub-color': 'black',
  24918. 'sub-background': 'white',
  24919. 'sub-stroke': 'white',
  24920. 'sub-font-size': 12,
  24921. 'sub-padding': [5, 10],
  24922. 'sub-margin': compact ? [5, 10] : [10, 20],
  24923. 'sub-radius': 5,
  24924. 'sub-space': 5,
  24925. 'connect-color': 'white',
  24926. 'connect-width': 2,
  24927. 'main-connect-width': 3,
  24928. 'connect-radius': 5,
  24929. 'selected-background': 'rgb(254, 219, 0)',
  24930. 'selected-stroke': 'rgb(254, 219, 0)',
  24931. 'marquee-background': 'rgba(255,255,255,.3)',
  24932. 'marquee-stroke': 'white',
  24933. 'drop-hint-color': 'yellow',
  24934. 'drop-hint-width': 4,
  24935. 'order-hint-area-color': 'rgba(0, 255, 0, .5)',
  24936. 'order-hint-path-color': '#0f0',
  24937. 'order-hint-path-width': 1,
  24938. 'text-selection-color': 'rgb(27,171,255)',
  24939. 'line-height':1.5
  24940. });
  24941. });
  24942. (function() {
  24943. function hsl(h, s, l) {
  24944. return kity.Color.createHSL(h, s, l);
  24945. }
  24946. function generate(h, compat) {
  24947. return {
  24948. 'background': '#fbfbfb',
  24949. 'root-color': 'white',
  24950. 'root-background': hsl(h, 37, 60),
  24951. 'root-stroke': hsl(h, 37, 60),
  24952. 'root-font-size': 16,
  24953. 'root-padding': compat ? [6, 12] : [12, 24],
  24954. 'root-margin': compat ? 10 : [30, 100],
  24955. 'root-radius': 5,
  24956. 'root-space': 10,
  24957. 'main-color': 'black',
  24958. 'main-background': hsl(h, 33, 95),
  24959. 'main-stroke': hsl(h, 37, 60),
  24960. 'main-stroke-width': 1,
  24961. 'main-font-size': 14,
  24962. 'main-padding': [6, 20],
  24963. 'main-margin': compat ? 8 : 20,
  24964. 'main-radius': 3,
  24965. 'main-space': 5,
  24966. 'sub-color': 'black',
  24967. 'sub-background': 'transparent',
  24968. 'sub-stroke': 'none',
  24969. 'sub-font-size': 12,
  24970. 'sub-padding': compat ? [3, 5] : [5, 10],
  24971. 'sub-margin': compat ? [4, 8] : [15, 20],
  24972. 'sub-radius': 5,
  24973. 'sub-space': 5,
  24974. 'connect-color': hsl(h, 37, 60),
  24975. 'connect-width': 1,
  24976. 'connect-radius': 5,
  24977. 'selected-stroke': hsl(h, 26, 30),
  24978. 'selected-stroke-width': '3',
  24979. 'marquee-background': hsl(h, 100, 80).set('a', 0.1),
  24980. 'marquee-stroke': hsl(h, 37, 60),
  24981. 'drop-hint-color': hsl(h, 26, 35),
  24982. 'drop-hint-width': 5,
  24983. 'order-hint-area-color': hsl(h, 100, 30).set('a', 0.5),
  24984. 'order-hint-path-color': hsl(h, 100, 25),
  24985. 'order-hint-path-width': 1,
  24986. 'text-selection-color': hsl(h, 100, 20),
  24987. 'line-height':1.5
  24988. };
  24989. }
  24990. var plans = {
  24991. red: 0,
  24992. soil: 25,
  24993. green: 122,
  24994. blue: 204,
  24995. purple: 246,
  24996. pink: 334
  24997. };
  24998. var name;
  24999. for (name in plans) {
  25000. KityMinder.registerTheme('fresh-' + name, generate(plans[name]));
  25001. KityMinder.registerTheme('fresh-' + name + '-compat', generate(plans[name], true));
  25002. }
  25003. })();
  25004. KityMinder.registerTheme('fish', {
  25005. 'background': '#3A4144 url(ui/theme/default/images/grid.png) repeat',
  25006. 'root-color': '#430',
  25007. 'root-background': '#e9df98',
  25008. 'root-stroke': '#e9df98',
  25009. 'root-font-size': 24,
  25010. 'root-padding': [35, 35],
  25011. 'root-margin': 30,
  25012. 'root-radius': 100,
  25013. 'root-space': 10,
  25014. 'root-shadow': 'rgba(0, 0, 0, .25)',
  25015. 'main-color': '#333',
  25016. 'main-background': '#a4c5c0',
  25017. 'main-stroke': '#a4c5c0',
  25018. 'main-font-size': 16,
  25019. 'main-padding': [6, 20],
  25020. 'main-margin': [20, 20],
  25021. 'main-radius': 5,
  25022. 'main-space': 5,
  25023. 'main-shadow': 'rgba(0, 0, 0, .25)',
  25024. 'sub-color': 'black',
  25025. 'sub-background': 'white',
  25026. 'sub-stroke': 'white',
  25027. 'sub-font-size': 12,
  25028. 'sub-padding': [5, 10],
  25029. 'sub-margin': [10],
  25030. 'sub-radius': 5,
  25031. 'sub-space': 5,
  25032. 'connect-color': 'white',
  25033. 'connect-width': 3,
  25034. 'main-connect-width': 3,
  25035. 'connect-radius': 5,
  25036. 'selected-background': 'rgb(254, 219, 0)',
  25037. 'selected-stroke': 'rgb(254, 219, 0)',
  25038. 'marquee-background': 'rgba(255,255,255,.3)',
  25039. 'marquee-stroke': 'white',
  25040. 'drop-hint-color': 'yellow',
  25041. 'drop-hint-width': 4,
  25042. 'order-hint-area-color': 'rgba(0, 255, 0, .5)',
  25043. 'order-hint-path-color': '#0f0',
  25044. 'order-hint-path-width': 1,
  25045. 'text-selection-color': 'rgb(27,171,255)',
  25046. 'line-height':1.5
  25047. });
  25048. KityMinder.registerTheme('wire', {
  25049. 'background': 'black',
  25050. 'color': '#999',
  25051. 'stroke': 'none',
  25052. 'padding': 10,
  25053. 'margin': 20,
  25054. 'font-size': 14,
  25055. 'connect-color': '#999',
  25056. 'connect-width': 1,
  25057. 'selected-background': '#999',
  25058. 'selected-color': 'black',
  25059. 'marquee-background': 'rgba(255,255,255,.3)',
  25060. 'marquee-stroke': 'white',
  25061. 'drop-hint-color': 'yellow',
  25062. 'sub-drop-hint-width': 2,
  25063. 'main-drop-hint-width': 4,
  25064. 'root-drop-hint-width': 4,
  25065. 'order-hint-area-color': 'rgba(0, 255, 0, .5)',
  25066. 'order-hint-path-color': '#0f0',
  25067. 'order-hint-path-width': 1,
  25068. 'text-selection-color': 'rgb(27,171,255)',
  25069. 'line-height':1.5
  25070. });
  25071. ['tianpan', 'tianpan-compact'].forEach(function (name) {
  25072. var compact = name == 'tianpan-compact';
  25073. KityMinder.registerTheme(name, {
  25074. 'background': '#3A4144 url(ui/theme/default/images/grid.png) repeat',
  25075. 'root-color': '#430',
  25076. 'root-background': '#e9df98',
  25077. 'root-stroke': '#e9df98',
  25078. 'root-font-size': 25,
  25079. 'root-padding': compact ? 15 : 20,
  25080. 'root-margin': compact ? [15, 25] : 100,
  25081. 'root-radius': 30,
  25082. 'root-space': 10,
  25083. 'root-shadow': 'rgba(0, 0, 0, .25)',
  25084. 'root-shape': 'circle',
  25085. 'main-color': '#333',
  25086. 'main-background': '#a4c5c0',
  25087. 'main-stroke': '#a4c5c0',
  25088. 'main-font-size': 15,
  25089. 'main-padding': compact ? 10 : 12,
  25090. 'main-margin': compact ? 10 : 12,
  25091. 'main-radius': 10,
  25092. 'main-space': 5,
  25093. 'main-shadow': 'rgba(0, 0, 0, .25)',
  25094. 'main-shape': 'circle',
  25095. 'sub-color': '#333',
  25096. 'sub-background': '#99ca6a',
  25097. 'sub-stroke': '#a4c5c0',
  25098. 'sub-font-size': 13,
  25099. 'sub-padding': 5,
  25100. 'sub-margin': compact ? 6 : 10,
  25101. 'sub-tree-margin': 30,
  25102. 'sub-radius': 5,
  25103. 'sub-space': 5,
  25104. 'sub-shadow': 'rgba(0, 0, 0, .25)',
  25105. 'sub-shape': 'circle',
  25106. 'connect-color': 'white',
  25107. 'connect-width': 2,
  25108. 'main-connect-width': 3,
  25109. 'connect-radius': 5,
  25110. 'selected-background': 'rgb(254, 219, 0)',
  25111. 'selected-stroke': 'rgb(254, 219, 0)',
  25112. 'selected-color': 'black',
  25113. 'marquee-background': 'rgba(255,255,255,.3)',
  25114. 'marquee-stroke': 'white',
  25115. 'drop-hint-color': 'yellow',
  25116. 'sub-drop-hint-width': 2,
  25117. 'main-drop-hint-width': 4,
  25118. 'root-drop-hint-width': 4,
  25119. 'order-hint-area-color': 'rgba(0, 255, 0, .5)',
  25120. 'order-hint-path-color': '#0f0',
  25121. 'order-hint-path-width': 1,
  25122. 'text-selection-color': 'rgb(27,171,255)',
  25123. 'line-height': 1.4
  25124. });
  25125. });
  25126. /**
  25127. * @fileOverview
  25128. *
  25129. * 默认模板 - 脑图模板
  25130. *
  25131. * @author: techird
  25132. * @copyright: Baidu FEX, 2014
  25133. */
  25134. KityMinder.registerTemplate('default', {
  25135. getLayout: function(node) {
  25136. if (node.getData('layout')) return node.getData('layout');
  25137. var level = node.getLevel();
  25138. // 根节点
  25139. if (level === 0) {
  25140. return 'mind';
  25141. }
  25142. // 一级节点
  25143. if (level === 1) {
  25144. return node.getLayoutPointPreview().x > 0 ? 'right': 'left';
  25145. }
  25146. return node.parent.getLayout();
  25147. },
  25148. getConnect: function(node) {
  25149. if (node.getLevel() == 1) return 'arc';
  25150. return 'under';
  25151. }
  25152. });
  25153. /**
  25154. * @fileOverview
  25155. *
  25156. * 组织结构图模板
  25157. *
  25158. * @author: techird
  25159. * @copyright: Baidu FEX, 2014
  25160. */
  25161. KityMinder.registerTemplate('structure', {
  25162. getLayout: function(node) {
  25163. return node.getData('layout') || 'bottom';
  25164. },
  25165. getConnect: function(node) {
  25166. return 'poly';
  25167. }
  25168. });
  25169. /**
  25170. * @fileOverview
  25171. *
  25172. * 文件夹模板
  25173. *
  25174. * @author: techird
  25175. * @copyright: Baidu FEX, 2014
  25176. */
  25177. KityMinder.registerTemplate('filetree', {
  25178. getLayout: function(node) {
  25179. if (node.getData('layout')) return node.getData('layout');
  25180. if (node.isRoot()) return 'bottom';
  25181. return 'filetree-down';
  25182. },
  25183. getConnect: function(node) {
  25184. if (node.getLevel() == 1) {
  25185. return 'poly';
  25186. }
  25187. return 'l';
  25188. }
  25189. });
  25190. /**
  25191. * @fileOverview
  25192. *
  25193. * 往右布局结构模板
  25194. *
  25195. * @author: techird
  25196. * @copyright: Baidu FEX, 2014
  25197. */
  25198. KityMinder.registerTemplate('right', {
  25199. getLayout: function(node) {
  25200. return node.getData('layout') || 'right';
  25201. },
  25202. getConnect: function(node) {
  25203. if (node.getLevel() == 1) return 'arc';
  25204. return 'bezier';
  25205. }
  25206. });
  25207. /**
  25208. * @fileOverview
  25209. *
  25210. * 默认模板 - 鱼骨头模板
  25211. *
  25212. * @author: techird
  25213. * @copyright: Baidu FEX, 2014
  25214. */
  25215. KityMinder.registerTemplate('fish-bone', {
  25216. getLayout: function(node) {
  25217. if (node.getData('layout')) return node.getData('layout');
  25218. var level = node.getLevel();
  25219. // 根节点
  25220. if (level === 0) {
  25221. return 'fish-bone-master';
  25222. }
  25223. // 一级节点
  25224. if (level === 1) {
  25225. return 'fish-bone-slave';
  25226. }
  25227. return node.getLayoutPointPreview().y > 0 ? 'filetree-up': 'filetree-down';
  25228. },
  25229. getConnect: function(node) {
  25230. switch (node.getLevel()) {
  25231. case 1: return 'fish-bone-master';
  25232. case 2: return 'line';
  25233. default: return 'l';
  25234. }
  25235. }
  25236. });
  25237. /**
  25238. * @fileOverview
  25239. *
  25240. * 天盘模板
  25241. *
  25242. * @author: along
  25243. * @copyright: bpd729@163.com, 2015
  25244. */
  25245. KityMinder.registerTemplate('tianpan', {
  25246. getLayout: function (node) {
  25247. if (node.getData('layout')) return node.getData('layout');
  25248. var level = node.getLevel();
  25249. // 根节点
  25250. if (level === 0) {
  25251. return 'tianpan';
  25252. }
  25253. return node.parent.getLayout();
  25254. },
  25255. getConnect: function (node) {
  25256. return 'arc_tp';
  25257. }
  25258. });
  25259. var AppendChildCommand = kity.createClass('AppendChildCommand', {
  25260. base: Command,
  25261. execute: function(km, text) {
  25262. var parent = km.getSelectedNode();
  25263. if (!parent) {
  25264. return null;
  25265. }
  25266. text = text || km.getLang('topic');
  25267. parent.expand();
  25268. var node = km.createNode(text, parent);
  25269. km.select(node, true);
  25270. node.render();
  25271. km.layout(600);
  25272. },
  25273. queryState: function(km) {
  25274. var selectedNode = km.getSelectedNode();
  25275. return selectedNode ? 0 : -1;
  25276. }
  25277. });
  25278. var AppendSiblingCommand = kity.createClass('AppendSiblingCommand', {
  25279. base: Command,
  25280. execute: function(km, text) {
  25281. var sibling = km.getSelectedNode();
  25282. var parent = sibling.parent;
  25283. if (!parent) {
  25284. return km.execCommand('AppendChildNode', text);
  25285. }
  25286. text = text || km.getLang('topic');
  25287. var node = km.createNode(text, parent, sibling.getIndex() + 1);
  25288. km.select(node, true);
  25289. node.render();
  25290. km.layout(600);
  25291. },
  25292. queryState: function(km) {
  25293. var selectedNode = km.getSelectedNode();
  25294. return selectedNode ? 0 : -1;
  25295. }
  25296. });
  25297. var RemoveNodeCommand = kity.createClass('RemoverNodeCommand', {
  25298. base: Command,
  25299. execute: function(km, text) {
  25300. var nodes = km.getSelectedNodes();
  25301. var ancestor = MinderNode.getCommonAncestor.apply(null, nodes);
  25302. nodes.forEach(function(node) {
  25303. if (!node.isRoot()) km.removeNode(node);
  25304. });
  25305. km.select(ancestor || km.getRoot(), true);
  25306. km.layout(600);
  25307. },
  25308. queryState: function(km) {
  25309. var selectedNode = km.getSelectedNode();
  25310. return selectedNode ? 0 : -1;
  25311. }
  25312. });
  25313. var EditNodeCommand = kity.createClass('EditNodeCommand', {
  25314. base: Command,
  25315. execute: function(km) {
  25316. var selectedNode = km.getSelectedNode();
  25317. if (!selectedNode) {
  25318. return null;
  25319. }
  25320. km.select(selectedNode, true);
  25321. km.textEditNode(selectedNode);
  25322. },
  25323. queryState: function(km) {
  25324. var selectedNode = km.getSelectedNode();
  25325. if (!selectedNode) {
  25326. return -1;
  25327. }
  25328. else {
  25329. return 0;
  25330. }
  25331. },
  25332. isNeedUndo: function() {
  25333. return false;
  25334. }
  25335. });
  25336. var $importDialog;
  25337. var $exportDialog;
  25338. var ImportTextNode = kity.createClass('ImportTextNode', {
  25339. base: Command,
  25340. execute: function(km, text) {
  25341. if (!$importDialog) {
  25342. var plainProtocol = km.getProtocol('plain');
  25343. var height = 400;
  25344. $importDialog = new FUI.Dialog({
  25345. width: 600,
  25346. height: height,
  25347. prompt: true,
  25348. caption: km.getLang('ui.importtextnode')
  25349. }).appendTo(document.getElementById('content-wrapper'));
  25350. var $dialogBody = $($importDialog.getBodyElement());
  25351. $dialogBody.html([
  25352. '<textarea style="width: 100%; height: ' + (height - 130) + 'px"></textarea>'
  25353. ].join(''));
  25354. var $editor = $dialogBody.find('textarea');
  25355. var $ok = $importDialog.getButton(0);
  25356. var $errorMsg = $('<span class="validate-error"></span>');
  25357. var rootNode;
  25358. function check(value) {
  25359. var error;
  25360. if (!value) {
  25361. error = '内容不能为空';
  25362. }
  25363. else {
  25364. try {
  25365. rootNode = plainProtocol.decode(value, true);
  25366. }
  25367. catch (ex) {
  25368. error = '文本格式解析错误. ' + ex.message;
  25369. }
  25370. }
  25371. if (error) {
  25372. $editor.addClass('validate-error');
  25373. $errorMsg.text(error);
  25374. $ok.disable();
  25375. }
  25376. else {
  25377. $editor.removeClass('validate-error');
  25378. $errorMsg.text('');
  25379. $ok.enable();
  25380. }
  25381. }
  25382. $editor.after($errorMsg);
  25383. $editor.on('input', function() {
  25384. check($editor.val());
  25385. });
  25386. $editor.on('keydown keyup', function(e) {
  25387. if (e.keyCode === 9 && e.type === 'keydown') {
  25388. e.preventDefault();
  25389. var s = this.selectionStart;
  25390. this.value = this.value.substring(0, this.selectionStart) + '\t' +
  25391. this.value.substring(this.selectionEnd);
  25392. this.selectionEnd = s + 1;
  25393. }
  25394. if (e.keyCode === 13 && !e.shiftKey) {
  25395. return;
  25396. }
  25397. e.stopPropagation();
  25398. });
  25399. $importDialog.on('open', function() {
  25400. check($editor.val());
  25401. setTimeout(function() {
  25402. $editor[0].focus();
  25403. }, 10);
  25404. });
  25405. $importDialog.on('ok', function() {
  25406. var _selectedNodes = [];
  25407. function appendChild(parent, child, index) {
  25408. if (!parent || !child) {
  25409. return;
  25410. }
  25411. var kmNode = km.createNode(child.data.text, parent);
  25412. if (child.children) {
  25413. child.children.forEach(function(item) {
  25414. appendChild(kmNode, item);
  25415. });
  25416. }
  25417. kmNode.render();
  25418. return kmNode;
  25419. }
  25420. var selectedNode = km.getSelectedNode();
  25421. if (rootNode && rootNode.children && selectedNode) {
  25422. selectedNode.expand();
  25423. rootNode.children.forEach(function(child) {
  25424. _selectedNodes.push(appendChild(selectedNode, child));
  25425. });
  25426. }
  25427. km.select(_selectedNodes, true);
  25428. km.layout(300);
  25429. $editor.val('');
  25430. _selectedNodes = null;
  25431. rootNode = null;
  25432. });
  25433. }
  25434. $importDialog.open();
  25435. },
  25436. queryState: function(km) {
  25437. var selectedNode = km.getSelectedNode();
  25438. return selectedNode ? 0 : -1;
  25439. }
  25440. });
  25441. var ExportTextNode = kity.createClass('ExportTextNode', {
  25442. base: Command,
  25443. execute: function(km, text) {
  25444. if (!$exportDialog) {
  25445. var plainProtocol = km.getProtocol('plain');
  25446. var height = 400;
  25447. $exportDialog = new FUI.Dialog({
  25448. width: 600,
  25449. height: height,
  25450. prompt: true,
  25451. caption: km.getLang('ui.exporttextnode')
  25452. }).appendTo(document.getElementById('content-wrapper'));
  25453. var $dialogBody = $($exportDialog.getBodyElement());
  25454. $dialogBody.html([
  25455. '<textarea style="width: 100%; height: ' + (height - 130) + 'px"></textarea>'
  25456. ].join(''));
  25457. var $editor = $dialogBody.find('textarea');
  25458. $editor.on('keydown keyup', function(e) {
  25459. if (e.keyCode === 9 && e.type === 'keydown') {
  25460. e.preventDefault();
  25461. var s = this.selectionStart;
  25462. this.value = this.value.substring(0, this.selectionStart) + '\t' +
  25463. this.value.substring(this.selectionEnd);
  25464. this.selectionEnd = s + 1;
  25465. }
  25466. if (e.keyCode === 13 && !e.shiftKey) {
  25467. return;
  25468. }
  25469. e.stopPropagation();
  25470. });
  25471. $exportDialog.on('open', function() {
  25472. $editor.val(plainProtocol.encode(km.getSelectedNode()));
  25473. setTimeout(function() {
  25474. $editor[0].focus();
  25475. }, 10);
  25476. });
  25477. }
  25478. $exportDialog.open();
  25479. },
  25480. queryState: function(km) {
  25481. var selectedNode = km.getSelectedNode();
  25482. return selectedNode ? 0 : -1;
  25483. }
  25484. });
  25485. KityMinder.registerModule('NodeModule', function() {
  25486. return {
  25487. commands: {
  25488. 'AppendChildNode': AppendChildCommand,
  25489. 'AppendSiblingNode': AppendSiblingCommand,
  25490. 'ImportTextNode': ImportTextNode,
  25491. 'ExportTextNode': ExportTextNode,
  25492. 'RemoveNode': RemoveNodeCommand,
  25493. 'EditNode': EditNodeCommand
  25494. },
  25495. 'contextmenu': [{
  25496. command: 'appendsiblingnode'
  25497. }, {
  25498. command: 'appendchildnode'
  25499. }, {
  25500. command: 'editnode'
  25501. }, {
  25502. command: 'removenode'
  25503. }, {
  25504. command: 'importtextnode'
  25505. }, {
  25506. command: 'exporttextnode'
  25507. }, {
  25508. divider: 1
  25509. }],
  25510. 'commandShortcutKeys': {
  25511. 'appendsiblingnode': 'normal::Enter',
  25512. 'appendchildnode': 'normal::Insert|Tab',
  25513. 'editnode': 'normal::F2',
  25514. 'removenode': 'normal::Del|Backspace'
  25515. }
  25516. };
  25517. });
  25518. /* global Renderer: true */
  25519. var FONT_ADJUST = {
  25520. '微软雅黑,Microsoft YaHei': -0.15,
  25521. 'arial black,avant garde': -0.17,
  25522. 'default': -0.15
  25523. };
  25524. var TextRenderer = KityMinder.TextRenderer = kity.createClass('TextRenderer', {
  25525. base: Renderer,
  25526. create: function() {
  25527. return new kity.Group().setId(KityMinder.uuid('node_text'));
  25528. },
  25529. update: function(textGroup, node) {
  25530. function s(name) {
  25531. return node.getData(name) || node.getStyle(name);
  25532. }
  25533. var textArr = node.getText(true);
  25534. var lineHeight = node.getStyle('line-height');
  25535. var fontSize = s('font-size');
  25536. var fontFamily = s('font-family') || 'default';
  25537. var height = (lineHeight * fontSize) * textArr.length - (lineHeight - 1) * fontSize;
  25538. var yStart = -height / 2;
  25539. var adjust = FONT_ADJUST[fontFamily] || 0;
  25540. textGroup.setTranslate(0, adjust * fontSize);
  25541. var rBox = new kity.Box(),
  25542. r = Math.round;
  25543. this.setTextStyle(node, textGroup);
  25544. var textLength = textArr.length;
  25545. var textGroupLength = textGroup.getItems().length;
  25546. if(textLength < textGroupLength){
  25547. for( var i = textLength,ci;ci = textGroup.getItem(i);){
  25548. textGroup.removeItem(i);
  25549. }
  25550. }else if(textLength > textGroupLength){
  25551. var length = textLength - textGroupLength;
  25552. for(var i = 0;i < length;i++){
  25553. var textShape = new kity.Text()
  25554. .setAttr('text-rendering', 'inherit');
  25555. if (kity.Browser.ie) {
  25556. textShape.setVerticalAlign('top');
  25557. } else {
  25558. textShape.setAttr('dominant-baseline', 'text-before-edge');
  25559. }
  25560. textGroup.addItem(textShape);
  25561. }
  25562. }
  25563. for (var i = 0, text, textShape;
  25564. (text = textArr[i], textShape = textGroup.getItem(i)); i++) {
  25565. textShape.setContent(text);
  25566. }
  25567. this.setTextStyle(node, textGroup);
  25568. var textHash = node.getText() + [s('font-size'), s('font-name'), s('font-weight'), s('font-style')].join('/');
  25569. if (node._currentTextHash == textHash && node._currentTextGroupBox) return node._currentTextGroupBox;
  25570. node._currentTextHash = textHash;
  25571. return function() {
  25572. textGroup.eachItem(function(i, textShape) {
  25573. var y = yStart + i * fontSize * lineHeight;
  25574. textShape.setY(y);
  25575. rBox = rBox.merge(new kity.Box(0, y, textShape.getBoundaryBox().width || 1, fontSize));
  25576. });
  25577. //为了让文字在圆中垂直居中
  25578. var w = 0;
  25579. var shape = node.getStyle('shape');
  25580. if(shape && shape=='circle'){
  25581. w = Math.max(rBox.width,rBox.height)/2-rBox.height/2;
  25582. }
  25583. var nBox = new kity.Box(r(rBox.x), r(rBox.y-w), r(rBox.width), r(rBox.height));
  25584. node._currentTextGroupBox = nBox;
  25585. return nBox;
  25586. };
  25587. },
  25588. setTextStyle: function(node, text) {
  25589. var hooks = TextRenderer._styleHooks;
  25590. hooks.forEach(function(hook) {
  25591. hook(node, text);
  25592. });
  25593. }
  25594. });
  25595. utils.extend(TextRenderer, {
  25596. _styleHooks: [],
  25597. registerStyleHook: function(fn) {
  25598. TextRenderer._styleHooks.push(fn);
  25599. }
  25600. });
  25601. kity.extendClass(MinderNode, {
  25602. getTextGroup: function() {
  25603. return this.getRenderer('TextRenderer').getRenderShape();
  25604. }
  25605. });
  25606. KityMinder.registerModule('text', {
  25607. 'renderers': {
  25608. center: TextRenderer
  25609. }
  25610. });
  25611. /* global Renderer: true */
  25612. KityMinder.registerModule('Expand', function() {
  25613. var minder = this;
  25614. var EXPAND_STATE_DATA = 'expandState',
  25615. STATE_EXPAND = 'expand',
  25616. STATE_COLLAPSE = 'collapse';
  25617. // 将展开的操作和状态读取接口拓展到 MinderNode 上
  25618. kity.extendClass(MinderNode, {
  25619. /**
  25620. * 展开节点
  25621. * @param {Policy} policy 展开的策略,默认为 KEEP_STATE
  25622. */
  25623. expand: function() {
  25624. this.setData(EXPAND_STATE_DATA, STATE_EXPAND);
  25625. return this;
  25626. },
  25627. /**
  25628. * 收起节点
  25629. */
  25630. collapse: function() {
  25631. this.setData(EXPAND_STATE_DATA, STATE_COLLAPSE);
  25632. return this;
  25633. },
  25634. /**
  25635. * 判断节点当前的状态是否为展开
  25636. */
  25637. isExpanded: function() {
  25638. var expanded = this.getData(EXPAND_STATE_DATA) !== STATE_COLLAPSE;
  25639. return expanded && (this.isRoot() || this.parent.isExpanded());
  25640. },
  25641. /**
  25642. * 判断节点当前的状态是否为收起
  25643. */
  25644. isCollapsed: function() {
  25645. return !this.isExpanded();
  25646. }
  25647. });
  25648. var ExpandCommand = kity.createClass('ExpandCommand', {
  25649. base: Command,
  25650. execute: function(km, justParents) {
  25651. var node = km.getSelectedNode();
  25652. if (!node) return;
  25653. if (justParents) {
  25654. node = node.parent;
  25655. }
  25656. while(node.parent) {
  25657. node.expand();
  25658. node = node.parent;
  25659. }
  25660. node.renderTree();
  25661. km.layout(100);
  25662. },
  25663. queryState: function(km) {
  25664. return km.getSelectedNode() ? 0 : -1;
  25665. }
  25666. });
  25667. var ExpandToLevelCommand = kity.createClass('ExpandToLevelCommand', {
  25668. base: Command,
  25669. execute: function(km, level) {
  25670. km.getRoot().traverse(function(node) {
  25671. if (node.getLevel() < level) node.expand();
  25672. if (node.getLevel() == level) node.collapse();
  25673. });
  25674. km.refresh(100);
  25675. },
  25676. enableReadOnly: true
  25677. });
  25678. var Expander = kity.createClass('Expander', {
  25679. base: kity.Group,
  25680. constructor: function(node) {
  25681. this.callBase();
  25682. this.radius = 6;
  25683. this.outline = new kity.Circle(this.radius).stroke('gray').fill('white');
  25684. this.sign = new kity.Path().stroke('gray');
  25685. this.addShapes([this.outline, this.sign]);
  25686. this.initEvent(node);
  25687. this.setId(KityMinder.uuid('node_expander'));
  25688. this.setStyle('cursor', 'pointer');
  25689. },
  25690. initEvent: function(node) {
  25691. this.on('mousedown', function(e) {
  25692. if (node.isExpanded()) {
  25693. node.collapse();
  25694. } else {
  25695. node.expand();
  25696. }
  25697. node.renderTree().getMinder().layout(100);
  25698. node.getMinder().fire('contentchange');
  25699. e.stopPropagation();
  25700. e.preventDefault();
  25701. });
  25702. this.on('dblclick click mouseup', function(e) {
  25703. e.stopPropagation();
  25704. e.preventDefault();
  25705. });
  25706. },
  25707. setState: function(state) {
  25708. if (state == 'hide') {
  25709. this.setVisible(false);
  25710. return;
  25711. }
  25712. this.setVisible(true);
  25713. var pathData = ['M', 1.5 - this.radius, 0, 'L', this.radius - 1.5, 0];
  25714. if (state == STATE_COLLAPSE) {
  25715. pathData.push(['M', 0, 1.5 - this.radius, 'L', 0, this.radius - 1.5]);
  25716. }
  25717. this.sign.setPathData(pathData);
  25718. }
  25719. });
  25720. var ExpanderRenderer = kity.createClass('ExpanderRenderer', {
  25721. base: Renderer,
  25722. create: function(node) {
  25723. if (node.isRoot()) return;
  25724. this.expander = new Expander(node);
  25725. node.getRenderContainer().prependShape(this.expander);
  25726. node.expanderRenderer = this;
  25727. this.node = node;
  25728. return this.expander;
  25729. },
  25730. shouldRender: function(node) {
  25731. return !node.isRoot();
  25732. },
  25733. update: function(expander, node, box) {
  25734. if (!node.parent) return;
  25735. var visible = node.parent.isExpanded();
  25736. expander.setState(visible && node.children.length ? node.getData(EXPAND_STATE_DATA) : 'hide');
  25737. var vector = node.getLayoutVectorIn().normalize(expander.radius + node.getStyle('stroke-width'));
  25738. var position = node.getVertexIn().offset(vector.reverse());
  25739. this.expander.setTranslate(position);
  25740. }
  25741. });
  25742. return {
  25743. commands: {
  25744. 'expand': ExpandCommand,
  25745. 'expandtolevel': ExpandToLevelCommand
  25746. },
  25747. events: {
  25748. 'layoutapply': function(e) {
  25749. var r = e.node.getRenderer('ExpanderRenderer');
  25750. if (r.getRenderShape()) {
  25751. r.update(r.getRenderShape(), e.node);
  25752. }
  25753. },
  25754. 'beforerender': function(e) {
  25755. var node = e.node;
  25756. var visible = !node.parent || node.parent.isExpanded();
  25757. var minder = this;
  25758. node.getRenderContainer().setVisible(visible);
  25759. if (!visible) e.stopPropagation();
  25760. },
  25761. 'normal.keydown': function(e) {
  25762. if (this.getStatus() == 'textedit') return;
  25763. if (e.originEvent.keyCode == keymap['/']) {
  25764. var node = this.getSelectedNode();
  25765. if (!node || node == this.getRoot()) return;
  25766. var expanded = node.isExpanded();
  25767. this.getSelectedNodes().forEach(function(node) {
  25768. if (expanded) node.collapse();
  25769. else node.expand();
  25770. node.renderTree();
  25771. });
  25772. this.layout(100);
  25773. this.fire('contentchange');
  25774. e.preventDefault();
  25775. e.stopPropagationImmediately();
  25776. }
  25777. if (e.isShortcutKey('Alt+`')) {
  25778. this.execCommand('expandtolevel', 9999);
  25779. }
  25780. for (var i = 1; i < 6; i++) {
  25781. if (e.isShortcutKey('Alt+' + i)) {
  25782. this.execCommand('expandtolevel', i);
  25783. }
  25784. }
  25785. }
  25786. },
  25787. renderers: {
  25788. outside: ExpanderRenderer
  25789. },
  25790. contextmenu: [{
  25791. command: 'expandtoleaf',
  25792. query: function() {
  25793. return !minder.getSelectedNode();
  25794. },
  25795. fn: function(minder) {
  25796. minder.execCommand('expandtolevel', 9999);
  25797. }
  25798. }, {
  25799. command: 'expandtolevel1',
  25800. query: function() {
  25801. return !minder.getSelectedNode();
  25802. },
  25803. fn: function(minder) {
  25804. minder.execCommand('expandtolevel', 1);
  25805. }
  25806. }, {
  25807. command: 'expandtolevel2',
  25808. query: function() {
  25809. return !minder.getSelectedNode();
  25810. },
  25811. fn: function(minder) {
  25812. minder.execCommand('expandtolevel', 2);
  25813. }
  25814. },{
  25815. command: 'expandtolevel3',
  25816. query: function() {
  25817. return !minder.getSelectedNode();
  25818. },
  25819. fn: function(minder) {
  25820. minder.execCommand('expandtolevel', 3);
  25821. }
  25822. }, {
  25823. divider: true
  25824. }]
  25825. };
  25826. });
  25827. /* global Renderer: true */
  25828. var OutlineRenderer = kity.createClass('OutlineRenderer', {
  25829. base: Renderer,
  25830. create: function(node) {
  25831. var outline = new kity.Rect()
  25832. .setId(KityMinder.uuid('node_outline'));
  25833. this.bringToBack = true;
  25834. return outline;
  25835. },
  25836. update: function(outline, node, box) {
  25837. //增加圆形update、待更好解决方案
  25838. var shape = node.getStyle('shape');
  25839. if(shape){
  25840. if(shape=='circle'){
  25841. return updateCircle(outline, node, box);
  25842. }
  25843. }
  25844. var paddingLeft = node.getStyle('padding-left'),
  25845. paddingRight = node.getStyle('padding-right'),
  25846. paddingTop = node.getStyle('padding-top'),
  25847. paddingBottom = node.getStyle('padding-bottom');
  25848. var outlineBox = {
  25849. x: box.x - paddingLeft,
  25850. y: box.y - paddingTop,
  25851. width: box.width + paddingLeft + paddingRight,
  25852. height: box.height + paddingTop + paddingBottom
  25853. };
  25854. var prefix = node.isSelected() ? 'selected-' : '';
  25855. outline
  25856. .setPosition(outlineBox.x, outlineBox.y)
  25857. .setSize(outlineBox.width, outlineBox.height)
  25858. .setRadius(node.getStyle('radius'))
  25859. .fill(node.getData('background') || node.getStyle(prefix + 'background') || node.getStyle('background'))
  25860. .stroke(node.getStyle(prefix + 'stroke' || node.getStyle('stroke')),
  25861. node.getStyle(prefix + 'stroke-width'));
  25862. return new kity.Box(outlineBox);
  25863. }
  25864. });
  25865. //圆
  25866. function updateCircle(outline, node, box){
  25867. var paddingLeft = node.getStyle('padding-left'),
  25868. paddingRight = node.getStyle('padding-right'),
  25869. paddingTop = node.getStyle('padding-top'),
  25870. paddingBottom = node.getStyle('padding-bottom');
  25871. var width= Math.max(box.width,box.height);
  25872. var outlineBox = {
  25873. x: box.x - paddingLeft,
  25874. y: box.y - paddingTop,
  25875. width: width + paddingLeft + paddingRight,
  25876. height: width + paddingTop + paddingBottom
  25877. };
  25878. var prefix = node.isSelected() ? 'selected-' : '';
  25879. width= Math.max(outlineBox.width,outlineBox.height);
  25880. outline
  25881. .setPosition(outlineBox.x, outlineBox.y)
  25882. .setSize(width, width)
  25883. .setRadius(width/2)
  25884. .fill(node.getData('background') || node.getStyle(prefix + 'background') || node.getStyle('background'))
  25885. .stroke(node.getStyle(prefix + 'stroke' || node.getStyle('stroke')),
  25886. node.getStyle(prefix + 'stroke-width'));
  25887. return new kity.Box(outlineBox);
  25888. }
  25889. var ShadowRenderer = kity.createClass('ShadowRenderer', {
  25890. base: Renderer,
  25891. create: function(node) {
  25892. this.bringToBack = true;
  25893. return new kity.Rect();
  25894. },
  25895. shouldRender: function(node) {
  25896. return node.getStyle('shadow');
  25897. },
  25898. update: function(shadow, node, box) {
  25899. shadow.setPosition(box.x + 4, box.y + 5)
  25900. .fill(node.getStyle('shadow'));
  25901. var shape = node.getStyle('shape');
  25902. if(!shape){
  25903. shadow.setSize(box.width, box.height)
  25904. shadow.setRadius(node.getStyle('radius'));
  25905. }else if(shape=='circle'){
  25906. var width= Math.max(box.width,box.height);
  25907. shadow.setSize(width, width)
  25908. shadow.setRadius(width/2);
  25909. }
  25910. }
  25911. });
  25912. var marker = new kity.Marker();
  25913. marker.setWidth(10);
  25914. marker.setHeight(12);
  25915. marker.setRef(0, 0);
  25916. marker.setViewBox(-6, -4, 8, 10);
  25917. marker.addShape(new kity.Path().setPathData('M-5-3l5,3,-5,3').stroke('#33ffff'));
  25918. var wireframeOption = /wire/.test(window.location.href);
  25919. var WireframeRenderer = kity.createClass('WireframeRenderer', {
  25920. base: Renderer,
  25921. create: function() {
  25922. var wireframe = new kity.Group();
  25923. var oxy = this.oxy = new kity.Path()
  25924. .stroke('#f6f')
  25925. .setPathData('M0,-50L0,50M-50,0L50,0');
  25926. var box = this.wireframe = new kity.Rect()
  25927. .stroke('lightgreen');
  25928. var vectorIn = this.vectorIn = new kity.Path()
  25929. .stroke('#66ffff');
  25930. var vectorOut = this.vectorOut = new kity.Path()
  25931. .stroke('#66ffff');
  25932. vectorIn.setMarker(marker, 'end');
  25933. vectorOut.setMarker(marker, 'end');
  25934. return wireframe.addShapes([oxy, box, vectorIn, vectorOut]);
  25935. },
  25936. shouldRender: function() {
  25937. return wireframeOption;
  25938. },
  25939. update: function(created, node, box) {
  25940. this.wireframe
  25941. .setPosition(box.x, box.y)
  25942. .setSize(box.width, box.height);
  25943. var pin = node.getVertexIn();
  25944. var pout = node.getVertexOut();
  25945. var vin = node.getLayoutVectorIn().normalize(30);
  25946. var vout = node.getLayoutVectorOut().normalize(30);
  25947. this.vectorIn.setPathData(['M', pin.offset(vin.reverse()), 'L', pin]);
  25948. this.vectorOut.setPathData(['M', pout, 'l', vout]);
  25949. }
  25950. });
  25951. KityMinder.registerModule('OutlineModule', function() {
  25952. return {
  25953. events: (!wireframeOption ? null : {
  25954. 'ready': function() {
  25955. this.getPaper().addResource(marker);
  25956. },
  25957. 'layoutallfinish': function() {
  25958. this.getRoot().traverse(function(node) {
  25959. node.getRenderer('WireframeRenderer').update(null, node, node.getContentBox());
  25960. });
  25961. }
  25962. }),
  25963. renderers: {
  25964. outline: OutlineRenderer,
  25965. outside: [ShadowRenderer, WireframeRenderer]
  25966. }
  25967. };
  25968. });
  25969. KityMinder.Geometry = (function() {
  25970. var g = {};
  25971. var min = Math.min,
  25972. max = Math.max,
  25973. abs = Math.abs;
  25974. var own = Object.prototype.hasOwnProperty;
  25975. g.isNumberInRange = function(number, range) {
  25976. return number > range[0] && number < range[1];
  25977. };
  25978. g.getDistance = function(p1, p2) {
  25979. return kity.Vector.fromPoints(p1, p2).length();
  25980. };
  25981. function wrapBox(box) {
  25982. box.width = box.right - box.left;
  25983. box.height = box.bottom - box.top;
  25984. box.x = box.left;
  25985. box.y = box.top;
  25986. box.cx = box.x + box.width / 2;
  25987. box.cy = box.y + box.height / 2;
  25988. return box;
  25989. }
  25990. function uniformBox(box) {
  25991. // duck check
  25992. if ('x' in box) {
  25993. box.left = box.x;
  25994. box.right = box.x + box.width;
  25995. box.top = box.y;
  25996. box.bottom = box.y + box.height;
  25997. }
  25998. }
  25999. g.wrapBox = wrapBox;
  26000. g.getBox = function(p1, p2) {
  26001. return wrapBox({
  26002. left: min(p1.x, p2.x),
  26003. right: max(p1.x, p2.x),
  26004. top: min(p1.y, p2.y),
  26005. bottom: max(p1.y, p2.y)
  26006. });
  26007. };
  26008. g.mergeBox = function(b1, b2) {
  26009. uniformBox(b1);
  26010. uniformBox(b2);
  26011. return wrapBox({
  26012. left: min(b1.left, b2.left),
  26013. right: max(b1.right, b2.right),
  26014. top: min(b1.top, b2.top),
  26015. bottom: max(b1.bottom, b2.bottom)
  26016. });
  26017. };
  26018. g.getBoxRange = function(box) {
  26019. return {
  26020. x: [box.left, box.right],
  26021. y: [box.top, box.bottom]
  26022. };
  26023. };
  26024. g.getBoxVertex = function(box) {
  26025. return {
  26026. leftTop: {
  26027. x: box.left,
  26028. y: box.top
  26029. },
  26030. rightTop: {
  26031. x: box.right,
  26032. y: box.top
  26033. },
  26034. leftBottom: {
  26035. x: box.left,
  26036. y: box.bottom
  26037. },
  26038. rightBottom: {
  26039. x: box.right,
  26040. y: box.bottom
  26041. }
  26042. };
  26043. };
  26044. g.isPointInsideBox = function(p, b) {
  26045. uniformBox(b);
  26046. var ranges = g.getBoxRange(b);
  26047. return g.isNumberInRange(p.x, ranges.x) && g.isNumberInRange(p.y, ranges.y);
  26048. };
  26049. g.getIntersectBox = function(b1, b2) {
  26050. uniformBox(b1);
  26051. uniformBox(b2);
  26052. var minx = max(b1.left, b2.left),
  26053. miny = max(b1.top, b2.top),
  26054. maxx = min(b1.right, b2.right),
  26055. maxy = min(b1.bottom, b2.bottom);
  26056. return minx < maxx && miny < maxy ? wrapBox({
  26057. left: minx,
  26058. right: maxx,
  26059. top: miny,
  26060. bottom: maxy
  26061. }) : null;
  26062. };
  26063. g.snapToSharp = function(unknown) {
  26064. if (utils.isNumber(unknown)) {
  26065. return (unknown | 0) + 0.5;
  26066. }
  26067. if (utils.isArray(unknown)) {
  26068. return unknown.map(g.snapToSharp);
  26069. }
  26070. ['x', 'y', 'left', 'top', 'right', 'bottom'].forEach(function(n) {
  26071. if (own.call(unknown, n)) {
  26072. unknown[n] = g.snapToSharp(unknown[n]);
  26073. }
  26074. });
  26075. return unknown;
  26076. };
  26077. g.expandBox = function(box, sizeX, sizeY) {
  26078. if (sizeY === undefined) {
  26079. sizeY = sizeX;
  26080. }
  26081. return wrapBox({
  26082. left: box.left - sizeX,
  26083. top: box.top - sizeY,
  26084. right: box.right + sizeX,
  26085. bottom: box.bottom + sizeY
  26086. });
  26087. };
  26088. return g;
  26089. })();
  26090. KityMinder.registerModule("HistoryModule", function() {
  26091. var km = this;
  26092. var Scene = kity.createClass('Scene', {
  26093. constructor: function(root,inputStatus) {
  26094. this.data = root.clone();
  26095. this.inputStatus = inputStatus;
  26096. },
  26097. getData: function() {
  26098. return this.data;
  26099. },
  26100. cloneData: function() {
  26101. return this.getData().clone();
  26102. },
  26103. equals: function(scene) {
  26104. return this.getData().equals(scene.getData());
  26105. },
  26106. isInputStatus:function(){
  26107. return this.inputStatus;
  26108. },
  26109. setInputStatus:function(status){
  26110. this.inputStatus = status;
  26111. }
  26112. });
  26113. var HistoryManager = kity.createClass('HistoryManager', {
  26114. constructor: function(km) {
  26115. this.list = [];
  26116. this.index = 0;
  26117. this.hasUndo = false;
  26118. this.hasRedo = false;
  26119. this.km = km;
  26120. },
  26121. undo: function() {
  26122. if (this.hasUndo) {
  26123. var currentScene = this.list[this.index];
  26124. //如果是输入文字时的保存,直接回复当前场景
  26125. if(currentScene && currentScene.isInputStatus()){
  26126. this.saveScene();
  26127. this.restore(--this.index);
  26128. currentScene.setInputStatus(false);
  26129. return;
  26130. }
  26131. if(this.list.length == 1){
  26132. this.restore(0);
  26133. return;
  26134. }
  26135. if (!this.list[this.index - 1] && this.list.length == 1) {
  26136. this.reset();
  26137. return;
  26138. }
  26139. while (this.list[this.index].equals(this.list[this.index - 1])) {
  26140. this.index--;
  26141. if (this.index === 0) {
  26142. return this.restore(0);
  26143. }
  26144. }
  26145. this.restore(--this.index);
  26146. }
  26147. },
  26148. redo: function() {
  26149. if (this.hasRedo) {
  26150. while (this.list[this.index].equals(this.list[this.index + 1])) {
  26151. this.index++;
  26152. if (this.index == this.list.length - 1) {
  26153. return this.restore(this.index);
  26154. }
  26155. }
  26156. this.restore(++this.index);
  26157. }
  26158. },
  26159. partialRenewal: function(target) {
  26160. var selectedNodes = [];
  26161. function compareNode(source, target) {
  26162. if (source.getText() != target.getText()) {
  26163. return false;
  26164. }
  26165. if (utils.compareObject(source.getData(), target.getData()) === false) {
  26166. return false;
  26167. }
  26168. if (utils.compareObject(source.getTmpData(), target.getTmpData()) === false) {
  26169. return false;
  26170. }
  26171. return true;
  26172. }
  26173. function appendChildNode(parent, child) {
  26174. if (child.isSelected()) {
  26175. selectedNodes.push(child);
  26176. }
  26177. km.appendNode(child, parent);
  26178. child.render();
  26179. var children = utils.cloneArr(child.children);
  26180. for (var i = 0, ci; ci = children[i++];) {
  26181. appendChildNode(child, ci);
  26182. }
  26183. }
  26184. function traverseNode(srcNode, tagNode) {
  26185. if (compareNode(srcNode, tagNode) === false) {
  26186. srcNode.setValue(tagNode);
  26187. }
  26188. //todo,这里有性能问题,变成全部render了
  26189. srcNode.render();
  26190. if (srcNode.isSelected()) {
  26191. selectedNodes.push(srcNode);
  26192. }
  26193. for (var i = 0, j = 0, si, tj;
  26194. (si = srcNode.children[i], tj = tagNode.children[j], si || tj); i++, j++) {
  26195. if (si && !tj) {
  26196. i--;
  26197. km.removeNode(si);
  26198. } else if (!si && tj) {
  26199. j--;
  26200. appendChildNode(srcNode, tj);
  26201. } else {
  26202. traverseNode(si, tj);
  26203. }
  26204. }
  26205. }
  26206. traverseNode(km.getRoot(), target);
  26207. km.layout(200);
  26208. km.select(selectedNodes,true);
  26209. selectedNodes = [];
  26210. },
  26211. restore: function(index) {
  26212. index = index === undefined ? this.index : index;
  26213. var scene = this.list[index];
  26214. this.partialRenewal(scene.cloneData());
  26215. this.update();
  26216. this.km.fire('restoreScene');
  26217. this.km.fire('contentChange');
  26218. },
  26219. getScene: function(inputStatus) {
  26220. return new Scene(this.km.getRoot(),inputStatus);
  26221. },
  26222. saveScene: function(inputStatus) {
  26223. var currentScene = this.getScene(inputStatus);
  26224. var lastScene = this.list[this.index];
  26225. if (lastScene && lastScene.equals(currentScene)) {
  26226. if(inputStatus){
  26227. lastScene.setInputStatus(true);
  26228. this.update();
  26229. }
  26230. return;
  26231. }
  26232. this.list = this.list.slice(0, this.index + 1);
  26233. this.list.push(currentScene);
  26234. //如果大于最大数量了,就把最前的剔除
  26235. if (this.list.length > this.km.getOptions('maxUndoCount')) {
  26236. this.list.shift();
  26237. }
  26238. this.index = this.list.length - 1;
  26239. //跟新undo/redo状态
  26240. this.update();
  26241. },
  26242. update: function() {
  26243. this.hasRedo = !!this.list[this.index + 1];
  26244. this.hasUndo = !!this.list[this.index - 1];
  26245. var currentScene = this.list[this.index];
  26246. if(currentScene && currentScene.isInputStatus()){
  26247. this.hasUndo = true;
  26248. }
  26249. },
  26250. reset: function() {
  26251. this.list = [];
  26252. this.index = 0;
  26253. this.hasUndo = false;
  26254. this.hasRedo = false;
  26255. }
  26256. });
  26257. //为km实例添加history管理
  26258. this.historyManager = new HistoryManager(this);
  26259. return {
  26260. defaultOptions: {
  26261. maxUndoCount: 20,
  26262. maxInputCount: 20
  26263. },
  26264. "commands": {
  26265. "undo": kity.createClass("UndoCommand", {
  26266. base: Command,
  26267. execute: function(km) {
  26268. km.historyManager.undo();
  26269. },
  26270. queryState: function(km) {
  26271. return km.historyManager.hasUndo ? 0 : -1;
  26272. },
  26273. isNeedUndo: function() {
  26274. return false;
  26275. }
  26276. }),
  26277. "redo": kity.createClass("RedoCommand", {
  26278. base: Command,
  26279. execute: function(km) {
  26280. km.historyManager.redo();
  26281. },
  26282. queryState: function(km) {
  26283. return km.historyManager.hasRedo ? 0 : -1;
  26284. },
  26285. isNeedUndo: function() {
  26286. return false;
  26287. }
  26288. })
  26289. },
  26290. commandShortcutKeys: {
  26291. "undo": "ctrl+z", //undo
  26292. "redo": "ctrl+y" //redo
  26293. },
  26294. "events": {
  26295. "saveScene": function(e) {
  26296. this.historyManager.saveScene(e.inputStatus);
  26297. },
  26298. "import": function() {
  26299. this.historyManager.reset();
  26300. }
  26301. }
  26302. };
  26303. });
  26304. KityMinder.registerModule('ProgressModule', function() {
  26305. var minder = this;
  26306. var PROGRESS_DATA = 'progress';
  26307. // Designed by Akikonata
  26308. var BG_COLOR = '#FFED83';
  26309. var PIE_COLOR = '#43BC00';
  26310. var SHADOW_PATH = 'M10,3c4.418,0,8,3.582,8,8h1c0-5.523-3.477-10-9-10S1,5.477,1,11h1C2,6.582,5.582,3,10,3z';
  26311. var SHADOW_COLOR = '#8E8E8E';
  26312. var FRAME_PATH = 'M10,0C4.477,0,0,4.477,0,10c0,5.523,4.477,10,10,10s10-4.477,10-10C20,4.477,15.523,0,10,0zM10,18c-4.418,0-8-3.582-8-8s3.582-8,8-8s8,3.582,8,8S14.418,18,10,18z';
  26313. var FRAME_GRAD = new kity.LinearGradient().pipe(function(g) {
  26314. g.setStartPosition(0, 0);
  26315. g.setEndPosition(0, 1);
  26316. g.addStop(0, '#fff');
  26317. g.addStop(1, '#ccc');
  26318. });
  26319. var CHECK_PATH = 'M15.812,7.896l-6.75,6.75l-4.5-4.5L6.25,8.459l2.812,2.803l5.062-5.053L15.812,7.896z';
  26320. var CHECK_COLOR = '#EEE';
  26321. minder.getPaper().addResource(FRAME_GRAD);
  26322. // 进度图标的图形
  26323. var ProgressIcon = kity.createClass('ProgressIcon', {
  26324. base: kity.Group,
  26325. constructor: function(value) {
  26326. this.callBase();
  26327. this.setSize(20);
  26328. this.create();
  26329. this.setValue(value);
  26330. this.setId(KityMinder.uuid('node_progress'));
  26331. this.translate(0.5, 0.5);
  26332. },
  26333. setSize: function(size) {
  26334. this.width = this.height = size;
  26335. },
  26336. create: function() {
  26337. var bg, pie, shadow, frame, check;
  26338. bg = new kity.Circle(9)
  26339. .fill(BG_COLOR);
  26340. pie = new kity.Pie(9, 0)
  26341. .fill(PIE_COLOR);
  26342. shadow = new kity.Path()
  26343. .setPathData(SHADOW_PATH)
  26344. .setTranslate(-10, -10)
  26345. .fill(SHADOW_COLOR);
  26346. frame = new kity.Path()
  26347. .setTranslate(-10, -10)
  26348. .setPathData(FRAME_PATH)
  26349. .fill(FRAME_GRAD);
  26350. check = new kity.Path()
  26351. .setTranslate(-10, -10)
  26352. .setPathData(CHECK_PATH)
  26353. .fill(CHECK_COLOR);
  26354. this.addShapes([bg, pie, shadow, check, frame]);
  26355. this.pie = pie;
  26356. this.check = check;
  26357. },
  26358. setValue: function(value) {
  26359. this.pie.setAngle(-360 * (value - 1) / 8);
  26360. this.check.setVisible(value == 9);
  26361. }
  26362. });
  26363. var ProgressCommand = kity.createClass('ProgressCommand', {
  26364. base: Command,
  26365. execute: function(km, value) {
  26366. var nodes = km.getSelectedNodes();
  26367. for (var i = 0; i < nodes.length; i++) {
  26368. nodes[i].setData(PROGRESS_DATA, value || null).render();
  26369. }
  26370. km.layout();
  26371. },
  26372. queryValue: function(km) {
  26373. var nodes = km.getSelectedNodes();
  26374. var val;
  26375. for (var i = 0; i < nodes.length; i++) {
  26376. val = nodes[i].getData(PROGRESS_DATA);
  26377. if (val) break;
  26378. }
  26379. return val|| null;
  26380. },
  26381. queryState: function(km) {
  26382. return km.getSelectedNodes().length ? 0 : -1;
  26383. }
  26384. });
  26385. return {
  26386. 'commands': {
  26387. 'progress': ProgressCommand
  26388. },
  26389. 'renderers': {
  26390. left: kity.createClass('ProgressRenderer', {
  26391. base: KityMinder.Renderer,
  26392. create: function(node) {
  26393. return new ProgressIcon();
  26394. },
  26395. shouldRender: function(node) {
  26396. return node.getData(PROGRESS_DATA);
  26397. },
  26398. update: function(icon, node, box) {
  26399. var data = node.getData(PROGRESS_DATA);
  26400. var spaceLeft = node.getStyle('space-left');
  26401. var x, y;
  26402. icon.setValue(data);
  26403. x = box.left - icon.width - spaceLeft;
  26404. y = -icon.height / 2;
  26405. icon.setTranslate(x + icon.width / 2, y + icon.height / 2);
  26406. return new kity.Box(x, y, icon.width, icon.height);
  26407. }
  26408. })
  26409. }
  26410. };
  26411. });
  26412. KityMinder.registerModule('PriorityModule', function() {
  26413. var minder = this;
  26414. // Designed by Akikonata
  26415. // [MASK, BACK]
  26416. var PRIORITY_COLORS = [null,
  26417. ['#FF1200', '#840023'], // 1 - red
  26418. ['#0074FF', '#01467F'], // 2 - blue
  26419. ['#00AF00', '#006300'], // 3 - green
  26420. ['#FF962E', '#B25000'], // 4 - orange
  26421. ['#A464FF', '#4720C4'], // 5 - purple
  26422. ['#A3A3A3', '#515151'], // 6,7,8,9 - gray
  26423. ['#A3A3A3', '#515151'],
  26424. ['#A3A3A3', '#515151'],
  26425. ['#A3A3A3', '#515151'],
  26426. ]; // hue from 1 to 5
  26427. var BACK_PATH = 'M0,13c0,3.866,3.134,7,7,7h6c3.866,0,7-3.134,7-7V7H0V13z';
  26428. var MASK_PATH = 'M20,10c0,3.866-3.134,7-7,7H7c-3.866,0-7-3.134-7-7V7c0-3.866,3.134-7,7-7h6c3.866,0,7,3.134,7,7V10z';
  26429. var PRIORITY_DATA = 'priority';
  26430. // 进度图标的图形
  26431. var PriorityIcon = kity.createClass('PriorityIcon', {
  26432. base: kity.Group,
  26433. constructor: function() {
  26434. this.callBase();
  26435. this.setSize(20);
  26436. this.create();
  26437. this.setId(KityMinder.uuid('node_priority'));
  26438. },
  26439. setSize: function(size) {
  26440. this.width = this.height = size;
  26441. },
  26442. create: function() {
  26443. var white, back, mask, number; // 4 layer
  26444. white = new kity.Path().setPathData(MASK_PATH).fill('white');
  26445. back = new kity.Path().setPathData(BACK_PATH).setTranslate(0.5, 0.5);
  26446. mask = new kity.Path().setPathData(MASK_PATH).setOpacity(0.8).setTranslate(0.5, 0.5);
  26447. number = new kity.Text()
  26448. .setX(this.width / 2 - 0.5).setY(this.height / 2 - 1.5)
  26449. .setTextAnchor('middle')
  26450. .setVerticalAlign('middle')
  26451. .setFontItalic(true)
  26452. .setFontSize(14)
  26453. .fill('white');
  26454. this.addShapes([back, mask, number]);
  26455. this.mask = mask;
  26456. this.back = back;
  26457. this.number = number;
  26458. },
  26459. setValue: function(value) {
  26460. var back = this.back,
  26461. mask = this.mask,
  26462. number = this.number;
  26463. var color = PRIORITY_COLORS[value];
  26464. if (color) {
  26465. back.fill(color[1]);
  26466. mask.fill(color[0]);
  26467. }
  26468. number.setContent(value);
  26469. }
  26470. });
  26471. // 提供的命令
  26472. var PriorityCommand = kity.createClass('SetPriorityCommand', {
  26473. base: Command,
  26474. execute: function(km, value) {
  26475. var nodes = km.getSelectedNodes();
  26476. for (var i = 0; i < nodes.length; i++) {
  26477. nodes[i].setData(PRIORITY_DATA, value || null).render();
  26478. }
  26479. km.layout();
  26480. },
  26481. queryValue: function(km) {
  26482. var nodes = km.getSelectedNodes();
  26483. var val;
  26484. for (var i = 0; i < nodes.length; i++) {
  26485. val = nodes[i].getData(PRIORITY_DATA);
  26486. if (val) break;
  26487. }
  26488. return val || null;
  26489. },
  26490. queryState: function(km) {
  26491. return km.getSelectedNodes().length ? 0 : -1;
  26492. }
  26493. });
  26494. return {
  26495. 'commands': {
  26496. 'priority': PriorityCommand,
  26497. },
  26498. 'renderers': {
  26499. left: kity.createClass('PriorityRenderer', {
  26500. base: KityMinder.Renderer,
  26501. create: function(node) {
  26502. return new PriorityIcon();
  26503. },
  26504. shouldRender: function(node) {
  26505. return node.getData(PRIORITY_DATA);
  26506. },
  26507. update: function(icon, node, box) {
  26508. var data = node.getData(PRIORITY_DATA);
  26509. var spaceLeft = node.getStyle('space-left'),
  26510. x, y;
  26511. icon.setValue(data);
  26512. x = box.left - icon.width - spaceLeft;
  26513. y = -icon.height / 2;
  26514. icon.setTranslate(x, y);
  26515. return new kity.Box({
  26516. x: x,
  26517. y: y,
  26518. width: icon.width,
  26519. height: icon.height
  26520. });
  26521. }
  26522. })
  26523. }
  26524. };
  26525. });
  26526. KityMinder.registerModule('image', function() {
  26527. function loadImageSize(url, callback) {
  26528. var img = document.createElement('img');
  26529. img.onload = function() {
  26530. callback(img.width, img.height);
  26531. };
  26532. img.onerror = function() {
  26533. callback(null);
  26534. };
  26535. img.src = url;
  26536. }
  26537. function fitImageSize(width, height, maxWidth, maxHeight) {
  26538. var ratio = width / height,
  26539. fitRatio = maxWidth / maxHeight;
  26540. // 宽高比大于最大尺寸的宽高比,以宽度为标准适应
  26541. if (width > maxWidth && ratio > fitRatio) {
  26542. width = maxWidth;
  26543. height = width / ratio;
  26544. } else if (height > maxHeight) {
  26545. height = maxHeight;
  26546. width = height * ratio;
  26547. }
  26548. return {
  26549. width: width | 0,
  26550. height: height | 0
  26551. };
  26552. }
  26553. var ImageCommand = kity.createClass('ImageCommand', {
  26554. base: Command,
  26555. execute: function(km, url, title) {
  26556. var nodes = km.getSelectedNodes();
  26557. loadImageSize(url, function(width, height) {
  26558. if (!width) return;
  26559. utils.each(nodes, function(i, n) {
  26560. var size = fitImageSize(
  26561. width, height,
  26562. km.getOptions('maxImageWidth'),
  26563. km.getOptions('maxImageHeight'));
  26564. n.setData('image', url);
  26565. n.setData('imageTitle', title);
  26566. n.setData('imageSize', size);
  26567. n.render();
  26568. });
  26569. km.fire("saveScene");
  26570. km.layout(300);
  26571. });
  26572. },
  26573. queryState: function(km) {
  26574. var nodes = km.getSelectedNodes(),
  26575. result = 0;
  26576. if (nodes.length === 0) {
  26577. return -1;
  26578. }
  26579. utils.each(nodes, function(i, n) {
  26580. if (n && n.getData('image')) {
  26581. result = 0;
  26582. return false;
  26583. }
  26584. });
  26585. return result;
  26586. },
  26587. queryValue: function(km) {
  26588. var node = km.getSelectedNode();
  26589. return {
  26590. url: node.getData('image'),
  26591. title: node.getData('imageTitle')
  26592. };
  26593. }
  26594. });
  26595. var RemoveImageCommand = kity.createClass('RemoveImageCommand', {
  26596. base: Command,
  26597. execute: function(km) {
  26598. var nodes = km.getSelectedNodes();
  26599. utils.each(nodes, function(i, n) {
  26600. n.setData('image').render();
  26601. });
  26602. km.layout(300);
  26603. },
  26604. queryState: function(km) {
  26605. var nodes = km.getSelectedNodes();
  26606. if (nodes.length === 0) {
  26607. return -1;
  26608. }
  26609. var image = false;
  26610. utils.each(nodes, function(i, n) {
  26611. if (n.getData('image')) {
  26612. image = true;
  26613. return false;
  26614. }
  26615. });
  26616. if (image) {
  26617. return 0;
  26618. }
  26619. return -1;
  26620. }
  26621. });
  26622. var ImageRenderer = kity.createClass('ImageRenderer', {
  26623. base: KityMinder.Renderer,
  26624. create: function(node) {
  26625. return new kity.Image(node.getData('image'));
  26626. },
  26627. shouldRender: function(node) {
  26628. return node.getData('image');
  26629. },
  26630. update: function(image, node, box) {
  26631. var url = node.getData('image');
  26632. var title = node.getData('imageTitle');
  26633. var size = node.getData('imageSize');
  26634. var spaceTop = node.getStyle('space-top');
  26635. if (!size) return;
  26636. if (title) {
  26637. image.node.setAttributeNS('http://www.w3.org/1999/xlink', 'title', title);
  26638. }
  26639. var x = box.cx - size.width / 2;
  26640. var y = box.y - size.height - spaceTop;
  26641. image
  26642. .setUrl(url)
  26643. .setX(x | 0)
  26644. .setY(y | 0)
  26645. .setWidth(size.width | 0)
  26646. .setHeight(size.height | 0);
  26647. return new kity.Box(x | 0, y | 0, size.width | 0, size.height | 0);
  26648. }
  26649. });
  26650. return {
  26651. 'defaultOptions': {
  26652. 'maxImageWidth': 200,
  26653. 'maxImageHeight': 200
  26654. },
  26655. 'commands': {
  26656. 'image': ImageCommand,
  26657. 'removeimage': RemoveImageCommand
  26658. },
  26659. 'renderers': {
  26660. 'top': ImageRenderer
  26661. }
  26662. };
  26663. });
  26664. KityMinder.registerModule('Resource', function() {
  26665. // String Hash
  26666. // https://github.com/drostie/sha3-js/edit/master/blake32.min.js
  26667. var blake32=(function(){var k,g,r,l,m,o,p,q,t,w,x;x=4*(1<<30);k=[0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19];m=[0x243F6A88,0x85A308D3,0x13198A2E,0x03707344,0xA4093822,0x299F31D0,0x082EFA98,0xEC4E6C89,0x452821E6,0x38D01377,0xBE5466CF,0x34E90C6C,0xC0AC29B7,0xC97C50DD,0x3F84D5B5,0xB5470917];w=function(i){if(i<0){i+=x}return("00000000"+i.toString(16)).slice(-8)};o=[[16,50,84,118,152,186,220,254],[174,132,249,109,193,32,123,53],[139,12,37,223,234,99,23,73],[151,19,205,235,98,165,4,143],[9,117,66,250,30,203,134,211],[194,166,176,56,212,87,239,145],[92,241,222,164,112,54,41,184],[189,231,28,147,5,79,104,162],[246,158,59,128,44,125,65,90],[42,72,103,81,191,233,195,13]];p=function(a,b,n){var s=q[a]^q[b];q[a]=(s>>>n)|(s<<(32-n))};g=function(i,a,b,c,d){var u=l+o[r][i]%16,v=l+(o[r][i]>>4);a%=4;b=4+b%4;c=8+c%4;d=12+d%4;q[a]+=q[b]+(t[u]^m[v%16]);p(d,a,16);q[c]+=q[d];p(b,c,12);q[a]+=q[b]+(t[v]^m[u%16]);p(d,a,8);q[c]+=q[d];p(b,c,7)};return function(a,b){if(!(b instanceof Array&&b.length===4)){b=[0,0,0,0]}var c,d,e,L,f,h,j,i;d=k.slice(0);c=m.slice(0,8);for(r=0;r<4;r+=1){c[r]^=b[r]}e=a.length*16;f=(e%512>446||e%512===0)?0:e;if(e%512===432){a+="\u8001"}else{a+="\u8000";while(a.length%32!==27){a+="\u0000"}a+="\u0001"}t=[];for(i=0;i<a.length;i+=2){t.push(a.charCodeAt(i)*65536+a.charCodeAt(i+1))}t.push(0);t.push(e);h=t.length-16;j=0;for(l=0;l<t.length;l+=16){j+=512;L=(l===h)?f:Math.min(e,j);q=d.concat(c);q[12]^=L;q[13]^=L;for(r=0;r<10;r+=1){for(i=0;i<8;i+=1){if(i<4){g(i,i,i,i,i)}else{g(i,i,i+1,i+2,i+3)}}}for(i=0;i<8;i+=1){d[i]^=b[i%4]^q[i]^q[i+8]}}return d.map(w).join("")}}());
  26668. /**
  26669. * 自动使用的颜色序列
  26670. */
  26671. var RESOURCE_COLOR_SERIES = [51, 303, 75, 200, 157, 0, 26, 254].map(function(h) {
  26672. return kity.Color.createHSL(h, 100, 85);
  26673. });
  26674. /**
  26675. * 在 Minder 上拓展一些关于资源的支持接口
  26676. */
  26677. kity.extendClass(Minder, {
  26678. /**
  26679. * 获取字符串的哈希值
  26680. *
  26681. * @param {String} str
  26682. * @return {Number} hashCode
  26683. */
  26684. getHashCode: function(str) {
  26685. str = blake32(str);
  26686. var hash = 1315423911, i, ch;
  26687. for (i = str.length - 1; i >= 0; i--) {
  26688. ch = str.charCodeAt(i);
  26689. hash ^= ((hash << 5) + ch + (hash >> 2));
  26690. }
  26691. return (hash & 0x7FFFFFFF);
  26692. },
  26693. /**
  26694. * 获取脑图中某个资源对应的颜色
  26695. *
  26696. * 如果存在同名资源,则返回已经分配给该资源的颜色,否则分配给该资源一个颜色,并且返回
  26697. *
  26698. * 如果资源数超过颜色序列数量,返回哈希颜色
  26699. *
  26700. * @param {String} resource 资源名称
  26701. * @return {Color}
  26702. */
  26703. getResourceColor: function(resource) {
  26704. var colorMapping = this._getResourceColorIndexMapping();
  26705. var nextIndex;
  26706. if (!colorMapping.hasOwnProperty(resource)) {
  26707. // 找不到找下个可用索引
  26708. nextIndex = this._getNextResourceColorIndex();
  26709. colorMapping[resource] = nextIndex;
  26710. }
  26711. // 资源过多,找不到可用索引颜色,统一返回哈希函数得到的颜色
  26712. return RESOURCE_COLOR_SERIES[colorMapping[resource]] || kity.Color.createHSL(Math.floor(this.getHashCode(resource) / 0x7FFFFFFF * 359), 100, 85);
  26713. },
  26714. /**
  26715. * 获得已使用的资源的列表
  26716. *
  26717. * @return {Array}
  26718. */
  26719. getUsedResource: function() {
  26720. var mapping = this._getResourceColorIndexMapping();
  26721. var used = [],
  26722. resource;
  26723. for (resource in mapping) {
  26724. if (mapping.hasOwnProperty(resource)) {
  26725. used.push(resource);
  26726. }
  26727. }
  26728. return used;
  26729. },
  26730. /**
  26731. * 获取脑图下一个可用的资源颜色索引
  26732. *
  26733. * @return {int}
  26734. */
  26735. _getNextResourceColorIndex: function() {
  26736. // 获取现有颜色映射
  26737. // resource => color_index
  26738. var colorMapping = this._getResourceColorIndexMapping();
  26739. var resource, used, i;
  26740. used = [];
  26741. // 抽取已经使用的值到 used 数组
  26742. for (resource in colorMapping) {
  26743. if (colorMapping.hasOwnProperty(resource)) {
  26744. used.push(colorMapping[resource]);
  26745. }
  26746. }
  26747. // 枚举所有的可用值,如果还没被使用,返回
  26748. for (i = 0; i < RESOURCE_COLOR_SERIES.length; i++) {
  26749. if (!~used.indexOf(i)) return i;
  26750. }
  26751. // 没有可用的颜色了
  26752. return -1;
  26753. },
  26754. // 获取现有颜色映射
  26755. // resource => color_index
  26756. _getResourceColorIndexMapping: function() {
  26757. return this._resourceColorMapping || (this._resourceColorMapping = {});
  26758. }
  26759. });
  26760. /**
  26761. * @class 设置资源的命令
  26762. *
  26763. * @example
  26764. *
  26765. * // 设置选中节点资源为 "张三"
  26766. * minder.execCommand('resource', ['张三']);
  26767. *
  26768. * // 添加资源 "李四" 到选中节点
  26769. * var resource = minder.queryCommandValue();
  26770. * resource.push('李四');
  26771. * minder.execCommand('resource', resource);
  26772. *
  26773. * // 清除选中节点的资源
  26774. * minder.execCommand('resource', null);
  26775. */
  26776. var ResourceCommand = kity.createClass('ResourceCommand', {
  26777. base: Command,
  26778. execute: function(minder, resource) {
  26779. var nodes = minder.getSelectedNodes();
  26780. if (typeof(resource) == 'string') {
  26781. resource = [resource];
  26782. }
  26783. nodes.forEach(function(node) {
  26784. node.setData('resource', resource).render();
  26785. });
  26786. minder.layout(200);
  26787. },
  26788. queryValue: function(minder) {
  26789. var nodes = minder.getSelectedNodes();
  26790. var resource = [];
  26791. nodes.forEach(function(node) {
  26792. var nodeResource = node.getData('resource');
  26793. if (!nodeResource) return;
  26794. nodeResource.forEach(function(name) {
  26795. if (!~resource.indexOf(name)) {
  26796. resource.push(name);
  26797. }
  26798. });
  26799. });
  26800. return resource;
  26801. },
  26802. queryState: function(km) {
  26803. return km.getSelectedNode() ? 0 : -1;
  26804. }
  26805. });
  26806. /**
  26807. * @class 资源的覆盖图形
  26808. *
  26809. * 该类为一个资源以指定的颜色渲染一个动态的覆盖图形
  26810. */
  26811. var ResourceOverlay = kity.createClass('ResourceOverlay', {
  26812. base: kity.Group,
  26813. constructor: function() {
  26814. this.callBase();
  26815. var text, rect;
  26816. rect = this.rect = new kity.Rect().setRadius(4);
  26817. text = this.text = new kity.Text()
  26818. .setFontSize(12)
  26819. .setVerticalAlign('middle');
  26820. this.addShapes([rect, text]);
  26821. },
  26822. setValue: function(resourceName, color) {
  26823. var paddingX = 8,
  26824. paddingY = 4,
  26825. borderRadius = 4;
  26826. var text, box, rect;
  26827. text = this.text;
  26828. if (resourceName == this.lastResourceName) {
  26829. box = this.lastBox;
  26830. } else {
  26831. text.setContent(resourceName);
  26832. box = text.getBoundaryBox();
  26833. this.lastResourceName = resourceName;
  26834. this.lastBox = box;
  26835. }
  26836. text.setX(paddingX).fill(color.dec('l', 70));
  26837. rect = this.rect;
  26838. rect.setPosition(0, box.y - paddingY);
  26839. this.width = Math.round(box.width + paddingX * 2);
  26840. this.height = Math.round(box.height + paddingY * 2);
  26841. rect.setSize(this.width, this.height);
  26842. rect.fill(color);
  26843. }
  26844. });
  26845. /**
  26846. * @class 资源渲染器
  26847. */
  26848. var ResourceRenderer = kity.createClass('ResourceRenderer', {
  26849. base: KityMinder.Renderer,
  26850. create: function(node) {
  26851. this.overlays = [];
  26852. return new kity.Group();
  26853. },
  26854. shouldRender: function(node) {
  26855. return node.getData('resource') && node.getData('resource').length;
  26856. },
  26857. update: function(container, node, box) {
  26858. var spaceRight = node.getStyle('space-right');
  26859. var overlays = this.overlays;
  26860. var resource = node.getData('resource');
  26861. var minder = node.getMinder();
  26862. var i, overlay, x;
  26863. x = 0;
  26864. for (i = 0; i < resource.length; i++) {
  26865. x += spaceRight;
  26866. overlay = overlays[i];
  26867. if (!overlay) {
  26868. overlay = new ResourceOverlay();
  26869. overlays.push(overlay);
  26870. container.addShape(overlay);
  26871. }
  26872. overlay.setVisible(true);
  26873. overlay.setValue(resource[i], minder.getResourceColor(resource[i]));
  26874. overlay.setTranslate(x, -1);
  26875. x += overlay.width;
  26876. }
  26877. while ((overlay = overlays[i++])) overlay.setVisible(false);
  26878. container.setTranslate(box.right, 0);
  26879. return new kity.Box({
  26880. x: box.right,
  26881. y: Math.round(-overlays[0].height / 2),
  26882. width: x,
  26883. height: overlays[0].height
  26884. });
  26885. }
  26886. });
  26887. return {
  26888. commands: {
  26889. 'resource': ResourceCommand
  26890. },
  26891. renderers: {
  26892. right: ResourceRenderer
  26893. }
  26894. };
  26895. });
  26896. /**
  26897. * @fileOverview
  26898. *
  26899. * 支持节点详细信息(HTML)格式
  26900. *
  26901. * @author: techird
  26902. * @copyright: Baidu FEX, 2014
  26903. */
  26904. KityMinder.registerModule('NoteModule', function() {
  26905. var NOTE_PATH = 'M9,9H3V8h6L9,9L9,9z M9,7H3V6h6V7z M9,5H3V4h6V5z M8.5,11H2V2h8v7.5 M9,12l2-2V1H1v11';
  26906. var NoteCommand = kity.createClass('NoteCommand', {
  26907. base: Command,
  26908. execute: function(minder, note) {
  26909. var node = minder.getSelectedNode();
  26910. node.setData('note', note);
  26911. node.render();
  26912. node.getMinder().layout(300);
  26913. },
  26914. queryState: function(minder) {
  26915. return minder.getSelectedNodes().length === 1 ? 0 : -1;
  26916. },
  26917. queryValue: function(minder) {
  26918. var node = minder.getSelectedNode();
  26919. return node && node.getData('note');
  26920. }
  26921. });
  26922. var NoteIcon = kity.createClass('NoteIcon', {
  26923. base: kity.Group,
  26924. constructor: function() {
  26925. this.callBase();
  26926. this.width = 16;
  26927. this.height = 17;
  26928. this.rect = new kity.Rect(16, 17, 0.5, -8.5, 2).fill('transparent');
  26929. this.path = new kity.Path().setPathData(NOTE_PATH).setTranslate(2.5, -6.5);
  26930. this.addShapes([this.rect, this.path]);
  26931. this.on('mouseover', function() {
  26932. this.rect.fill('rgba(255, 255, 200, .8)');
  26933. }).on('mouseout', function() {
  26934. this.rect.fill('transparent');
  26935. });
  26936. this.setStyle('cursor', 'pointer');
  26937. }
  26938. });
  26939. var NoteIconRenderer = kity.createClass('NoteIconRenderer', {
  26940. base: KityMinder.Renderer,
  26941. create: function(node) {
  26942. var icon = new NoteIcon();
  26943. icon.on('mousedown', function(e) {
  26944. e.preventDefault();
  26945. node.getMinder().fire('editnoterequest');
  26946. });
  26947. icon.on('mouseover', function() {
  26948. node.getMinder().fire('shownoterequest', {node: node, icon: icon});
  26949. });
  26950. icon.on('mouseout', function() {
  26951. node.getMinder().fire('hidenoterequest', {node: node, icon: icon});
  26952. });
  26953. return icon;
  26954. },
  26955. shouldRender: function(node) {
  26956. return node.getData('note');
  26957. },
  26958. update: function(icon, node, box) {
  26959. var x = box.right + node.getStyle('space-left');
  26960. var y = box.cy;
  26961. icon.path.fill(node.getStyle('color'));
  26962. icon.setTranslate(x, y);
  26963. return new kity.Box(x, Math.round(y - icon.height / 2), icon.width, icon.height);
  26964. }
  26965. });
  26966. return {
  26967. renderers: {
  26968. right: NoteIconRenderer
  26969. },
  26970. commands: {
  26971. 'note': NoteCommand
  26972. }
  26973. };
  26974. });
  26975. var ViewDragger = kity.createClass("ViewDragger", {
  26976. constructor: function(minder) {
  26977. this._minder = minder;
  26978. this._enabled = false;
  26979. this._bind();
  26980. var me = this;
  26981. this._minder.getViewDragger = function() {
  26982. return me;
  26983. };
  26984. },
  26985. isEnabled: function() {
  26986. return this._enabled;
  26987. },
  26988. setEnabled: function(value) {
  26989. var paper = this._minder.getPaper();
  26990. paper.setStyle('cursor', value ? 'pointer' : 'default');
  26991. paper.setStyle('cursor', value ? '-webkit-grab' : 'default');
  26992. this._enabled = value;
  26993. },
  26994. move: function(offset, duration) {
  26995. var minder = this._minder;
  26996. var targetPosition = this.getMovement().offset(offset);
  26997. this.moveTo(targetPosition, duration);
  26998. },
  26999. moveTo: function(position, duration) {
  27000. if (duration) {
  27001. var dragger = this;
  27002. if (this._moveTimeline) this._moveTimeline.stop();
  27003. this._moveTimeline = this._minder.getRenderContainer().animate(new kity.Animator(
  27004. this.getMovement(),
  27005. position,
  27006. function(target, value) {
  27007. dragger.moveTo(value);
  27008. }
  27009. ), duration, 'easeOutCubic');
  27010. this._moveTimeline.on('finish', function() {
  27011. dragger._moveTimeline = null;
  27012. });
  27013. return this;
  27014. }
  27015. this._minder.getRenderContainer().setTranslate(position.round());
  27016. this._minder.fire('viewchange');
  27017. },
  27018. getMovement: function() {
  27019. var translate = this._minder.getRenderContainer().transform.translate;
  27020. return translate ? translate[0] : new kity.Point();
  27021. },
  27022. getView: function() {
  27023. var minder = this._minder;
  27024. var c = {
  27025. width: minder.getRenderTarget().clientWidth,
  27026. height: minder.getRenderTarget().clientHeight
  27027. };
  27028. var m = this.getMovement();
  27029. var box = new kity.Box(0, 0, c.width, c.height);
  27030. var viewMatrix = minder.getPaper().getViewPortMatrix();
  27031. return viewMatrix.inverse().translate(-m.x, -m.y).transformBox(box);
  27032. },
  27033. _bind: function() {
  27034. var dragger = this,
  27035. isTempDrag = false,
  27036. lastPosition = null,
  27037. currentPosition = null;
  27038. function dragEnd(e) {
  27039. if (!lastPosition) return;
  27040. lastPosition = null;
  27041. e.stopPropagation();
  27042. // 临时拖动需要还原状态
  27043. if (isTempDrag) {
  27044. dragger.setEnabled(false);
  27045. isTempDrag = false;
  27046. if (dragger._minder.getStatus() == 'hand')
  27047. dragger._minder.rollbackStatus();
  27048. }
  27049. var paper = dragger._minder.getPaper();
  27050. paper.setStyle('cursor', dragger._minder.getStatus() == 'hand' ? '-webkit-grab' : 'default');
  27051. }
  27052. this._minder.on('normal.mousedown normal.touchstart ' +
  27053. 'inputready.mousedown inputready.touchstart ' +
  27054. 'readonly.mousedown readonly.touchstart', function(e) {
  27055. if (e.originEvent.button == 2) {
  27056. e.originEvent.preventDefault(); // 阻止中键拉动
  27057. }
  27058. // 点击未选中的根节点临时开启
  27059. if (e.getTargetNode() == this.getRoot() || e.originEvent.button == 2 || e.originEvent.altKey) {
  27060. lastPosition = e.getPosition();
  27061. isTempDrag = true;
  27062. }
  27063. })
  27064. .on('normal.mousemove normal.touchmove ' +
  27065. 'readonly.mousemove readonly.touchmove ' +
  27066. 'inputready.mousemove inputready.touchmove', function(e) {
  27067. if (e.type == 'touchmove') {
  27068. e.preventDefault(); // 阻止浏览器的后退事件
  27069. }
  27070. if (!isTempDrag) return;
  27071. var offset = kity.Vector.fromPoints(lastPosition, e.getPosition());
  27072. if (offset.length() > 10) {
  27073. this.setStatus('hand', true);
  27074. var paper = dragger._minder.getPaper();
  27075. paper.setStyle('cursor', '-webkit-grabbing');
  27076. }
  27077. })
  27078. .on('hand.beforemousedown hand.beforetouchstart', function(e) {
  27079. // 已经被用户打开拖放模式
  27080. if (dragger.isEnabled()) {
  27081. lastPosition = e.getPosition();
  27082. e.stopPropagation();
  27083. var paper = dragger._minder.getPaper();
  27084. paper.setStyle('cursor', '-webkit-grabbing');
  27085. }
  27086. })
  27087. .on('hand.beforemousemove hand.beforetouchmove', function(e) {
  27088. if (lastPosition) {
  27089. currentPosition = e.getPosition();
  27090. // 当前偏移加上历史偏移
  27091. var offset = kity.Vector.fromPoints(lastPosition, currentPosition);
  27092. dragger.move(offset);
  27093. e.stopPropagation();
  27094. e.preventDefault();
  27095. e.originEvent.preventDefault();
  27096. lastPosition = currentPosition;
  27097. }
  27098. })
  27099. .on('mouseup touchend', dragEnd);
  27100. window.addEventListener('mouseup', dragEnd);
  27101. this._minder.on('contextmenu', function(e) {
  27102. e.preventDefault();
  27103. });
  27104. }
  27105. });
  27106. KityMinder.registerModule('View', function() {
  27107. var km = this;
  27108. var ToggleHandCommand = kity.createClass('ToggleHandCommand', {
  27109. base: Command,
  27110. execute: function(minder) {
  27111. if (minder.getStatus() != 'hand') {
  27112. minder.setStatus('hand', true);
  27113. } else {
  27114. minder.rollbackStatus();
  27115. }
  27116. this.setContentChanged(false);
  27117. },
  27118. queryState: function(minder) {
  27119. return minder.getStatus() == 'hand' ? 1 : 0;
  27120. },
  27121. enableReadOnly: true
  27122. });
  27123. var CameraCommand = kity.createClass('CameraCommand', {
  27124. base: Command,
  27125. execute: function(km, focusNode, duration) {
  27126. focusNode = focusNode || km.getRoot();
  27127. var viewport = km.getPaper().getViewPort();
  27128. var offset = focusNode.getRenderContainer().getRenderBox('view');
  27129. var dx = viewport.center.x - offset.x - offset.width / 2,
  27130. dy = viewport.center.y - offset.y;
  27131. var dragger = km._viewDragger;
  27132. dragger.move(new kity.Point(dx, dy), duration);
  27133. this.setContentChanged(false);
  27134. },
  27135. enableReadOnly: true
  27136. });
  27137. var MoveCommand = kity.createClass('MoveCommand', {
  27138. base: Command,
  27139. execute: function(km, dir, duration) {
  27140. var dragger = km._viewDragger;
  27141. var size = km._lastClientSize;
  27142. switch (dir) {
  27143. case 'up':
  27144. dragger.move(new kity.Point(0, size.height / 2), duration);
  27145. break;
  27146. case 'down':
  27147. dragger.move(new kity.Point(0, -size.height / 2), duration);
  27148. break;
  27149. case 'left':
  27150. dragger.move(new kity.Point(size.width / 2, 0), duration);
  27151. break;
  27152. case 'right':
  27153. dragger.move(new kity.Point(-size.width / 2, 0), duration);
  27154. break;
  27155. }
  27156. },
  27157. enableReadOnly: true
  27158. });
  27159. return {
  27160. init: function() {
  27161. this._viewDragger = new ViewDragger(this);
  27162. },
  27163. commands: {
  27164. 'hand': ToggleHandCommand,
  27165. 'camera': CameraCommand,
  27166. 'move': MoveCommand
  27167. },
  27168. events: {
  27169. keydown: function(e) {
  27170. var minder = this;
  27171. ['up', 'down', 'left', 'right'].forEach(function(name) {
  27172. if (e.isShortcutKey('ctrl+' + name) && minder.getStatus() != 'textedit') {
  27173. minder.removeAllSelectedNodes();
  27174. minder.execCommand('move', name, 100);
  27175. e.preventDefault();
  27176. }
  27177. });
  27178. if (e.isShortcutKey('ctrl+enter')) {
  27179. minder.execCommand('camera', minder.getRoot(), 100);
  27180. }
  27181. },
  27182. statuschange: function(e) {
  27183. this._viewDragger.setEnabled(e.currentStatus == 'hand');
  27184. },
  27185. mousewheel: function(e) {
  27186. var dx, dy;
  27187. e = e.originEvent;
  27188. if (e.ctrlKey || e.shiftKey) return;
  27189. if ('wheelDeltaX' in e) {
  27190. dx = e.wheelDeltaX || 0;
  27191. dy = e.wheelDeltaY || 0;
  27192. } else {
  27193. dx = 0;
  27194. dy = e.wheelDelta;
  27195. }
  27196. this._viewDragger.move({
  27197. x: dx / 2.5,
  27198. y: dy / 2.5
  27199. });
  27200. e.preventDefault();
  27201. },
  27202. 'normal.dblclick readonly.dblclick': function(e) {
  27203. if (e.kityEvent.targetShape instanceof kity.Paper) {
  27204. this.execCommand('camera', this.getRoot(), 800);
  27205. }
  27206. },
  27207. ready: function() {
  27208. this.execCommand('camera', null, 0);
  27209. this._lastClientSize = {
  27210. width: this.getRenderTarget().clientWidth,
  27211. height: this.getRenderTarget().clientHeight
  27212. };
  27213. },
  27214. resize: function(e) {
  27215. var a = {
  27216. width: this.getRenderTarget().clientWidth,
  27217. height: this.getRenderTarget().clientHeight
  27218. },
  27219. b = this._lastClientSize;
  27220. this._viewDragger.move(
  27221. new kity.Point((a.width - b.width) / 2 | 0, (a.height - b.height) / 2 | 0));
  27222. this._lastClientSize = a;
  27223. },
  27224. 'selectionchange layoutallfinish': function(e) {
  27225. var selected = this.getSelectedNode();
  27226. if (!selected) return;
  27227. var dragger = this._viewDragger;
  27228. var view = dragger.getView();
  27229. var focus = selected.getLayoutBox();
  27230. var space = 50;
  27231. var dx = 0, dy = 0;
  27232. if (focus.right > view.right) {
  27233. dx += view.right - focus.right - space;
  27234. }
  27235. else if (focus.left < view.left) {
  27236. dx += view.left - focus.left + space;
  27237. }
  27238. if (focus.bottom > view.bottom) {
  27239. dy += view.bottom - focus.bottom - space;
  27240. }
  27241. if (focus.top < view.top) {
  27242. dy += view.top - focus.top + space;
  27243. }
  27244. if (dx || dy) dragger.move(new kity.Point(dx, dy), 100);
  27245. }
  27246. }
  27247. };
  27248. });
  27249. var GM = KityMinder.Geometry;
  27250. // 矩形的变形动画定义
  27251. var MoveToParentCommand = kity.createClass('MoveToParentCommand', {
  27252. base: Command,
  27253. execute: function(minder, nodes, parent) {
  27254. var node;
  27255. for (var i = nodes.length - 1; i >= 0; i--) {
  27256. node = nodes[i];
  27257. if (node.parent) {
  27258. node.parent.removeChild(node);
  27259. parent.appendChild(node);
  27260. node.render();
  27261. }
  27262. }
  27263. parent.expand();
  27264. minder.select(nodes, true);
  27265. }
  27266. });
  27267. var DropHinter = kity.createClass('DropHinter', {
  27268. base: kity.Group,
  27269. constructor: function() {
  27270. this.callBase();
  27271. this.rect = new kity.Rect();
  27272. this.addShape(this.rect);
  27273. },
  27274. render: function(target) {
  27275. this.setVisible(!!target);
  27276. if (target) {
  27277. this.rect
  27278. .setBox(target.getLayoutBox())
  27279. .setRadius(target.getStyle('radius') || 0)
  27280. .stroke(
  27281. target.getStyle('drop-hint-color') || 'yellow',
  27282. target.getStyle('drop-hint-width') || 2
  27283. );
  27284. this.bringTop();
  27285. }
  27286. }
  27287. });
  27288. var OrderHinter = kity.createClass('OrderHinter', {
  27289. base: kity.Group,
  27290. constructor: function() {
  27291. this.callBase();
  27292. this.area = new kity.Rect();
  27293. this.path = new kity.Path();
  27294. this.addShapes([this.area, this.path]);
  27295. },
  27296. render: function(hint) {
  27297. this.setVisible(!!hint);
  27298. if (hint) {
  27299. this.area.setBox(hint.area);
  27300. this.area.fill(hint.node.getStyle('order-hint-area-color') || 'rgba(0, 255, 0, .5)');
  27301. this.path.setPathData(hint.path);
  27302. this.path.stroke(
  27303. hint.node.getStyle('order-hint-path-color') || '#0f0',
  27304. hint.node.getStyle('order-hint-path-width') || 1);
  27305. }
  27306. }
  27307. });
  27308. // 对拖动对象的一个替代盒子,控制整个拖放的逻辑,包括:
  27309. // 1. 从节点列表计算出拖动部分
  27310. // 2. 计算可以 drop 的节点,产生 drop 交互提示
  27311. var TreeDragger = kity.createClass('TreeDragger', {
  27312. constructor: function(minder) {
  27313. this._minder = minder;
  27314. this._dropHinter = new DropHinter();
  27315. this._orderHinter = new OrderHinter();
  27316. minder.getRenderContainer().addShapes([this._dropHinter, this._orderHinter]);
  27317. },
  27318. dragStart: function(position) {
  27319. // 只记录开始位置,不马上开启拖放模式
  27320. // 这个位置同时是拖放范围收缩时的焦点位置(中心)
  27321. this._startPosition = position;
  27322. },
  27323. dragMove: function(position) {
  27324. // 启动拖放模式需要最小的移动距离
  27325. var DRAG_MOVE_THRESHOLD = 10;
  27326. if (!this._startPosition) return;
  27327. var movement = kity.Vector.fromPoints(this._dragPosition || this._startPosition, position);
  27328. var minder = this._minder;
  27329. this._dragPosition = position;
  27330. if (!this._dragMode) {
  27331. // 判断拖放模式是否该启动
  27332. if (GM.getDistance(this._dragPosition, this._startPosition) < DRAG_MOVE_THRESHOLD) {
  27333. return;
  27334. }
  27335. if (!this._enterDragMode()) {
  27336. return;
  27337. }
  27338. }
  27339. for (var i = 0; i < this._dragSources.length; i++) {
  27340. this._dragSources[i].setLayoutOffset(this._dragSources[i].getLayoutOffset().offset(movement));
  27341. minder.applyLayoutResult(this._dragSources[i]);
  27342. }
  27343. if (!this._dropTest()) {
  27344. this._orderTest();
  27345. } else {
  27346. this._renderOrderHint(this._orderSucceedHint = null);
  27347. }
  27348. },
  27349. dragEnd: function() {
  27350. this._startPosition = null;
  27351. this._dragPosition = null;
  27352. if (!this._dragMode) {
  27353. return;
  27354. }
  27355. this._fadeDragSources(1);
  27356. if (this._dropSucceedTarget) {
  27357. this._dragSources.forEach(function(source) {
  27358. source.setLayoutOffset(null);
  27359. });
  27360. this._minder.layout(-1);
  27361. this._minder.execCommand('movetoparent', this._dragSources, this._dropSucceedTarget);
  27362. } else if (this._orderSucceedHint) {
  27363. var hint = this._orderSucceedHint;
  27364. var index = hint.node.getIndex();
  27365. var sourceIndexes = this._dragSources.map(function(source) {
  27366. // 顺便干掉布局偏移
  27367. source.setLayoutOffset(null);
  27368. return source.getIndex();
  27369. });
  27370. var maxIndex = Math.max.apply(Math, sourceIndexes);
  27371. var minIndex = Math.min.apply(Math, sourceIndexes);
  27372. if (index < minIndex && hint.type == 'down') index++;
  27373. if (index > maxIndex && hint.type == 'up') index--;
  27374. hint.node.setLayoutOffset(null);
  27375. this._minder.execCommand('arrange', this._dragSources, index);
  27376. this._renderOrderHint(null);
  27377. } else {
  27378. this._minder.fire('savescene');
  27379. }
  27380. this._minder.layout(300);
  27381. this._leaveDragMode();
  27382. this._minder.fire('contentchange');
  27383. },
  27384. // 进入拖放模式:
  27385. // 1. 计算拖放源和允许的拖放目标
  27386. // 2. 标记已启动
  27387. _enterDragMode: function() {
  27388. this._calcDragSources();
  27389. if (!this._dragSources.length) {
  27390. this._startPosition = null;
  27391. return false;
  27392. }
  27393. this._fadeDragSources(0.5);
  27394. this._calcDropTargets();
  27395. this._calcOrderHints();
  27396. this._dragMode = true;
  27397. this._minder.setStatus('dragtree');
  27398. return true;
  27399. },
  27400. // 从选中的节点计算拖放源
  27401. // 并不是所有选中的节点都作为拖放源,如果选中节点中存在 A 和 B,
  27402. // 并且 A 是 B 的祖先,则 B 不作为拖放源
  27403. //
  27404. // 计算过程:
  27405. // 1. 将节点按照树高排序,排序后只可能是前面节点是后面节点的祖先
  27406. // 2. 从后往前枚举排序的结果,如果发现枚举目标之前存在其祖先,
  27407. // 则排除枚举目标作为拖放源,否则加入拖放源
  27408. _calcDragSources: function() {
  27409. this._dragSources = this._minder.getSelectedAncestors();
  27410. },
  27411. _fadeDragSources: function(opacity) {
  27412. var minder = this._minder;
  27413. this._dragSources.forEach(function(source) {
  27414. source.getRenderContainer().setOpacity(opacity, 200);
  27415. source.traverse(function(node) {
  27416. if (opacity < 1) {
  27417. minder.detachNode(node);
  27418. } else {
  27419. minder.attachNode(node);
  27420. }
  27421. }, true);
  27422. });
  27423. },
  27424. // 计算拖放目标可以释放的节点列表(释放意味着成为其子树),存在这条限制规则:
  27425. // - 不能拖放到拖放目标的子树上(允许拖放到自身,因为多选的情况下可以把其它节点加入)
  27426. //
  27427. // 1. 加入当前节点(初始为根节点)到允许列表
  27428. // 2. 对于当前节点的每一个子节点:
  27429. // (1) 如果是拖放目标的其中一个节点,忽略(整棵子树被剪枝)
  27430. // (2) 如果不是拖放目标之一,以当前子节点为当前节点,回到 1 计算
  27431. // 3. 返回允许列表
  27432. //
  27433. _calcDropTargets: function() {
  27434. function findAvailableParents(nodes, root) {
  27435. var availables = [],
  27436. i;
  27437. availables.push(root);
  27438. root.getChildren().forEach(function(test) {
  27439. for (i = 0; i < nodes.length; i++) {
  27440. if (nodes[i] == test) return;
  27441. }
  27442. availables = availables.concat(findAvailableParents(nodes, test));
  27443. });
  27444. return availables;
  27445. }
  27446. this._dropTargets = findAvailableParents(this._dragSources, this._minder.getRoot());
  27447. this._dropTargetBoxes = this._dropTargets.map(function(source) {
  27448. return source.getLayoutBox();
  27449. });
  27450. },
  27451. _calcOrderHints: function() {
  27452. var sources = this._dragSources;
  27453. var ancestor = MinderNode.getCommonAncestor(sources);
  27454. // 只有一个元素选中,公共祖先是其父
  27455. if (ancestor == sources[0]) ancestor = sources[0].parent;
  27456. if (sources.length === 0 || ancestor != sources[0].parent) {
  27457. this._orderHints = [];
  27458. return;
  27459. }
  27460. var siblings = ancestor.children;
  27461. this._orderHints = siblings.reduce(function(hint, sibling) {
  27462. if (sources.indexOf(sibling) == -1) {
  27463. hint = hint.concat(sibling.getOrderHint());
  27464. }
  27465. return hint;
  27466. }, []);
  27467. },
  27468. _leaveDragMode: function() {
  27469. this._dragMode = false;
  27470. this._dropSucceedTarget = null;
  27471. this._orderSucceedHint = null;
  27472. this._renderDropHint(null);
  27473. this._renderOrderHint(null);
  27474. this._minder.rollbackStatus();
  27475. },
  27476. _drawForDragMode: function() {
  27477. this._text.setContent(this._dragSources.length + ' items');
  27478. this._text.setPosition(this._startPosition.x, this._startPosition.y + 5);
  27479. this._minder.getRenderContainer().addShape(this);
  27480. },
  27481. _boxTest: function(targets, targetBoxMapper, judge) {
  27482. var sourceBoxes = this._dragSources.map(function(source) {
  27483. return source.getLayoutBox();
  27484. });
  27485. var i, j, target, sourceBox, targetBox;
  27486. judge = judge || function(intersectBox, sourceBox, targetBox) {
  27487. return intersectBox;
  27488. };
  27489. for (i = 0; i < targets.length; i++) {
  27490. target = targets[i];
  27491. targetBox = targetBoxMapper.call(this, target, i);
  27492. for (j = 0; j < sourceBoxes.length; j++) {
  27493. sourceBox = sourceBoxes[j];
  27494. var intersectBox = GM.getIntersectBox(sourceBox, targetBox);
  27495. if (judge(intersectBox, sourceBox, targetBox)) {
  27496. return target;
  27497. }
  27498. }
  27499. }
  27500. return null;
  27501. },
  27502. _dropTest: function() {
  27503. this._dropSucceedTarget = this._boxTest(this._dropTargets, function(target, i) {
  27504. return this._dropTargetBoxes[i];
  27505. }, function(intersectBox, sourceBox, targetBox) {
  27506. function area(box) {
  27507. return box.width * box.height;
  27508. }
  27509. if (!intersectBox) return false;
  27510. // 面积判断
  27511. if (area(intersectBox) > 0.5 * Math.min(area(sourceBox), area(targetBox))) return true;
  27512. if (intersectBox.width + 1 >= Math.min(sourceBox.width, targetBox.width)) return true;
  27513. if (intersectBox.height + 1 >= Math.min(sourceBox.height, targetBox.height)) return true;
  27514. return false;
  27515. });
  27516. this._renderDropHint(this._dropSucceedTarget);
  27517. return !!this._dropSucceedTarget;
  27518. },
  27519. _orderTest: function() {
  27520. this._orderSucceedHint = this._boxTest(this._orderHints, function(hint) {
  27521. return hint.area;
  27522. });
  27523. this._renderOrderHint(this._orderSucceedHint);
  27524. return !!this._orderSucceedHint;
  27525. },
  27526. _renderDropHint: function(target) {
  27527. this._dropHinter.render(target);
  27528. },
  27529. _renderOrderHint: function(hint) {
  27530. this._orderHinter.render(hint);
  27531. },
  27532. preventDragMove: function() {
  27533. this._startPosition = null;
  27534. }
  27535. });
  27536. KityMinder.registerModule('DragTree', function() {
  27537. var dragger;
  27538. return {
  27539. init: function() {
  27540. dragger = new TreeDragger(this);
  27541. window.addEventListener('mouseup', function() {
  27542. dragger.dragEnd();
  27543. });
  27544. },
  27545. events: {
  27546. 'normal.mousedown inputready.mousedown': function(e) {
  27547. // 单选中根节点也不触发拖拽
  27548. if (e.originEvent.button) return;
  27549. if (e.getTargetNode() && e.getTargetNode() != this.getRoot()) {
  27550. dragger.dragStart(e.getPosition(this.getRenderContainer()));
  27551. }
  27552. },
  27553. 'normal.mousemove dragtree.mousemove': function(e) {
  27554. dragger.dragMove(e.getPosition(this.getRenderContainer()));
  27555. },
  27556. 'normal.mouseup dragtree.beforemouseup': function(e) {
  27557. dragger.dragEnd();
  27558. //e.stopPropagation();
  27559. e.preventDefault();
  27560. },
  27561. 'statuschange': function(e) {
  27562. if (e.lastStatus == 'textedit' && e.currentStatus == 'normal') {
  27563. dragger.preventDragMove();
  27564. }
  27565. }
  27566. },
  27567. commands: {
  27568. 'movetoparent': MoveToParentCommand
  27569. }
  27570. };
  27571. });
  27572. KityMinder.registerModule('KeyboardModule', function() {
  27573. var min = Math.min,
  27574. max = Math.max,
  27575. abs = Math.abs,
  27576. sqrt = Math.sqrt,
  27577. exp = Math.exp;
  27578. function buildPositionNetwork(root) {
  27579. var pointIndexes = [],
  27580. p;
  27581. root.traverse(function(node) {
  27582. p = node.getLayoutBox();
  27583. // bugfix: 不应导航到收起的节点(判断其尺寸是否存在)
  27584. if (p.width && p.height) {
  27585. pointIndexes.push({
  27586. left: p.x,
  27587. top: p.y,
  27588. right: p.x + p.width,
  27589. bottom: p.y + p.height,
  27590. width: p.width,
  27591. height: p.height,
  27592. node: node,
  27593. text: node.getText()
  27594. });
  27595. }
  27596. });
  27597. for (var i = 0; i < pointIndexes.length; i++) {
  27598. findClosestPointsFor(pointIndexes, i);
  27599. }
  27600. }
  27601. // 这是金泉的点子,赞!
  27602. // 求两个不相交矩形的最近距离
  27603. function getCoefedDistance(box1, box2) {
  27604. var xMin, xMax, yMin, yMax, xDist, yDist, dist, cx, cy;
  27605. xMin = min(box1.left, box2.left);
  27606. xMax = max(box1.right, box2.right);
  27607. yMin = min(box1.top, box2.top);
  27608. yMax = max(box1.bottom, box2.bottom);
  27609. xDist = xMax - xMin - box1.width - box2.width;
  27610. yDist = yMax - yMin - box1.height - box2.height;
  27611. if (xDist < 0) dist = yDist;
  27612. else if (yDist < 0) dist = xDist;
  27613. else dist = sqrt(xDist * xDist + yDist * yDist);
  27614. return {
  27615. cx: dist,
  27616. cy: dist
  27617. };
  27618. }
  27619. function findClosestPointsFor(pointIndexes, iFind) {
  27620. var find = pointIndexes[iFind];
  27621. var most = {},
  27622. quad;
  27623. var current, dist;
  27624. for (var i = 0; i < pointIndexes.length; i++) {
  27625. if (i == iFind) continue;
  27626. current = pointIndexes[i];
  27627. dist = getCoefedDistance(current, find);
  27628. // left check
  27629. if (current.right < find.left) {
  27630. if (!most.left || dist.cx < most.left.dist) {
  27631. most.left = {
  27632. dist: dist.cx,
  27633. node: current.node
  27634. };
  27635. }
  27636. }
  27637. // right check
  27638. if (current.left > find.right) {
  27639. if (!most.right || dist.cx < most.right.dist) {
  27640. most.right = {
  27641. dist: dist.cx,
  27642. node: current.node
  27643. };
  27644. }
  27645. }
  27646. // top check
  27647. if (current.bottom < find.top) {
  27648. if (!most.top || dist.cy < most.top.dist) {
  27649. most.top = {
  27650. dist: dist.cy,
  27651. node: current.node
  27652. };
  27653. }
  27654. }
  27655. // bottom check
  27656. if (current.top > find.bottom) {
  27657. if (!most.down || dist.cy < most.down.dist) {
  27658. most.down = {
  27659. dist: dist.cy,
  27660. node: current.node
  27661. };
  27662. }
  27663. }
  27664. }
  27665. find.node._nearestNodes = {
  27666. right: most.right && most.right.node || null,
  27667. top: most.top && most.top.node || null,
  27668. left: most.left && most.left.node || null,
  27669. down: most.down && most.down.node || null
  27670. };
  27671. }
  27672. function navigateTo(km, direction) {
  27673. var referNode = km.getSelectedNode();
  27674. if (!referNode) {
  27675. km.select(km.getRoot());
  27676. buildPositionNetwork(km.getRoot());
  27677. return;
  27678. }
  27679. if (!referNode._nearestNodes) {
  27680. buildPositionNetwork(km.getRoot());
  27681. }
  27682. var nextNode = referNode._nearestNodes[direction];
  27683. if (nextNode) {
  27684. km.select(nextNode, true);
  27685. }
  27686. }
  27687. var NavigateToParentCommand = kity.createClass({
  27688. base: Command,
  27689. execute: function(km) {
  27690. var node = km.getSelectedNode();
  27691. if (node && node.parent) {
  27692. km.select(node.parent, true);
  27693. }
  27694. this.setContentChanged(false);
  27695. },
  27696. queryState: function(km) {
  27697. return km.getSelectedNode() ? 0 : -1;
  27698. },
  27699. enableReadOnly: true
  27700. });
  27701. // 稀释用
  27702. var lastFrame;
  27703. return {
  27704. 'commands': {
  27705. 'navparent': NavigateToParentCommand
  27706. },
  27707. 'commandShortcutKeys': {
  27708. 'navparent': 'shift+tab'
  27709. },
  27710. 'events': {
  27711. 'layoutallfinish': function() {
  27712. var root = this.getRoot();
  27713. buildPositionNetwork(root);
  27714. },
  27715. 'normal.keydown readonly.keydown': function(e) {
  27716. var minder = this;
  27717. ['left', 'right', 'up', 'down'].forEach(function(key) {
  27718. if (e.isShortcutKey(key)) {
  27719. navigateTo(minder, key == 'up' ? 'top' : key);
  27720. }
  27721. });
  27722. },
  27723. 'normal.keyup': function(e) {
  27724. if (browser.ipad) {
  27725. var keys = KityMinder.keymap;
  27726. var node = e.getTargetNode();
  27727. var lang = this.getLang();
  27728. if (this.receiver) this.receiver.keydownNode = node;
  27729. var keyEvent = e.originEvent;
  27730. if (keyEvent.altKey || keyEvent.ctrlKey || keyEvent.metaKey || keyEvent.shiftKey) return;
  27731. switch (keyEvent.keyCode) {
  27732. case keys.Enter:
  27733. this.execCommand('AppendSiblingNode', lang.topic);
  27734. e.preventDefault();
  27735. break;
  27736. case keys.Backspace:
  27737. case keys.Del:
  27738. e.preventDefault();
  27739. this.execCommand('RemoveNode');
  27740. break;
  27741. }
  27742. }
  27743. }
  27744. }
  27745. };
  27746. });
  27747. KityMinder.registerModule('Select', function() {
  27748. var minder = this;
  27749. var rc = minder.getRenderContainer();
  27750. var g = KityMinder.Geometry;
  27751. // 在实例上渲染框选矩形、计算框选范围的对象
  27752. var marqueeActivator = (function() {
  27753. // 记录选区的开始位置(mousedown的位置)
  27754. var startPosition = null;
  27755. // 选区的图形
  27756. var marqueeShape = new kity.Path();
  27757. // 标记是否已经启动框选状态
  27758. // 并不是 mousedown 发生之后就启动框选状态,而是检测到移动了一定的距离(MARQUEE_MODE_THRESHOLD)之后
  27759. var marqueeMode = false;
  27760. var MARQUEE_MODE_THRESHOLD = 10;
  27761. return {
  27762. selectStart: function(e) {
  27763. // 只接受左键
  27764. if (e.originEvent.button || e.originEvent.altKey) return;
  27765. // 清理不正确状态
  27766. if (startPosition) {
  27767. return this.selectEnd();
  27768. }
  27769. startPosition = g.snapToSharp(e.getPosition(rc));
  27770. },
  27771. selectMove: function(e) {
  27772. if (minder.getStatus() == 'textedit') {
  27773. return;
  27774. }
  27775. if (!startPosition) return;
  27776. var p1 = startPosition,
  27777. p2 = e.getPosition(rc);
  27778. // 检测是否要进入选区模式
  27779. if (!marqueeMode) {
  27780. // 距离没达到阈值,退出
  27781. if (g.getDistance(p1, p2) < MARQUEE_MODE_THRESHOLD) {
  27782. return;
  27783. }
  27784. // 已经达到阈值,记录下来并且重置选区形状
  27785. marqueeMode = true;
  27786. rc.addShape(marqueeShape);
  27787. marqueeShape
  27788. .fill(minder.getStyle('marquee-background'))
  27789. .stroke(minder.getStyle('marquee-stroke')).setOpacity(0.8).getDrawer().clear();
  27790. }
  27791. var marquee = g.getBox(p1, p2),
  27792. selectedNodes = [];
  27793. // 使其犀利
  27794. marquee.left = Math.round(marquee.left);
  27795. marquee.top = Math.round(marquee.top);
  27796. marquee.right = Math.round(marquee.right);
  27797. marquee.bottom = Math.round(marquee.bottom);
  27798. // 选区形状更新
  27799. marqueeShape.getDrawer().pipe(function() {
  27800. this.clear();
  27801. this.moveTo(marquee.left, marquee.top);
  27802. this.lineTo(marquee.right, marquee.top);
  27803. this.lineTo(marquee.right, marquee.bottom);
  27804. this.lineTo(marquee.left, marquee.bottom);
  27805. this.close();
  27806. });
  27807. // 计算选中范围
  27808. minder.getRoot().traverse(function(node) {
  27809. var renderBox = node.getLayoutBox();
  27810. if (g.getIntersectBox(renderBox, marquee)) {
  27811. selectedNodes.push(node);
  27812. }
  27813. });
  27814. // 应用选中范围
  27815. minder.select(selectedNodes, true);
  27816. // 清除多余的东西
  27817. window.getSelection().removeAllRanges();
  27818. },
  27819. selectEnd: function(e) {
  27820. if (startPosition) {
  27821. startPosition = null;
  27822. }
  27823. if (marqueeMode) {
  27824. marqueeShape.fadeOut(200, 'ease', 0, function() {
  27825. if (marqueeShape.remove) marqueeShape.remove();
  27826. });
  27827. marqueeMode = false;
  27828. }
  27829. }
  27830. };
  27831. })();
  27832. var lastDownNode = null, lastDownPosition = null;
  27833. return {
  27834. 'init': function() {
  27835. window.addEventListener('mouseup', function() {
  27836. marqueeActivator.selectEnd();
  27837. });
  27838. },
  27839. 'events': {
  27840. 'mousedown': function(e) {
  27841. var downNode = e.getTargetNode();
  27842. // 没有点中节点:
  27843. // 清除选中状态,并且标记选区开始位置
  27844. if (!downNode) {
  27845. this.removeAllSelectedNodes();
  27846. marqueeActivator.selectStart(e);
  27847. this.setStatus('normal');
  27848. }
  27849. // 点中了节点,并且按了 shift 键:
  27850. // 被点中的节点切换选中状态
  27851. else if (e.originEvent.shiftKey) {
  27852. this.toggleSelect(downNode);
  27853. }
  27854. // 点中的节点没有被选择:
  27855. // 单选点中的节点
  27856. else if (!downNode.isSelected()) {
  27857. this.select(downNode, true);
  27858. }
  27859. // 点中的节点被选中了,并且不是单选:
  27860. // 完成整个点击之后需要使其变为单选。
  27861. // 不能马上变为单选,因为可能是需要拖动选中的多个节点
  27862. else if (!this.isSingleSelect()) {
  27863. lastDownNode = downNode;
  27864. lastDownPosition = e.getPosition(this.getRenderContainer());
  27865. }
  27866. },
  27867. 'mousemove': marqueeActivator.selectMove,
  27868. 'mouseup': function(e) {
  27869. var upNode = e.getTargetNode();
  27870. // 如果 mouseup 发生在 lastDownNode 外,是无需理会的
  27871. if (upNode && upNode == lastDownNode) {
  27872. var upPosition = e.getPosition(this.getRenderContainer());
  27873. var movement = kity.Vector.fromPoints(lastDownPosition, upPosition);
  27874. if (movement.length() < 1) this.select(lastDownNode, true);
  27875. lastDownNode = null;
  27876. }
  27877. // 清理一下选择状态
  27878. marqueeActivator.selectEnd(e);
  27879. },
  27880. //全选操作
  27881. 'normal.keydown inputready.keydown':function(e){
  27882. if ( e.isShortcutKey('ctrl+a') ){
  27883. var selectedNodes = [];
  27884. this.getRoot().traverse(function(node){
  27885. selectedNodes.push(node);
  27886. });
  27887. this.select(selectedNodes,true);
  27888. e.preventDefault();
  27889. }
  27890. }
  27891. }
  27892. };
  27893. });
  27894. KityMinder.registerModule('basestylemodule', function() {
  27895. var km = this;
  27896. function getNodeDataOrStyle(node, name) {
  27897. return node.getData(name) || node.getStyle(name);
  27898. }
  27899. KityMinder.TextRenderer.registerStyleHook(function(node, textGroup) {
  27900. var fontWeight = getNodeDataOrStyle(node,'font-weight');
  27901. var fontStyle = getNodeDataOrStyle(node, 'font-style');
  27902. var styleHash = [fontWeight, fontStyle].join('/');
  27903. textGroup.eachItem(function(index,item){
  27904. item.setFont({
  27905. 'weight': fontWeight,
  27906. 'style': fontStyle
  27907. });
  27908. });
  27909. });
  27910. return {
  27911. 'commands': {
  27912. 'bold': kity.createClass('boldCommand', {
  27913. base: Command,
  27914. execute: function(km) {
  27915. var nodes = km.getSelectedNodes();
  27916. if (this.queryState('bold') == 1) {
  27917. utils.each(nodes, function(i, n) {
  27918. n.setData('font-weight').render();
  27919. });
  27920. } else {
  27921. utils.each(nodes, function(i, n) {
  27922. n.setData('font-weight', 'bold').render();
  27923. });
  27924. }
  27925. km.layout();
  27926. },
  27927. queryState: function() {
  27928. var nodes = km.getSelectedNodes(),
  27929. result = 0;
  27930. if (nodes.length === 0) {
  27931. return -1;
  27932. }
  27933. utils.each(nodes, function(i, n) {
  27934. if (n && n.getData('font-weight')) {
  27935. result = 1;
  27936. return false;
  27937. }
  27938. });
  27939. return result;
  27940. }
  27941. }),
  27942. 'italic': kity.createClass('italicCommand', {
  27943. base: Command,
  27944. execute: function(km) {
  27945. var nodes = km.getSelectedNodes();
  27946. if (this.queryState('italic') == 1) {
  27947. utils.each(nodes, function(i, n) {
  27948. n.setData('font-style').render();
  27949. });
  27950. } else {
  27951. utils.each(nodes, function(i, n) {
  27952. n.setData('font-style', 'italic').render();
  27953. });
  27954. }
  27955. km.layout();
  27956. },
  27957. queryState: function() {
  27958. var nodes = km.getSelectedNodes(),
  27959. result = 0;
  27960. if (nodes.length === 0) {
  27961. return -1;
  27962. }
  27963. utils.each(nodes, function(i, n) {
  27964. if (n && n.getData('font-style')) {
  27965. result = 1;
  27966. return false;
  27967. }
  27968. });
  27969. return result;
  27970. }
  27971. })
  27972. },
  27973. commandShortcutKeys: {
  27974. 'bold': 'ctrl+b', //bold
  27975. 'italic': 'ctrl+i' //italic
  27976. }
  27977. };
  27978. });
  27979. KityMinder.registerModule("fontmodule", function() {
  27980. function getNodeDataOrStyle(node, name) {
  27981. return node.getData(name) || node.getStyle(name);
  27982. }
  27983. KityMinder.TextRenderer.registerStyleHook(function(node, textGroup) {
  27984. var dataColor = node.getData('color');
  27985. var selectedColor = node.getStyle('selected-color');
  27986. var styleColor = node.getStyle('color');
  27987. var foreColor = dataColor || (node.isSelected() && selectedColor ? selectedColor : styleColor);
  27988. var fontFamily = getNodeDataOrStyle(node, 'font-family');
  27989. var fontSize = getNodeDataOrStyle(node, 'font-size');
  27990. var fontHash = [fontFamily, fontSize].join('/');
  27991. textGroup.fill(foreColor);
  27992. node.setTmpData('fore-color', foreColor.toString());
  27993. textGroup.eachItem(function(index,item){
  27994. item.setFont({
  27995. 'family': fontFamily,
  27996. 'size': fontSize
  27997. });
  27998. });
  27999. node.setTmpData('font-hash', fontHash);
  28000. });
  28001. return {
  28002. defaultOptions: {
  28003. 'fontfamily': [{
  28004. name: '宋体',
  28005. val: '宋体,SimSun'
  28006. }, {
  28007. name: '微软雅黑',
  28008. val: '微软雅黑,Microsoft YaHei'
  28009. }, {
  28010. name: '楷体',
  28011. val: '楷体,楷体_GB2312,SimKai'
  28012. }, {
  28013. name: '黑体',
  28014. val: '黑体, SimHei'
  28015. }, {
  28016. name: '隶书',
  28017. val: '隶书, SimLi'
  28018. }, {
  28019. name: 'Andale Mono',
  28020. val: 'andale mono'
  28021. }, {
  28022. name: 'Arial',
  28023. val: 'arial,helvetica,sans-serif'
  28024. }, {
  28025. name: 'arialBlack',
  28026. val: 'arial black,avant garde'
  28027. }, {
  28028. name: 'Comic Sans Ms',
  28029. val: 'comic sans ms'
  28030. }, {
  28031. name: 'Impact',
  28032. val: 'impact,chicago'
  28033. }, {
  28034. name: 'Times New Roman',
  28035. val: 'times new roman'
  28036. }, {
  28037. name: 'Sans-Serif',
  28038. val: 'sans-serif'
  28039. }],
  28040. 'fontsize': [10, 12, 16, 18, 24, 32, 48]
  28041. },
  28042. "commands": {
  28043. "forecolor": kity.createClass("fontcolorCommand", {
  28044. base: Command,
  28045. execute: function(km, color) {
  28046. var nodes = km.getSelectedNodes();
  28047. utils.each(nodes, function(i, n) {
  28048. n.setData('color', color);
  28049. n.render();
  28050. });
  28051. },
  28052. queryState: function(km) {
  28053. return km.getSelectedNodes().length == 0 ? -1 : 0
  28054. },
  28055. queryValue: function(km) {
  28056. if (km.getSelectedNodes().length == 1) {
  28057. return km.getSelectedNodes()[0].getData('color');
  28058. }
  28059. return 'mixed';
  28060. }
  28061. }),
  28062. "background": kity.createClass("backgroudCommand", {
  28063. base: Command,
  28064. execute: function(km, color) {
  28065. var nodes = km.getSelectedNodes();
  28066. utils.each(nodes, function(i, n) {
  28067. n.setData('background', color);
  28068. n.render();
  28069. });
  28070. },
  28071. queryState: function(km) {
  28072. return km.getSelectedNodes().length == 0 ? -1 : 0
  28073. },
  28074. queryValue: function(km) {
  28075. if (km.getSelectedNodes().length == 1) {
  28076. return km.getSelectedNodes()[0].getData('background');
  28077. }
  28078. return 'mixed';
  28079. }
  28080. }),
  28081. "fontfamily": kity.createClass("fontfamilyCommand", {
  28082. base: Command,
  28083. execute: function(km, family) {
  28084. var nodes = km.getSelectedNodes();
  28085. utils.each(nodes, function(i, n) {
  28086. n.setData('font-family', family);
  28087. n.render();
  28088. km.layout();
  28089. });
  28090. },
  28091. queryState: function(km) {
  28092. return km.getSelectedNodes().length === 0 ? -1 : 0
  28093. },
  28094. queryValue: function(km) {
  28095. var node = km.getSelectedNode();
  28096. if (node) return node.getData('font-family');
  28097. return null;
  28098. }
  28099. }),
  28100. "fontsize": kity.createClass("fontsizeCommand", {
  28101. base: Command,
  28102. execute: function(km, size) {
  28103. var nodes = km.getSelectedNodes();
  28104. utils.each(nodes, function(i, n) {
  28105. n.setData('font-size', size);
  28106. n.render();
  28107. km.layout(300);
  28108. });
  28109. },
  28110. queryState: function(km) {
  28111. return km.getSelectedNodes().length == 0 ? -1 : 0
  28112. },
  28113. queryValue: function(km) {
  28114. var node = km.getSelectedNode();
  28115. if (node) return node.getData('font-size');
  28116. return null;
  28117. }
  28118. })
  28119. }
  28120. };
  28121. });
  28122. KityMinder.registerModule('Zoom', function() {
  28123. var me = this;
  28124. var timeline;
  28125. me.setDefaultOptions('zoom', [10, 20, 30, 50, 80, 100, 120, 150, 200]);
  28126. function setTextRendering() {
  28127. var value = me._zoomValue >= 100 ? 'optimize-speed' : 'geometricPrecision';
  28128. me.getRenderContainer().setAttr('text-rendering', value);
  28129. }
  28130. function fixPaperCTM(paper) {
  28131. var node = paper.shapeNode;
  28132. var ctm = node.getCTM();
  28133. var matrix = new kity.Matrix(ctm.a, ctm.b, ctm.c, ctm.d, (ctm.e | 0) + 0.5, (ctm.f | 0) + 0.5);
  28134. node.setAttribute('transform', 'matrix(' + matrix.toString() + ')');
  28135. }
  28136. kity.extendClass(Minder, {
  28137. zoom: function(value) {
  28138. var paper = this.getPaper();
  28139. var viewport = paper.getViewPort();
  28140. viewport.zoom = value / 100;
  28141. viewport.center = {
  28142. x: viewport.center.x,
  28143. y: viewport.center.y
  28144. };
  28145. paper.setViewPort(viewport);
  28146. if (value == 100) fixPaperCTM(paper);
  28147. },
  28148. getZoomValue: function() {
  28149. return this._zoomValue;
  28150. }
  28151. });
  28152. function zoomMinder(minder, value) {
  28153. var paper = minder.getPaper();
  28154. var viewport = paper.getViewPort();
  28155. if (!value) return;
  28156. setTextRendering();
  28157. if (minder.getRoot().getComplex() > 200) {
  28158. minder._zoomValue = value;
  28159. minder.zoom(value);
  28160. minder.fire('viewchange');
  28161. } else {
  28162. var animator = new kity.Animator({
  28163. beginValue: minder._zoomValue,
  28164. finishValue: value,
  28165. setter: function(target, value) {
  28166. target.zoom(value);
  28167. }
  28168. });
  28169. minder._zoomValue = value;
  28170. if (timeline) {
  28171. timeline.pause();
  28172. }
  28173. timeline = animator.start(minder, 300, 'easeInOutSine');
  28174. timeline.on('finish', function() {
  28175. minder.fire('viewchange');
  28176. });
  28177. }
  28178. minder.fire('zoom', { zoom: value });
  28179. }
  28180. var ZoomCommand = kity.createClass('Zoom', {
  28181. base: Command,
  28182. execute: zoomMinder,
  28183. queryValue: function(minder) {
  28184. return minder._zoomValue;
  28185. }
  28186. });
  28187. var ZoomInCommand = kity.createClass('ZoomInCommand', {
  28188. base: Command,
  28189. execute: function(minder) {
  28190. zoomMinder(minder, this.nextValue(minder));
  28191. },
  28192. queryState: function(minder) {
  28193. return +!this.nextValue(minder);
  28194. },
  28195. nextValue: function(minder) {
  28196. var stack = minder.getOptions('zoom'),
  28197. i;
  28198. for (i = 0; i < stack.length; i++) {
  28199. if (stack[i] > minder._zoomValue) return stack[i];
  28200. }
  28201. return 0;
  28202. },
  28203. enableReadOnly: true
  28204. });
  28205. var ZoomOutCommand = kity.createClass('ZoomOutCommand', {
  28206. base: Command,
  28207. execute: function(minder) {
  28208. zoomMinder(minder, this.nextValue(minder));
  28209. },
  28210. queryState: function(minder) {
  28211. return +!this.nextValue(minder);
  28212. },
  28213. nextValue: function(minder) {
  28214. var stack = minder.getOptions('zoom'),
  28215. i;
  28216. for (i = stack.length - 1; i >= 0; i--) {
  28217. if (stack[i] < minder._zoomValue) return stack[i];
  28218. }
  28219. return 0;
  28220. },
  28221. enableReadOnly: true
  28222. });
  28223. return {
  28224. init: function() {
  28225. this._zoomValue = 100;
  28226. setTextRendering();
  28227. },
  28228. commands: {
  28229. 'zoom-in': ZoomInCommand,
  28230. 'zoom-out': ZoomOutCommand,
  28231. 'zoom': ZoomCommand
  28232. },
  28233. events: {
  28234. 'normal.mousewheel readonly.mousewheel': function(e) {
  28235. if (!e.originEvent.ctrlKey && !e.originEvent.metaKey) return;
  28236. var delta = e.originEvent.wheelDelta;
  28237. var me = this;
  28238. if (!kity.Browser.mac) {
  28239. delta = -delta;
  28240. }
  28241. // 稀释
  28242. if (Math.abs(delta) > 100) {
  28243. clearTimeout(this._wheelZoomTimeout);
  28244. } else {
  28245. return;
  28246. }
  28247. this._wheelZoomTimeout = setTimeout(function() {
  28248. var value;
  28249. var lastValue = me.getPaper()._zoom || 1;
  28250. if (delta < 0) {
  28251. me.execCommand('zoom-in');
  28252. } else if (delta > 0) {
  28253. me.execCommand('zoom-out');
  28254. }
  28255. }, 100);
  28256. e.originEvent.preventDefault();
  28257. }
  28258. },
  28259. commandShortcutKeys: {
  28260. 'zoom-in': 'ctrl+=',
  28261. 'zoom-out': 'ctrl+-'
  28262. }
  28263. };
  28264. });
  28265. KityMinder.registerModule("hyperlink", function() {
  28266. var linkShapePath = "M16.614,10.224h-1.278c-1.668,0-3.07-1.07-3.599-2.556h4.877c0.707,0,1.278-0.571,1.278-1.278V3.834 c0-0.707-0.571-1.278-1.278-1.278h-4.877C12.266,1.071,13.668,0,15.336,0h1.278c2.116,0,3.834,1.716,3.834,3.834V6.39 C20.448,8.508,18.73,10.224,16.614,10.224z M5.112,5.112c0-0.707,0.573-1.278,1.278-1.278h7.668c0.707,0,1.278,0.571,1.278,1.278 S14.765,6.39,14.058,6.39H6.39C5.685,6.39,5.112,5.819,5.112,5.112z M2.556,3.834V6.39c0,0.707,0.573,1.278,1.278,1.278h4.877 c-0.528,1.486-1.932,2.556-3.599,2.556H3.834C1.716,10.224,0,8.508,0,6.39V3.834C0,1.716,1.716,0,3.834,0h1.278 c1.667,0,3.071,1.071,3.599,2.556H3.834C3.129,2.556,2.556,3.127,2.556,3.834z";
  28267. return {
  28268. "commands": {
  28269. "hyperlink": kity.createClass("hyperlink", {
  28270. base: Command,
  28271. execute: function(km, url, title) {
  28272. var nodes = km.getSelectedNodes();
  28273. utils.each(nodes, function(i, n) {
  28274. n.setData('hyperlink', url);
  28275. n.setData('hyperlinkTitle', title);
  28276. n.render();
  28277. });
  28278. km.layout();
  28279. },
  28280. queryState: function(km) {
  28281. var nodes = km.getSelectedNodes(),
  28282. result = 0;
  28283. if (nodes.length === 0) {
  28284. return -1;
  28285. }
  28286. utils.each(nodes, function(i, n) {
  28287. if (n && n.getData('hyperlink')) {
  28288. result = 0;
  28289. return false;
  28290. }
  28291. });
  28292. return result;
  28293. },
  28294. queryValue: function(km) {
  28295. var node = km.getSelectedNode();
  28296. return {
  28297. url: node.getData('hyperlink'),
  28298. title: node.getData('hyperlinkTitle')
  28299. };
  28300. }
  28301. }),
  28302. "unhyperlink": kity.createClass("hyperlink", {
  28303. base: Command,
  28304. execute: function(km) {
  28305. var nodes = km.getSelectedNodes();
  28306. utils.each(nodes, function(i, n) {
  28307. n.setData('hyperlink');
  28308. n.render();
  28309. });
  28310. km.layout();
  28311. },
  28312. queryState: function(km) {
  28313. var nodes = km.getSelectedNodes();
  28314. if (nodes.length === 0) {
  28315. return -1;
  28316. }
  28317. var link = false;
  28318. utils.each(nodes, function(i, n) {
  28319. if (n.getData('hyperlink')) {
  28320. link = true;
  28321. return false;
  28322. }
  28323. });
  28324. if (link) {
  28325. return 0;
  28326. }
  28327. return -1;
  28328. }
  28329. })
  28330. },
  28331. 'renderers': {
  28332. right: kity.createClass('hyperlinkrender', {
  28333. base: KityMinder.Renderer,
  28334. create: function() {
  28335. var link = new kity.HyperLink();
  28336. var linkshape = new kity.Path();
  28337. var outline = new kity.Rect(24, 22, -2, -6, 4).fill('rgba(255, 255, 255, 0)');
  28338. linkshape.setPathData(linkShapePath).fill('#666');
  28339. link.addShape(outline);
  28340. link.addShape(linkshape);
  28341. link.setTarget('_blank');
  28342. link.setStyle('cursor', 'pointer');
  28343. link.on('mouseover', function() {
  28344. outline.fill('rgba(255, 255, 200, .8)');
  28345. }).on('mouseout', function() {
  28346. outline.fill('rgba(255, 255, 255, 0)');
  28347. });
  28348. return link;
  28349. },
  28350. shouldRender: function(node) {
  28351. return node.getData('hyperlink');
  28352. },
  28353. update: function(link, node, box) {
  28354. var href = node.getData('hyperlink');
  28355. link.setHref(href);
  28356. var title = node.getData('hyperlinkTitle');
  28357. if (title) {
  28358. title = [title, '(', href, ')'].join('');
  28359. } else {
  28360. title = href;
  28361. }
  28362. link.node.setAttributeNS('http://www.w3.org/1999/xlink', 'title', title);
  28363. var spaceRight = node.getStyle('space-right');
  28364. link.setTranslate(box.right + spaceRight + 2, -5);
  28365. return new kity.Box({
  28366. x: box.right + spaceRight,
  28367. y: -11,
  28368. width: 24,
  28369. height: 22
  28370. });
  28371. }
  28372. })
  28373. }
  28374. };
  28375. });
  28376. KityMinder.registerProtocol('plain', function(minder) {
  28377. var LINE_ENDING = '\r',
  28378. LINE_ENDING_SPLITER = /\r\n|\r|\n/,
  28379. TAB_CHAR = '\t';
  28380. function repeat(s, n) {
  28381. var result = '';
  28382. while (n--) result += s;
  28383. return result;
  28384. }
  28385. function encode(json, level) {
  28386. var local = '';
  28387. level = level || 0;
  28388. local += repeat(TAB_CHAR, level);
  28389. local += json.data.text + LINE_ENDING;
  28390. if (json.children) {
  28391. json.children.forEach(function(child) {
  28392. local += encode(child, level + 1);
  28393. });
  28394. }
  28395. return local;
  28396. }
  28397. function isEmpty(line) {
  28398. return !/\S/.test(line);
  28399. }
  28400. function getLevel(line) {
  28401. var level = 0;
  28402. while (line.charAt(level) === TAB_CHAR) level++;
  28403. return level;
  28404. }
  28405. function getNode(line) {
  28406. return {
  28407. data: {
  28408. text: line.replace(new RegExp('^' + TAB_CHAR + '*'), '')
  28409. }
  28410. };
  28411. }
  28412. /**
  28413. * 文本解码
  28414. *
  28415. * @param {string} local 文本内容
  28416. * @param {=boolean} root 自动根节点
  28417. * @return {Object} 返回解析后节点
  28418. */
  28419. function decode(local, root) {
  28420. var json,
  28421. offset,
  28422. parentMap = {},
  28423. lines = local.split(LINE_ENDING_SPLITER),
  28424. line, level, node;
  28425. function addChild(parent, child) {
  28426. var children = parent.children || (parent.children = []);
  28427. children.push(child);
  28428. }
  28429. if (root) {
  28430. parentMap[0] = json = getNode('root');
  28431. offset = 1;
  28432. } else {
  28433. offset = 0;
  28434. }
  28435. for (var i = 0; i < lines.length; i++) {
  28436. line = lines[i];
  28437. if (isEmpty(line)) continue;
  28438. level = getLevel(line) + offset;
  28439. node = getNode(line);
  28440. if (level === 0) {
  28441. if (json) {
  28442. throw new Error('Invalid local format');
  28443. }
  28444. json = node;
  28445. } else {
  28446. if (!parentMap[level - 1]) {
  28447. throw new Error('Invalid local format');
  28448. }
  28449. addChild(parentMap[level - 1], node);
  28450. }
  28451. parentMap[level] = node;
  28452. }
  28453. return json;
  28454. }
  28455. return {
  28456. fileDescription: '大纲文本',
  28457. fileExtension: '.txt',
  28458. mineType: 'text/plain',
  28459. dataType: 'text',
  28460. encode: function(json) {
  28461. return encode(json, 0);
  28462. },
  28463. decode: function(local, root) {
  28464. return decode(local, root);
  28465. },
  28466. recognizePriority: -1
  28467. };
  28468. });
  28469. /**
  28470. * @fileOverview
  28471. *
  28472. * Markdown 格式导入导出支持
  28473. *
  28474. * @author: techird
  28475. * @copyright: Baidu FEX, 2014
  28476. */
  28477. KityMinder.registerProtocol('markdown', function() {
  28478. var LINE_ENDING_SPLITER = /\r\n|\r|\n/;
  28479. var EMPTY_LINE = '';
  28480. var NOTE_MARK_START = '<!--Note-->';
  28481. var NOTE_MARK_CLOSE = '<!--/Note-->';
  28482. function encode(json) {
  28483. return _build(json, 1).join('\n');
  28484. }
  28485. function _build(node, level) {
  28486. var lines = [];
  28487. level = level || 1;
  28488. var sharps = _generateHeaderSharp(level);
  28489. lines.push(sharps + ' ' + node.data.text);
  28490. lines.push(EMPTY_LINE);
  28491. var note = node.data.note;
  28492. if (note) {
  28493. var hasSharp = /^#/.test(note);
  28494. if (hasSharp) {
  28495. lines.push(NOTE_MARK_START);
  28496. note = note.replace(/^#+/gm, function($0) {
  28497. return sharps + $0;
  28498. });
  28499. }
  28500. lines.push(note);
  28501. if (hasSharp) {
  28502. lines.push(NOTE_MARK_CLOSE);
  28503. }
  28504. lines.push(EMPTY_LINE);
  28505. }
  28506. if (node.children) node.children.forEach(function(child) {
  28507. lines = lines.concat(_build(child, level + 1));
  28508. });
  28509. return lines;
  28510. }
  28511. function _generateHeaderSharp(level) {
  28512. var sharps = '';
  28513. while(level--) sharps += '#';
  28514. return sharps;
  28515. }
  28516. function decode(markdown) {
  28517. var json,
  28518. parentMap = {},
  28519. lines, line, lineInfo, level, node, parent, noteProgress, codeBlock;
  28520. // 一级标题转换 `{title}\n===` => `# {title}`
  28521. markdown = markdown.replace(/^(.+)\n={3,}/, function($0, $1) {
  28522. return '# ' + $1;
  28523. });
  28524. lines = markdown.split(LINE_ENDING_SPLITER);
  28525. // 按行分析
  28526. for (var i = 0; i < lines.length; i++) {
  28527. line = lines[i];
  28528. lineInfo = _resolveLine(line);
  28529. // 备注标记处理
  28530. if (lineInfo.noteClose) {
  28531. noteProgress = false;
  28532. continue;
  28533. } else if (lineInfo.noteStart) {
  28534. noteProgress = true;
  28535. continue;
  28536. }
  28537. // 代码块处理
  28538. codeBlock = lineInfo.codeBlock ? !codeBlock : codeBlock;
  28539. // 备注条件:备注标签中,非标题定义,或标题越位
  28540. if (noteProgress || codeBlock || !lineInfo.level || lineInfo.level > level + 1) {
  28541. if (node) _pushNote(node, line);
  28542. continue;
  28543. }
  28544. // 标题处理
  28545. level = lineInfo.level;
  28546. node = _initNode(lineInfo.content, parentMap[level - 1]);
  28547. parentMap[level] = node;
  28548. }
  28549. _cleanUp(parentMap[1]);
  28550. return parentMap[1];
  28551. }
  28552. function _initNode(text, parent) {
  28553. var node = {
  28554. data: {
  28555. text: text,
  28556. note: ''
  28557. }
  28558. };
  28559. if (parent) {
  28560. if (parent.children) parent.children.push(node);
  28561. else parent.children = [node];
  28562. }
  28563. return node;
  28564. }
  28565. function _pushNote(node, line) {
  28566. node.data.note += line + '\n';
  28567. }
  28568. function _isEmpty(line) {
  28569. return !/\S/.test(line);
  28570. }
  28571. function _resolveLine(line) {
  28572. var match = /^(#+)?\s*(.*)$/.exec(line);
  28573. return {
  28574. level: match[1] && match[1].length || null,
  28575. content: match[2],
  28576. noteStart: line == NOTE_MARK_START,
  28577. noteClose: line == NOTE_MARK_CLOSE,
  28578. codeBlock: /^\s*```/.test(line)
  28579. };
  28580. }
  28581. function _cleanUp(node) {
  28582. if (!/\S/.test(node.data.note)) {
  28583. node.data.note = null;
  28584. delete node.data.note;
  28585. } else {
  28586. var notes = node.data.note.split('\n');
  28587. while(notes.length && !/\S/.test(notes[0])) notes.shift();
  28588. while(notes.length && !/\S/.test(notes[notes.length - 1])) notes.pop();
  28589. node.data.note = notes.join('\n');
  28590. }
  28591. if (node.children) node.children.forEach(_cleanUp);
  28592. }
  28593. return {
  28594. fileDescription: 'Markdown/GFM 格式',
  28595. fileExtension: '.md',
  28596. mineType: 'text/markdown',
  28597. dataType: 'text',
  28598. encode: function(json) {
  28599. return encode(json);
  28600. },
  28601. decode: function(markdown) {
  28602. return decode(markdown);
  28603. },
  28604. recognizePriority: -1
  28605. };
  28606. });
  28607. KityMinder.registerProtocol('json', function(minder) {
  28608. return {
  28609. fileDescription: 'KityMinder 格式',
  28610. fileExtension: '.km',
  28611. dataType: 'text',
  28612. mineType: 'application/json',
  28613. encode: function(json) {
  28614. return JSON.stringify(json);
  28615. },
  28616. decode: function(local) {
  28617. return JSON.parse(local);
  28618. }
  28619. };
  28620. });
  28621. if (!kity.Browser.ie) {
  28622. KityMinder.registerProtocol('png', function(minder) {
  28623. var DomURL = window.URL || window.webkitURL || window;
  28624. function loadImage(url, callback) {
  28625. return new Promise(function(resolve, reject) {
  28626. var image = document.createElement('img');
  28627. image.onload = function() {
  28628. resolve(this);
  28629. };
  28630. image.onerror = function(err) {
  28631. reject(err);
  28632. };
  28633. image.crossOrigin = '';
  28634. image.src = url;
  28635. });
  28636. }
  28637. function getSVGInfo() {
  28638. var paper = minder.getPaper(),
  28639. paperTransform,
  28640. domContainer = paper.container,
  28641. svgXml,
  28642. $svg,
  28643. renderContainer = minder.getRenderContainer(),
  28644. renderBox = renderContainer.getRenderBox(),
  28645. width = renderBox.width + 1,
  28646. height = renderBox.height + 1,
  28647. blob, svgUrl, img;
  28648. // 保存原始变换,并且移动到合适的位置
  28649. paperTransform = paper.shapeNode.getAttribute('transform');
  28650. paper.shapeNode.setAttribute('transform', 'translate(0.5, 0.5)');
  28651. renderContainer.translate(-renderBox.x, -renderBox.y);
  28652. // 获取当前的 XML 代码
  28653. svgXml = paper.container.innerHTML;
  28654. // 回复原始变换及位置
  28655. renderContainer.translate(renderBox.x, renderBox.y);
  28656. paper.shapeNode.setAttribute('transform', paperTransform);
  28657. // 过滤内容
  28658. $svg = $(svgXml).filter('svg');
  28659. $svg.attr({
  28660. width: renderBox.width + 1,
  28661. height: renderBox.height + 1,
  28662. style: 'font-family: Arial, "Microsoft Yahei","Heiti SC";'
  28663. });
  28664. svgXml = $('<div></div>').append($svg).html();
  28665. // Dummy IE
  28666. svgXml = svgXml.replace(' xmlns="http://www.w3.org/2000/svg" xmlns:NS1="" NS1:ns1:xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:NS2="" NS2:xmlns:ns1=""', '');
  28667. // svg 含有 &nbsp; 符号导出报错 Entity 'nbsp' not defined
  28668. svgXml = svgXml.replace(/&nbsp;/g, '&#xa0;');
  28669. blob = new Blob([svgXml], {
  28670. type: 'image/svg+xml'
  28671. });
  28672. svgUrl = DomURL.createObjectURL(blob);
  28673. //svgUrl = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svgXml);
  28674. return {
  28675. width: width,
  28676. height: height,
  28677. dataUrl: svgUrl,
  28678. xml: svgXml
  28679. };
  28680. }
  28681. function encode(json) {
  28682. /* 绘制 PNG 的画布及上下文 */
  28683. var canvas = document.createElement('canvas');
  28684. var ctx = canvas.getContext('2d');
  28685. /* 尝试获取背景图片 URL 或背景颜色 */
  28686. var bgDeclare = minder.getStyle('background').toString();
  28687. var bgUrl = /url\((.+)\)/.exec(bgDeclare);
  28688. var bgColor = kity.Color.parse(bgDeclare);
  28689. /* 获取 SVG 文件内容 */
  28690. var svgInfo = getSVGInfo();
  28691. var width = svgInfo.width;
  28692. var height = svgInfo.height;
  28693. var svgDataUrl = svgInfo.dataUrl;
  28694. /* 画布的填充大小 */
  28695. var padding = 20;
  28696. canvas.width = width + padding * 2;
  28697. canvas.height = height + padding * 2;
  28698. function fillBackground(ctx, style) {
  28699. ctx.save();
  28700. ctx.fillStyle = style;
  28701. ctx.fillRect(0, 0, canvas.width, canvas.height);
  28702. ctx.restore();
  28703. }
  28704. function drawImage(ctx, image, x, y) {
  28705. ctx.drawImage(image, x, y);
  28706. }
  28707. function generateDataUrl(canvas) {
  28708. try {
  28709. var url = canvas.toDataURL('png');
  28710. return url;
  28711. } catch (e) {
  28712. throw new Error('当前浏览器版本不支持导出 PNG 功能,请尝试升级到最新版本!');
  28713. }
  28714. }
  28715. function drawSVG() {
  28716. if (typeof(window.canvg) != 'undefined') {
  28717. return new Promise(function(resolve) {
  28718. window.canvg(canvas, svgInfo.xml, {
  28719. ignoreMouse: true,
  28720. ignoreAnimation: true,
  28721. ignoreDimensions: true,
  28722. ignoreClear: true,
  28723. offsetX: padding,
  28724. offsetY: padding,
  28725. renderCallback: function() {
  28726. resolve(generateDataUrl(canvas));
  28727. }
  28728. });
  28729. });
  28730. } else {
  28731. return loadImage(svgDataUrl).then(function(svgImage) {
  28732. drawImage(ctx, svgImage, padding, padding);
  28733. DomURL.revokeObjectURL(svgDataUrl);
  28734. return generateDataUrl(canvas);
  28735. });
  28736. }
  28737. }
  28738. if (bgUrl) {
  28739. return loadImage(bgUrl[1]).then(function(image) {
  28740. fillBackground(ctx, ctx.createPattern(image, 'repeat'));
  28741. return drawSVG();
  28742. });
  28743. } else {
  28744. fillBackground(ctx, bgColor.toString());
  28745. return drawSVG();
  28746. }
  28747. }
  28748. return {
  28749. fileDescription: 'PNG 图片',
  28750. fileExtension: '.png',
  28751. mineType: 'image/png',
  28752. dataType: 'base64',
  28753. encode: encode,
  28754. recognizePriority: -1
  28755. };
  28756. });
  28757. }
  28758. if (!kity.Browser.ie) {
  28759. KityMinder.registerProtocol('svg', function(minder) {
  28760. return {
  28761. fileDescription: 'SVG 矢量图',
  28762. fileExtension: '.svg',
  28763. mineType: 'image/svg+xml',
  28764. dataType: 'text',
  28765. encode: function(json) {
  28766. var paper = minder.getPaper(),
  28767. paperTransform = paper.shapeNode.getAttribute('transform'),
  28768. svgXml,
  28769. $svg,
  28770. renderContainer = minder.getRenderContainer(),
  28771. renderBox = renderContainer.getRenderBox(),
  28772. transform = renderContainer.getTransform(),
  28773. width = renderBox.width,
  28774. height = renderBox.height,
  28775. padding = 20;
  28776. paper.shapeNode.setAttribute('transform', 'translate(0.5, 0.5)');
  28777. svgXml = paper.container.innerHTML;
  28778. paper.shapeNode.setAttribute('transform', paperTransform);
  28779. $svg = $(svgXml).filter('svg');
  28780. $svg.attr({
  28781. width: width + padding * 2 | 0,
  28782. height: height + padding * 2 | 0,
  28783. style: 'font-family: Arial, "Microsoft Yahei", "Heiti SC"; background: ' + minder.getStyle('background')
  28784. });
  28785. $svg[0].setAttribute('viewBox', [renderBox.x - padding | 0,
  28786. renderBox.y - padding | 0,
  28787. width + padding * 2 | 0,
  28788. height + padding * 2 | 0
  28789. ].join(' '));
  28790. // need a xml with width and height
  28791. svgXml = $('<div></div>').append($svg).html();
  28792. svgXml = $('<div></div>').append($svg).html();
  28793. // svg 含有 &nbsp; 符号导出报错 Entity 'nbsp' not defined
  28794. svgXml = svgXml.replace(/&nbsp;/g, '&#xa0;');
  28795. // svg 含有 &nbsp; 符号导出报错 Entity 'nbsp' not defined
  28796. return svgXml;
  28797. },
  28798. recognizePriority: -1
  28799. };
  28800. });
  28801. }
  28802. /**
  28803. * @fileOverview
  28804. *
  28805. * KityMinder UI 注册及加载机制
  28806. *
  28807. * @author: techird
  28808. * @copyright: Baidu FEX, 2014
  28809. */
  28810. (function() {
  28811. var uiQueue = [];
  28812. /* 注册一个新的 UI 交互 */
  28813. KityMinder.registerUI = function(id, deps, ui) {
  28814. if (typeof(deps) == 'function') {
  28815. ui = deps;
  28816. deps = null;
  28817. }
  28818. uiQueue.push({
  28819. id: id,
  28820. ui: ui,
  28821. deps: deps
  28822. });
  28823. };
  28824. kity.extendClass(Minder, {
  28825. /* 为实例注册 UI 交互 */
  28826. initUI: function() {
  28827. var ui = this._ui = {};
  28828. var minder = this;
  28829. uiQueue.forEach(function(uiDeal) {
  28830. var deps = uiDeal.deps;
  28831. if (deps) deps = deps.map(function(dep) {
  28832. return minder.getUI(dep);
  28833. });
  28834. ui[uiDeal.id] = uiDeal.ui.apply(null, [minder].concat(deps || []));
  28835. });
  28836. // 阻止非脑图事件冒泡
  28837. $('#content-wrapper').delegate('#panel, #tab-container, .fui-dialog, #main-menu', 'keydown keyup', function(e) {
  28838. e.stopPropagation();
  28839. });
  28840. // 阻止非脑图事件冒泡
  28841. $('#content-wrapper').delegate('input', 'mousedown mousemove mouseup contextmenu', function(e) {
  28842. e.stopPropagation();
  28843. });
  28844. minder.getPaper().addClass('loading-target');
  28845. this.fire('interactchange');
  28846. this.fire('uiready');
  28847. },
  28848. /* 获得实例的 UI 实例 */
  28849. getUI: function(id) {
  28850. return this._ui[id];
  28851. }
  28852. });
  28853. $.ajaxSetup({ cache: false });
  28854. $.extend($, {
  28855. pajax: function() {
  28856. var jqXHR = $.ajax.apply($, arguments);
  28857. return new Promise(function(resolve, reject) {
  28858. jqXHR.done(resolve);
  28859. jqXHR.fail(function(jqXHR, textStatus, errorThrown) {
  28860. var e = new Error(textStatus);
  28861. e.getDetail = function() {
  28862. try {
  28863. return 'jQuery XHR Error: \n' + JSON.stringify(errorThrown);
  28864. } catch (e) {
  28865. return errorThrown;
  28866. }
  28867. };
  28868. reject(e);
  28869. });
  28870. });
  28871. }
  28872. });
  28873. // preload css images
  28874. $(function() {
  28875. var list = ["kmcat_warn.png", "kmcat_sad.png", "icons.png", "template_large.png", "history.png", "feedback.png", "iconpriority.png", "iconprogress.png", "template.png", "layout.png", "next-level.png", "prev-level.png"];
  28876. list.forEach(function(item) {
  28877. (new Image()).src = 'ui/theme/default/images/' + item;
  28878. });
  28879. });
  28880. })();
  28881. /**
  28882. * @fileOverview
  28883. *
  28884. * 简版事件解耦功能
  28885. *
  28886. * @author: techird
  28887. * @copyright: Baidu FEX, 2014
  28888. */
  28889. KityMinder.registerUI('eve', function(minder) {
  28890. return {
  28891. setup: function(obj) {
  28892. var callbacks = {};
  28893. obj.on = function on(name, callback) {
  28894. var list = callbacks[name] || (callbacks[name] = []);
  28895. list.push(callback);
  28896. return this;
  28897. };
  28898. obj.off = function off(name, callback) {
  28899. var list = callbacks[name];
  28900. if (list) {
  28901. var index = list.indexOf(callback);
  28902. if (~index) {
  28903. list.splice(index, 1);
  28904. } else {
  28905. callback[name] = null;
  28906. }
  28907. }
  28908. return this;
  28909. };
  28910. obj.once = function once(name, callback) {
  28911. return this.on(name, function wrapped() {
  28912. callback.apply(obj, arguments);
  28913. obj.off(name, wrapped);
  28914. });
  28915. };
  28916. obj.fire = function fire(name) {
  28917. var list = callbacks[name];
  28918. var args = [].slice.call(arguments, 1);
  28919. if (list) list.forEach(function(callback) {
  28920. callback.apply(obj, args);
  28921. });
  28922. return this;
  28923. };
  28924. return obj;
  28925. }
  28926. };
  28927. });
  28928. /**
  28929. * @fileOverview
  28930. *
  28931. * UI 状态记忆
  28932. *
  28933. * @author: techird
  28934. * @copyright: Baidu FEX, 2014
  28935. */
  28936. KityMinder.registerUI('memory', function () {
  28937. var ls = window.localStorage;
  28938. var memory = ls.uiMemory ? JSON.parse(ls.uiMemory) : {};
  28939. return {
  28940. get: function(item) {
  28941. return memory[item] || null;
  28942. },
  28943. set: function(item, value) {
  28944. memory[item] = value;
  28945. ls.uiMemory = JSON.stringify(memory);
  28946. }
  28947. };
  28948. });
  28949. /**
  28950. * @fileOverview
  28951. *
  28952. * 拓展 FUI 组件的功能
  28953. *
  28954. * @author: techird
  28955. * @copyright: Baidu FEX, 2014
  28956. */
  28957. kity.extendClass(FUI.Widget, {
  28958. setEnable: function(value) {
  28959. if (value === false) this.disable();
  28960. else this.enable();
  28961. },
  28962. setActive: function(value) {
  28963. if (value === false) this.removeClass('active');
  28964. else this.addClass('active');
  28965. },
  28966. bindExecution: function(event, fn) {
  28967. var widget = this;
  28968. widget.on(event, function() {
  28969. if (widget.interactFlag) return;
  28970. fn.apply(widget, arguments);
  28971. });
  28972. },
  28973. bindCommandState: function(minder, command, valueHandle) {
  28974. var widget = this;
  28975. minder.on('interactchange', function() {
  28976. widget.interactFlag = true;
  28977. if (valueHandle) {
  28978. var value = this.queryCommandValue(command);
  28979. if (value != widget.lastHandleCommandValue) {
  28980. valueHandle.call(widget, value);
  28981. widget.lastHandleCommandValue = value;
  28982. }
  28983. }
  28984. widget.setEnable(this.queryCommandState(command) !== -1);
  28985. widget.setActive(this.queryCommandState(command) === 1);
  28986. widget.interactFlag = false;
  28987. });
  28988. }
  28989. });
  28990. /**
  28991. * @fileOverview
  28992. *
  28993. * XSS Protection
  28994. *
  28995. * @author: techird
  28996. * @copyright: Baidu FEX, 2014
  28997. */
  28998. KityMinder.registerUI('axss', function() {
  28999. function axss(value) {
  29000. var div = document.createElement('div');
  29001. div.innerHTML = value;
  29002. $(div).find('script, iframe, link').remove();
  29003. for (var name in div) {
  29004. if (name.indexOf('on') === 0) {
  29005. div.removeAttribute(name);
  29006. }
  29007. }
  29008. return div.innerHTML;
  29009. }
  29010. return axss;
  29011. });
  29012. /**
  29013. * @fileOverview
  29014. *
  29015. * 通知小组件
  29016. *
  29017. * @author: techird
  29018. * @copyright: Baidu FEX, 2014
  29019. */
  29020. KityMinder.registerUI('widget/notice', function(minder) {
  29021. var errorMessage = minder.getLang('error_message');
  29022. var memory = minder.getUI('memory');
  29023. var $notice = $('<div>')
  29024. .addClass('notice-widget')
  29025. .appendTo('#content-wrapper');
  29026. var $mask = $('<div>')
  29027. .addClass('error-mask');
  29028. var $error = new FUI.Dialog({
  29029. width: 500,
  29030. height: 'auto',
  29031. prompt: true,
  29032. caption: errorMessage.title,
  29033. className: 'error-dialog'
  29034. }).appendTo(document.getElementById('content-wrapper'));
  29035. $error.on('ok cancel', function(e) {
  29036. if (error.resolve) error.resolve(e);
  29037. });
  29038. var $error_body = $($error.getBodyElement());
  29039. var isBuilded = (function() {
  29040. var scripts = [].slice.apply(document.getElementsByTagName('script'));
  29041. var s, m;
  29042. while ((s = scripts.pop())) {
  29043. if ((m = /kityminder.*\.min\.js/.exec(s.src))) return m[0];
  29044. }
  29045. return false;
  29046. })();
  29047. // concatMap: sperate files -> join file
  29048. // minMap: join file -> min file
  29049. var concatMap, minMap;
  29050. function fixSourceSymbol($ta, $mask) {
  29051. function fix() {
  29052. var text = $ta.text();
  29053. var pattern = new RegExp('at.+' + isBuilded + '.+\\:(\\d+)\\:(\\d+)\\)?', 'g');
  29054. var match;
  29055. $ta.text(text.replace(pattern, function(match, $1, $2) {
  29056. var lookup = {
  29057. line: +$1,
  29058. column: +$2
  29059. };
  29060. var info = minMap.originalPositionFor(lookup);
  29061. var name = info.name;
  29062. lookup = {
  29063. line: info.line,
  29064. column: info.column
  29065. };
  29066. info = concatMap.originalPositionFor(lookup);
  29067. name = name || '<Anonymous>';
  29068. var replaced = 'at ' + name + ' (' +
  29069. info.source.replace('../', '') + ':' + info.line + ':' + info.column + ')';
  29070. if (replaced.indexOf('promise') != -1) {
  29071. replaced = 'at <async> Promise.' + name;
  29072. }
  29073. return replaced;
  29074. }));
  29075. }
  29076. if (isBuilded) {
  29077. if (concatMap) return fix();
  29078. $mask.addClass('loading');
  29079. setTimeout(function() {
  29080. $mask.removeClass('loading');
  29081. }, 5000);
  29082. var script = document.createElement('script');
  29083. script.onload = function() {
  29084. Promise.all([
  29085. $.pajax({
  29086. url: isBuilded.replace('min.js', 'js.map'),
  29087. dataType: 'json'
  29088. }),
  29089. $.pajax({
  29090. url: isBuilded.replace('.js', '.map'),
  29091. dataType: 'json'
  29092. })
  29093. ]).then(function(files) {
  29094. concatMap = new window.sourceMap.SourceMapConsumer(files[0]);
  29095. minMap = new window.sourceMap.SourceMapConsumer(files[1]);
  29096. fix();
  29097. $mask.removeClass('loading');
  29098. });
  29099. };
  29100. script.src = 'lib/source-map.min.js';
  29101. document.head.appendChild(script);
  29102. }
  29103. }
  29104. $error_body.delegate('.error-detail a.expander', 'click', function(e) {
  29105. var $detail = $(e.target).closest('.error-detail').toggleClass('expanded');
  29106. var showDetail = $detail.hasClass('expanded');
  29107. memory.set('show-error-detail', showDetail);
  29108. });
  29109. function info(msg, warn, time) {
  29110. if (!$notice.hasClass('show')) $notice.empty();
  29111. clearTimeout(info.ttl2);
  29112. if (warn) $notice.addClass('warn');
  29113. else $notice.removeClass('warn');
  29114. var $menu = minder.getUI('menu/menu');
  29115. $notice.css({
  29116. top: $menu && $menu.isVisible() ?
  29117. $('#main-menu .main-menu-level1').offset().top :
  29118. $('#kityminder').offset().top + 20
  29119. });
  29120. $notice.append($('<p>').text(msg));
  29121. $notice.addClass('show');
  29122. clearTimeout(info.ttl);
  29123. time = time || (warn ? 5000 : 3000);
  29124. info.ttl = setTimeout(function() {
  29125. $notice.removeClass('show');
  29126. info.ttl2 = setTimeout(function() {
  29127. $notice.empty();
  29128. }, 1000);
  29129. }, time);
  29130. }
  29131. function warn(msg) {
  29132. info(msg, warn);
  29133. }
  29134. function descriptReason(e) {
  29135. e = e || new Error();
  29136. if (typeof(e) == 'string') {
  29137. e = new Error(e);
  29138. }
  29139. if (e.getDetail) return e;
  29140. // 文件访问错误
  29141. if (typeof(fio) != 'undefined' && (e instanceof fio.FileRequestError)) {
  29142. if (!e.status) {
  29143. e.description = errorMessage.err_network;
  29144. } else {
  29145. e.description = errorMessage.pcs_code[e.detail.error_code];
  29146. }
  29147. e.getDetail = function() {
  29148. return JSON.stringify(e, null, 4);
  29149. };
  29150. }
  29151. // jqXhr
  29152. else if ('readyState' in e) {
  29153. } else {
  29154. e.getDetail = function() {
  29155. return e.stack || new Error().stack;
  29156. };
  29157. }
  29158. return e;
  29159. }
  29160. function error(name, e) {
  29161. if (arguments.length == 1) {
  29162. e = name;
  29163. name = 'unknown';
  29164. }
  29165. $error_body.empty();
  29166. e = descriptReason(e);
  29167. var $content = $('<div>')
  29168. .addClass('error-content')
  29169. .appendTo($error_body);
  29170. var $msg = $('<h3>')
  29171. .text(errorMessage[name] || errorMessage.err_unknown)
  29172. .appendTo($content);
  29173. var $reason = $('<p>')
  29174. .text(e.message || e.description || errorMessage.unknownreason)
  29175. .appendTo($content);
  29176. if (e.getDetail) {
  29177. var $detail = $('<div>')
  29178. .addClass('error-detail')
  29179. .append($('<a class="expander"></a>').text(minder.getLang('ui.error_detail')))
  29180. .appendTo($error_body);
  29181. var $detailContent = $('<div>')
  29182. .addClass('error-detail-wrapper')
  29183. .appendTo($detail);
  29184. var $textarea = $('<textarea>')
  29185. .attr('id', 'error-detail-content')
  29186. .text(e.getDetail() + '\n\n浏览器信息:' + navigator.userAgent)
  29187. .appendTo($detailContent);
  29188. fixSourceSymbol($textarea, $detailContent);
  29189. var $copy = $('<button>')
  29190. .addClass('copy-and-feedback')
  29191. .text(minder.getLang('ui.copy_and_feedback'))
  29192. .appendTo($detailContent);
  29193. $copy.attr('data-clipboard-target', 'error-detail-content');
  29194. zeroCopy($copy);
  29195. if (memory.get('show-error-detail')) $detail.addClass('expanded');
  29196. }
  29197. $error.show();
  29198. $error.getElement().style.top = '180px';
  29199. return new Promise(function(resolve) {
  29200. error.resolve = resolve;
  29201. });
  29202. }
  29203. function zeroCopy($target) {
  29204. /* global ZeroClipboard:true */
  29205. if (window.ZeroClipboard) {
  29206. ZeroClipboard.config({
  29207. swfPath: 'lib/ZeroClipboard.swf',
  29208. hoverClass: 'hover',
  29209. activeClass: 'active'
  29210. });
  29211. var clip = new window.ZeroClipboard($target);
  29212. clip.on('ready', function() {
  29213. clip.on('aftercopy', function() {
  29214. $error.hide();
  29215. minder.getUI('topbar/feedback').click();
  29216. });
  29217. });
  29218. } else {
  29219. $target.remove();
  29220. }
  29221. }
  29222. return {
  29223. info: info,
  29224. error: error,
  29225. warn: warn
  29226. };
  29227. });
  29228. /**
  29229. * @fileOverview
  29230. *
  29231. * 用 FUI.Tabs 实现的多级的创建
  29232. *
  29233. * @author: techird
  29234. * @copyright: Baidu FEX, 2014
  29235. */
  29236. KM.registerUI('widget/menutab', function(minder) {
  29237. function generate(parent, name, asDefault) {
  29238. var index = parent.getButtons().length;
  29239. var tab = parent.appendTab({
  29240. buttons: [{
  29241. label: minder.getLang('ui.menu.' + name + 'tab'),
  29242. className: 'tab-' + name
  29243. }]
  29244. });
  29245. if (asDefault) {
  29246. parent.select(index);
  29247. }
  29248. return tab[0].panel.getContentElement();
  29249. }
  29250. return {
  29251. generate: generate
  29252. };
  29253. });
  29254. /**
  29255. * @fileOverview
  29256. *
  29257. * 当前文档管理
  29258. *
  29259. * @author: techird
  29260. * @copyright: Baidu FEX, 2014
  29261. */
  29262. KityMinder.registerUI('doc', function(minder) {
  29263. var ret = minder.getUI('eve').setup({});
  29264. var current = { saved: true };
  29265. var loading = false;
  29266. var notice = minder.getUI('widget/notice');
  29267. var finder = minder.getUI('widget/netdiskfinder');
  29268. if (finder) finder.on('mv', trackFileMove);
  29269. function trackFileMove(from, to) {
  29270. if (current.source != 'netdisk') return;
  29271. var fromPath = from.split('/');
  29272. var toPath = to.split('/');
  29273. function preCommonLength(a, b) {
  29274. var i = 0;
  29275. while ((i in a) && (i in b) && a[i] == b[i]) i++;
  29276. return (i in b) ? 0 : i;
  29277. }
  29278. var originPath = current.path.split('/');
  29279. var clen = preCommonLength(originPath, fromPath);
  29280. if (clen) {
  29281. var movedPath = toPath.concat(originPath.slice(clen));
  29282. current.path = movedPath.join('/');
  29283. current.title = movedPath.pop();
  29284. ret.fire('docchange', current);
  29285. }
  29286. }
  29287. var locked = false;
  29288. ret.lock = function() { locked = true; };
  29289. ret.unlock = function() { locked = false; };
  29290. /**
  29291. * 加载文档
  29292. *
  29293. * @param {Object} doc 文档的属性,可包括:
  29294. * doc.content {string} [Required] 文档内容
  29295. * doc.protocol {string} [Required] 内容所使用的编码协议
  29296. * doc.title {string} 文档的标题
  29297. * doc.source {string} 文档的来源
  29298. * doc.path {string} 文档的路径
  29299. * doc.saved {bool} 文档的保存状态
  29300. *
  29301. * @event docload(doc)
  29302. * doc - 文档解析之后的文档对象
  29303. *
  29304. * @return {Promise<doc>} 返回解析完之后的文档对象,解析的结果为 doc.data
  29305. */
  29306. function load(doc) {
  29307. if (locked) return Promise.reject(new Error('doc was locked'));
  29308. var restore = doc;
  29309. current = doc;
  29310. loading = true;
  29311. return minder.importData(doc.content, doc.protocol).then(function(data) {
  29312. doc.title = doc.title || minder.getMinderTitle();
  29313. minder.execCommand('camera', minder.getRoot(), 300);
  29314. doc.data = data;
  29315. doc.json = JSON.stringify(data);
  29316. ret.fire('docload', doc);
  29317. ret.fire('docchange', doc);
  29318. return doc;
  29319. })['catch'](function(e) {
  29320. current = restore;
  29321. notice.error('err_doc_resolve', e);
  29322. }).then(function(doc) {
  29323. loading = false;
  29324. if (doc)
  29325. notice.info(minder.getLang('ui.load_success', doc.title));
  29326. return doc;
  29327. });
  29328. }
  29329. function save(doc) {
  29330. current = doc;
  29331. doc.data = minder.exportJson();
  29332. doc.json = JSON.stringify(doc.data);
  29333. doc.saved = true;
  29334. ret.fire('docsave', doc);
  29335. ret.fire('docchange', doc);
  29336. }
  29337. function getCurrent() {
  29338. return current;
  29339. }
  29340. function checkSaved(noConfirm) {
  29341. if (!fio.user.current()) return true;
  29342. if (locked) return false;
  29343. if (noConfirm) return current.saved;
  29344. return current.saved || window.confirm(minder.getLang('ui.unsavedcontent', '* ' + current.title));
  29345. }
  29346. /* 绕开初始化时候的乱事件 */
  29347. setTimeout(function() {
  29348. minder.on('contentchange', function() {
  29349. if (loading) return;
  29350. if (current.source != 'netdisk') {
  29351. current.title = minder.getMinderTitle();
  29352. current.saved = false;
  29353. } else {
  29354. current.saved = current.json == JSON.stringify(minder.exportJson());
  29355. }
  29356. ret.fire('docchange', current);
  29357. });
  29358. }, 1000);
  29359. ret.load = load;
  29360. ret.save = save;
  29361. ret.current = getCurrent;
  29362. ret.checkSaved = checkSaved;
  29363. return ret;
  29364. });
  29365. /**
  29366. * @fileOverview
  29367. *
  29368. * 查看分享文件
  29369. *
  29370. * @author: techird
  29371. * @copyright: Baidu FEX, 2014
  29372. */
  29373. KityMinder.registerUI('menu/share/m-share', function (minder) {
  29374. var $doc = minder.getUI('doc');
  29375. function loadShareDoc() {
  29376. var pattern = /(?:shareId|share_id)=(\w+)([&#]|$)/;
  29377. var match = pattern.exec(window.location) || pattern.exec(document.referrer);
  29378. if (!match) return Promise.resolve(null);
  29379. var shareId = match[1];
  29380. function renderShareData(data) {
  29381. if (data.error) {
  29382. window.alert(data.error);
  29383. window.location.href = 'index.html';
  29384. return;
  29385. }
  29386. var content = data.shareMinder.data;
  29387. return $doc.load({
  29388. source: 'share',
  29389. content: content,
  29390. protocol: 'json',
  29391. saved: true,
  29392. ownerId: data.uid,
  29393. ownerName: data.uname
  29394. }).then(function(doc) {
  29395. var $title = minder.getUI('topbar/title');
  29396. });
  29397. }
  29398. $('#kityminder').addClass('loading');
  29399. return $.pajax({
  29400. url: 'http://naotu.baidu.com/share.php', //'http://naotu.baidu.com/mongo.php',
  29401. data: {
  29402. action: 'find',
  29403. id: shareId
  29404. },
  29405. dataType: 'json'
  29406. }).then(renderShareData)['catch'](function(e) {
  29407. window.alert('请求分享文件失败,请重试!');
  29408. }).then(function() {
  29409. $(minder.getRenderTarget()).removeClass('loading');
  29410. minder.execCommand('hand');
  29411. $('#kityminder').removeClass('loading');
  29412. });
  29413. }
  29414. minder.on('dblclick', function() {
  29415. minder.execCommand('camera', minder.getRoot(), 500);
  29416. });
  29417. return {
  29418. ready: loadShareDoc()
  29419. };
  29420. });
  29421. /**
  29422. * @fileOverview
  29423. *
  29424. * 移动端分享页面转换视图按钮
  29425. *
  29426. * @author: zhangbobell
  29427. * @copyright: Baidu FEX, 2014
  29428. */
  29429. KityMinder.registerUI('topbar/switch-view', function(minder) {
  29430. var $switch = $('<span class="switch-view" id="switch-view">转换</span>').appendTo('#panel');
  29431. $('<div class="back"></div>').appendTo('#m-logo');
  29432. var treeData;
  29433. var $curView=$('<div id="curView">');
  29434. var $preView=$('<div id="preView">');
  29435. minder.on('uiready', function() {
  29436. var shareView = minder.getUI('menu/share/m-share');
  29437. shareView.ready.then(function(){
  29438. treeData = addParentPointer(minder);
  29439. renderNodeData(treeData, minder, $curView);
  29440. renderNodeData(treeData, minder, $preView);
  29441. $('#km-list-view').append($curView);
  29442. $('#km-list-view').append($preView);
  29443. $preView.css('x', '100%');
  29444. $('#km-list-view').css('display', 'none');
  29445. });
  29446. });
  29447. var isListView = false; // mutex : 当前是否是列表视图
  29448. $switch.on('click', function(){
  29449. if (!isListView ){
  29450. $('#kityminder').css('display', 'none');
  29451. $('#km-list-view').css('display', 'block');
  29452. isListView = true;
  29453. } else {
  29454. $('#km-list-view').css('display', 'none');
  29455. $('#kityminder').css('display', 'block');
  29456. isListView = false;
  29457. }
  29458. });
  29459. $('#km-list-view').delegate('li', 'click', function(){
  29460. var preViewData = $(this).data();
  29461. if (preViewData.children) {
  29462. renderNodeData(preViewData, minder, $preView);
  29463. // $curView.css('x');
  29464. // console.log($preView.css('x'));
  29465. $preView.css('x', parseInt($curView.css('x')) + 100 + '%');
  29466. // console.log($preView.css('x'));
  29467. // $('#km-list-view').css('x', '0');
  29468. $('#km-list-view').transition({
  29469. x: parseInt($('#km-list-view').css('x')) - 100 + '%',
  29470. duration: 200,
  29471. easing: 'ease',
  29472. complete: function(){
  29473. var $temp = $curView;
  29474. $curView = $preView;
  29475. $preView = $temp;
  29476. }
  29477. });
  29478. if (preViewData.parent){
  29479. $('.back').css('display', 'block');
  29480. $('#km-cat').css('display', 'none');
  29481. }
  29482. }
  29483. });
  29484. $('.back').on('click', function(){
  29485. var parentViewData = $('.cur-root', $curView).data();
  29486. renderNodeData(parentViewData, minder, $preView);
  29487. $preView.css('x', parseInt($curView.css('x')) - 100 + '%');
  29488. // $curView.css('x');
  29489. // $('#km-list-view').css('x', '-100%');
  29490. $('#km-list-view').transition({
  29491. x: parseInt($('#km-list-view').css('x')) + 100 + '%',
  29492. duration: 200,
  29493. easing: 'ease',
  29494. complete: function(){
  29495. var $temp = $curView;
  29496. $curView = $preView;
  29497. $preView = $temp;
  29498. }
  29499. });
  29500. if (!parentViewData.parent){
  29501. $('.back').css('display', 'none');
  29502. $('#km-cat').css('display', 'block');
  29503. }
  29504. })
  29505. return $switch;
  29506. });
  29507. /**
  29508. * addParentPointer - 给 minder 的 json 数据增加 parent 指针
  29509. * @param minder - kityminder 实例
  29510. * @returns {*} - 增加了 parent 指针之后的 json 结构
  29511. */
  29512. function addParentPointer(minder){
  29513. var root = minder.exportJson();
  29514. return AddParent(root);
  29515. }
  29516. /**
  29517. * AddParent - 递归的增加 parent 指针
  29518. * @param root - 传入的根节点
  29519. * @returns {*}
  29520. */
  29521. function AddParent(root){
  29522. if (root.children){
  29523. $.each(root.children, function(idx, ele){
  29524. ele.parent = root;
  29525. AddParent(ele);
  29526. });
  29527. }
  29528. return root;
  29529. }
  29530. /**
  29531. * creadNodeData - 根据 json 结构创建好视图的 jQuery 对象
  29532. * @param node
  29533. * @param minder
  29534. * @returns {*} - 创建好的 jQuery 对象
  29535. */
  29536. function renderNodeData(node, minder, $target){
  29537. var $curRoot = createRootNode(node, minder);
  29538. var $curList = $('<ul class="cur-list">');
  29539. if (node.children){
  29540. $.each(node.children, function(idx, ele){
  29541. var $listNode = createListNode(ele, minder);
  29542. $curList.append($listNode);
  29543. });
  29544. }
  29545. // debugger;
  29546. return $target.html($curRoot.add($curList));
  29547. }
  29548. /**
  29549. * createRootNode - 创建当前根节点对应的 jQuery 对象
  29550. * @param node 节点的 jQuery 对象
  29551. * @param minder kityminder 实例
  29552. * @returns {*|jQuery|HTMLElement} 当前根节点的 jQuery 对象
  29553. */
  29554. function createRootNode(node, minder){
  29555. var $root = $('<h1 class="cur-root">');
  29556. $root.append(getNodeHtml(node, minder));
  29557. if (node.parent){
  29558. $root.data(node.parent);
  29559. }
  29560. return $root;
  29561. }
  29562. /**
  29563. * createListNode - 创建子节点对应的 jQuery 对象
  29564. * @param node 节点的 json 对象
  29565. * @param minder kityminder 实例
  29566. * @returns {*|jQuery|HTMLElement} 子节点的 jQuery 对象
  29567. */
  29568. function createListNode(node, minder){
  29569. var $list = $('<li>');
  29570. $list.append(getNodeHtml(node, minder));
  29571. // 处理子节点
  29572. if (node.children){
  29573. $list.addClass('clickable');
  29574. $list.children().first().before('<span class="next-level"></span>');
  29575. $list.data(node);
  29576. }
  29577. return $list;
  29578. }
  29579. /**
  29580. * getNodeHtml - 根据传入节点的 json 对象创建该节点的 html 数据
  29581. * @param node 节点的 json 对象
  29582. * @param minder kityminder 实例
  29583. * @returns {string} 返回的 html 字符串
  29584. */
  29585. function getNodeHtml (node, minder){
  29586. var data = node.data;
  29587. var html = '';
  29588. // 处理优先级
  29589. if (data.priority){
  29590. html += '<div class="priority priority-' + data.priority + '"></div>'
  29591. }
  29592. // 处理进度
  29593. if (data.progress){
  29594. html += '<div class="progress progress-' + data.progress + '"></div>'
  29595. }
  29596. // 处理超链接
  29597. if (data.hyperlink) {
  29598. html +='<a class="hyperlink" href="'+ data.hyperlink +'" target="_blank"></a>';
  29599. }
  29600. // 处理资源
  29601. if (data.resource){
  29602. $.each(data.resource, function(idx, ele){
  29603. html += '<span class="resource" style="background-color: '+ minder.getResourceColor(ele).toRGB() +'">' + ele + '</span>' + ' ';
  29604. });
  29605. }
  29606. // 处理文字
  29607. if (data.text) {
  29608. html += '<span class="text">' + (data.text || '') + '</span>';
  29609. }
  29610. return html;
  29611. }
  29612. /**
  29613. * @fileOverview
  29614. *
  29615. * 移动端分享页面加载 logo 功能
  29616. *
  29617. * @author: zhangbobell
  29618. * @copyright: Baidu FEX, 2014
  29619. */
  29620. KityMinder.registerUI('topbar/m-logo', function(minder) {
  29621. var $logoSvg = $('<svg id="km-cat" viewBox="0 0 1200 1200" width="32px" height="32px"><g id="cat-face"><path d="M1066.769,368.482L1119.5,80L830,131.611C760.552,97.29,682.35,77.999,599.641,77.999c-82.424,0-160.371,19.161-229.641,53.26L81,81l50.769,289l0,0c-33.792,69.019-52.77,146.612-52.77,228.641c0,287.542,233.099,520.642,520.642,520.642s520.642-233.099,520.642-520.642C1120.282,516.011,1101.028,437.88,1066.769,368.482z"/></g><g id="cat-eye"><path style="fill:#FFFFFF;" d="M920.255,371C794.746,371,693,472.746,693,598.255s101.746,227.255,227.255,227.255s227.255-101.746,227.255-227.255S1045.765,371,920.255,371z M920,746c-80.081,0-145-64.919-145-145s64.919-145,145-145s145,64.919,145,145S1000.081,746,920,746z"/><path style="fill:#FFFFFF;" d="M276.255,371C150.746,371,49,472.746,49,598.255s101.746,227.255,227.255,227.255s227.255-101.746,227.255-227.255S401.765,371,276.255,371z M276,745c-80.081,0-145-64.919-145-145s64.919-145,145-145s145,64.919,145,145S356.081,745,276,745z"/></g></svg>');
  29622. var $mLogo = $logoSvg.appendTo('#m-logo');
  29623. return $mLogo;
  29624. });
  29625. /**
  29626. * @fileOverview
  29627. *
  29628. * 显示并更新脑图文件的标题
  29629. *
  29630. * @author: techird
  29631. * @copyright: Baidu FEX, 2014
  29632. */
  29633. KityMinder.registerUI('topbar/title', function(minder) {
  29634. var $title = $('<h1>').appendTo('#panel');
  29635. var $doc = minder.getUI('doc');
  29636. var finder = minder.getUI('widget/netdiskfinder');
  29637. var notice = minder.getUI('widget/notice');
  29638. var renameEnabled = false;
  29639. var renameMode = false;
  29640. $doc.on('docchange', update);
  29641. $title.on('click', rename);
  29642. function rename() {
  29643. if (!renameEnabled || renameMode) return;
  29644. var doc = $doc.current();
  29645. var $input = $('<input>').width($title.find('.title-content').width());
  29646. var oldFilename = doc.title;
  29647. var oldPath = doc.path;
  29648. $input.val(oldFilename);
  29649. setTimeout(function() {
  29650. $input[0].select();
  29651. });
  29652. $title.addClass('rename-mode');
  29653. $title.empty();
  29654. $title.append($input);
  29655. renameMode = true;
  29656. $input.on('keydown', function(e) {
  29657. if (e.keyCode == 13) confirm();
  29658. else if (e.keyCode == 27) {
  29659. cancel();
  29660. e.stopPropagation();
  29661. }
  29662. }).on('blur', cancel);
  29663. function exit() {
  29664. setTimeout(function() {
  29665. renameMode = false;
  29666. });
  29667. }
  29668. function cancel() {
  29669. update();
  29670. exit();
  29671. }
  29672. function confirm() {
  29673. var newFilename = $input.val();
  29674. var oldFilenameInfo = fio.file.anlysisPath(oldFilename);
  29675. var newFilenameInfo = fio.file.anlysisPath(newFilename);
  29676. if (!newFilenameInfo.name.length) return cancel();
  29677. newFilename = newFilenameInfo.name + oldFilenameInfo.extension;
  29678. var newPath = fio.file.anlysisPath(oldPath).parentPath + newFilename;
  29679. if (newPath == oldPath) return cancel();
  29680. $title.addClass('loading');
  29681. fio.file.move({
  29682. path: oldPath,
  29683. newPath: newPath
  29684. }).then(function() {
  29685. doc.path = newPath;
  29686. doc.title = newFilename;
  29687. finder.fire('mv', oldPath, newPath);
  29688. notice.info(minder.getLang('ui.rename_success', newFilename));
  29689. })['catch'](function(e) {
  29690. notice.error('err_rename', e);
  29691. }).then(function() {
  29692. $title.removeClass('loading');
  29693. update();
  29694. exit();
  29695. });
  29696. }
  29697. }
  29698. function enableRename(enabled) {
  29699. renameEnabled = enabled;
  29700. if (enabled) $title.addClass('rename-enabled');
  29701. else $title.removeClass('rename-enabled');
  29702. }
  29703. function update() {
  29704. var doc = $doc.current();
  29705. function setTitle(title) {
  29706. if (setTitle.lastValue == title) return;
  29707. title = title || minder.getLang('ui.untitleddoc');
  29708. $title.empty().append($('<span class="title-content"></span>').text(title));
  29709. document.title = title ? title + ' - 众核脑图' : '众核脑图';
  29710. setTitle.lastValue = title;
  29711. }
  29712. if (doc.saved) {
  29713. setTitle(doc.title);
  29714. } else {
  29715. setTitle('* ' + doc.title);
  29716. }
  29717. enableRename(doc.source == 'netdisk' && doc.saved);
  29718. }
  29719. update();
  29720. return {
  29721. $title: $title,
  29722. getTitle: function() {
  29723. return $doc.current().title;
  29724. }
  29725. };
  29726. });
  29727. })(window)
  29728. //# sourceMappingURL=kityminder.m-share.js.map