| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455 | 
							- /*
 
- Copyright 2012, KISSY UI Library v1.20
 
- MIT Licensed
 
- build time: Feb 8 17:28
 
- */
 
- /*
 
-  * a seed where KISSY grows up from , KISS Yeah !
 
-  * @author lifesinger@gmail.com,yiminghe@gmail.com
 
-  */
 
- (function (S, undefined) {
 
-     /**
 
-      * @namespace KISSY
 
-      */
 
-     var host = this,
 
-         meta = {
 
-             /**
 
-              * Copies all the properties of s to r.
 
-              * @param deep {boolean} whether recursive mix if encounter object
 
-              * @return {Object} the augmented object
 
-              */
 
-             mix:function (r, s, ov, wl, deep) {
 
-                 if (!s || !r) {
 
-                     return r;
 
-                 }
 
-                 if (ov === undefined) {
 
-                     ov = true;
 
-                 }
 
-                 var i, p, len;
 
-                 if (wl && (len = wl.length)) {
 
-                     for (i = 0; i < len; i++) {
 
-                         p = wl[i];
 
-                         if (p in s) {
 
-                             _mix(p, r, s, ov, deep);
 
-                         }
 
-                     }
 
-                 } else {
 
-                     for (p in s) {
 
-                         _mix(p, r, s, ov, deep);
 
-                     }
 
-                 }
 
-                 return r;
 
-             }
 
-         },
 
-         _mix = function (p, r, s, ov, deep) {
 
-             if (ov || !(p in r)) {
 
-                 var target = r[p], src = s[p];
 
-                 // prevent never-end loop
 
-                 if (target === src) {
 
-                     return;
 
-                 }
 
-                 // 来源是数组和对象,并且要求深度 mix
 
-                 if (deep && src && (S.isArray(src) || S.isPlainObject(src))) {
 
-                     // 目标值为对象或数组,直接 mix
 
-                     // 否则 新建一个和源值类型一样的空数组/对象,递归 mix
 
-                     var clone = target && (S.isArray(target) || S.isPlainObject(target)) ?
 
-                         target :
 
-                         (S.isArray(src) ? [] : {});
 
-                     r[p] = S.mix(clone, src, ov, undefined, true);
 
-                 } else if (src !== undefined) {
 
-                     r[p] = s[p];
 
-                 }
 
-             }
 
-         },
 
-         // If KISSY is already defined, the existing KISSY object will not
 
-         // be overwritten so that defined namespaces are preserved.
 
-         seed = (host && host[S]) || {},
 
-         guid = 0,
 
-         EMPTY = '';
 
-     // The host of runtime environment. specify by user's seed or <this>,
 
-     // compatibled for  '<this> is null' in unknown engine.
 
-     host = seed.__HOST || (seed.__HOST = host || {});
 
-     // shortcut and meta for seed.
 
-     // override previous kissy
 
-     S = host[S] = meta.mix(seed, meta);
 
-     S.mix(S, {
 
-         configs:{},
 
-         // S.app() with these members.
 
-         __APP_MEMBERS:['namespace'],
 
-         __APP_INIT_METHODS:['__init'],
 
-         /**
 
-          * The version of the library.
 
-          * @type {String}
 
-          */
 
-         version:'1.20',
 
-         buildTime:'20120208172832',
 
-         /**
 
-          * Returns a new object containing all of the properties of
 
-          * all the supplied objects. The properties from later objects
 
-          * will overwrite those in earlier objects. Passing in a
 
-          * single object will create a shallow copy of it.
 
-          * @return {Object} the new merged object
 
-          */
 
-         merge:function () {
 
-             var o = {}, i, l = arguments.length;
 
-             for (i = 0; i < l; i++) {
 
-                 S.mix(o, arguments[i]);
 
-             }
 
-             return o;
 
-         },
 
-         /**
 
-          * Applies prototype properties from the supplier to the receiver.
 
-          * @return {Object} the augmented object
 
-          */
 
-         augment:function (/*r, s1, s2, ..., ov, wl*/) {
 
-             var args = S.makeArray(arguments),
 
-                 len = args.length - 2,
 
-                 r = args[0],
 
-                 ov = args[len],
 
-                 wl = args[len + 1],
 
-                 i = 1;
 
-             if (!S.isArray(wl)) {
 
-                 ov = wl;
 
-                 wl = undefined;
 
-                 len++;
 
-             }
 
-             if (!S.isBoolean(ov)) {
 
-                 ov = undefined;
 
-                 len++;
 
-             }
 
-             for (; i < len; i++) {
 
-                 S.mix(r.prototype, args[i].prototype || args[i], ov, wl);
 
-             }
 
-             return r;
 
-         },
 
-         /**
 
-          * Utility to set up the prototype, constructor and superclass properties to
 
-          * support an inheritance strategy that can chain constructors and methods.
 
-          * Static members will not be inherited.
 
-          * @param r {Function} the object to modify
 
-          * @param s {Function} the object to inherit
 
-          * @param px {Object} prototype properties to add/override
 
-          * @param {Object} [sx] static properties to add/override
 
-          * @return r {Object}
 
-          */
 
-         extend:function (r, s, px, sx) {
 
-             if (!s || !r) {
 
-                 return r;
 
-             }
 
-             var create = Object.create ?
 
-                 function (proto, c) {
 
-                     return Object.create(proto, {
 
-                         constructor:{
 
-                             value:c
 
-                         }
 
-                     });
 
-                 } :
 
-                 function (proto, c) {
 
-                     function F() {
 
-                     }
 
-                     F.prototype = proto;
 
-                     var o = new F();
 
-                     o.constructor = c;
 
-                     return o;
 
-                 },
 
-                 sp = s.prototype,
 
-                 rp;
 
-             // add prototype chain
 
-             rp = create(sp, r);
 
-             r.prototype = S.mix(rp, r.prototype);
 
-             r.superclass = create(sp, s);
 
-             // add prototype overrides
 
-             if (px) {
 
-                 S.mix(rp, px);
 
-             }
 
-             // add object overrides
 
-             if (sx) {
 
-                 S.mix(r, sx);
 
-             }
 
-             return r;
 
-         },
 
-         /****************************************************************************************
 
-          *                            The KISSY System Framework                                *
 
-          ****************************************************************************************/
 
-         /**
 
-          * Initializes KISSY
 
-          */
 
-         __init:function () {
 
-             this.Config = this.Config || {};
 
-             this.Env = this.Env || {};
 
-             // NOTICE: '@DEBUG@' will replace with '' when compressing.
 
-             // So, if loading source file, debug is on by default.
 
-             // If loading min version, debug is turned off automatically.
 
-             this.Config.debug = '@DEBUG@';
 
-         },
 
-         /**
 
-          * Returns the namespace specified and creates it if it doesn't exist. Be careful
 
-          * when naming packages. Reserved words may work in some browsers and not others.
 
-          * <code>
 
-          * S.namespace('KISSY.app'); // returns KISSY.app
 
-          * S.namespace('app.Shop'); // returns KISSY.app.Shop
 
-          * S.namespace('TB.app.Shop', true); // returns TB.app.Shop
 
-          * </code>
 
-          * @return {Object}  A reference to the last namespace object created
 
-          */
 
-         namespace:function () {
 
-             var args = S.makeArray(arguments),
 
-                 l = args.length,
 
-                 o = null, i, j, p,
 
-                 global = (args[l - 1] === true && l--);
 
-             for (i = 0; i < l; i++) {
 
-                 p = (EMPTY + args[i]).split('.');
 
-                 o = global ? host : this;
 
-                 for (j = (host[p[0]] === o) ? 1 : 0; j < p.length; ++j) {
 
-                     o = o[p[j]] = o[p[j]] || { };
 
-                 }
 
-             }
 
-             return o;
 
-         },
 
-         /**
 
-          * create app based on KISSY.
 
-          * @param name {String} the app name
 
-          * @param sx {Object} static properties to add/override
 
-          * <code>
 
-          * S.app('TB');
 
-          * TB.namespace('app'); // returns TB.app
 
-          * </code>
 
-          * @return {Object}  A reference to the app global object
 
-          */
 
-         app:function (name, sx) {
 
-             var isStr = S.isString(name),
 
-                 O = isStr ? host[name] || {} : name,
 
-                 i = 0,
 
-                 len = S.__APP_INIT_METHODS.length;
 
-             S.mix(O, this, true, S.__APP_MEMBERS);
 
-             for (; i < len; i++) {
 
-                 S[S.__APP_INIT_METHODS[i]].call(O);
 
-             }
 
-             S.mix(O, S.isFunction(sx) ? sx() : sx);
 
-             isStr && (host[name] = O);
 
-             return O;
 
-         },
 
-         config:function (c) {
 
-             var configs, cfg, r;
 
-             for (var p in c) {
 
-                 if (c.hasOwnProperty(p)) {
 
-                     if ((configs = this['configs']) &&
 
-                         (cfg = configs[p])) {
 
-                         r = cfg(c[p]);
 
-                     }
 
-                 }
 
-             }
 
-             return r;
 
-         },
 
-         /**
 
-          * Prints debug info.
 
-          * @param msg {String} the message to log.
 
-          * @param {String} [cat] the log category for the message. Default
 
-          *        categories are "info", "warn", "error", "time" etc.
 
-          * @param {String} [src] the source of the the message (opt)
 
-          */
 
-         log:function (msg, cat, src) {
 
-             if (S.Config.debug) {
 
-                 if (src) {
 
-                     msg = src + ': ' + msg;
 
-                 }
 
-                 if (host['console'] !== undefined && console.log) {
 
-                     console[cat && console[cat] ? cat : 'log'](msg);
 
-                 }
 
-             }
 
-         },
 
-         /**
 
-          * Throws error message.
 
-          */
 
-         error:function (msg) {
 
-             if (S.Config.debug) {
 
-                 throw msg;
 
-             }
 
-         },
 
-         /*
 
-          * Generate a global unique id.
 
-          * @param {String} [pre] guid prefix
 
-          * @return {String} the guid
 
-          */
 
-         guid:function (pre) {
 
-             return (pre || EMPTY) + guid++;
 
-         }
 
-     });
 
-     S.__init();
 
-     return S;
 
- })('KISSY', undefined);
 
- /**
 
-  * @module  lang
 
-  * @author  lifesinger@gmail.com,yiminghe@gmail.com
 
-  * @description this code can run in any ecmascript compliant environment
 
-  */
 
- (function (S, undefined) {
 
-     var host = S.__HOST,
 
-         TRUE = true,
 
-         FALSE = false,
 
-         OP = Object.prototype,
 
-         toString = OP.toString,
 
-         hasOwnProperty = OP.hasOwnProperty,
 
-         AP = Array.prototype,
 
-         indexOf = AP.indexOf,
 
-         lastIndexOf = AP.lastIndexOf,
 
-         filter = AP.filter,
 
-         every = AP.every,
 
-         some = AP.some,
 
-         //reduce = AP.reduce,
 
-         trim = String.prototype.trim,
 
-         map = AP.map,
 
-         EMPTY = '',
 
-         HEX_BASE = 16,
 
-         CLONE_MARKER = '__~ks_cloned',
 
-         COMPARE_MARKER = '__~ks_compared',
 
-         STAMP_MARKER = '__~ks_stamped',
 
-         RE_TRIM = /^[\s\xa0]+|[\s\xa0]+$/g,
 
-         encode = encodeURIComponent,
 
-         decode = decodeURIComponent,
 
-         SEP = '&',
 
-         EQ = '=',
 
-         // [[Class]] -> type pairs
 
-         class2type = {},
 
-         // http://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
 
-         htmlEntities = {
 
-             '&':'&',
 
-             '>':'>',
 
-             '<':'<',
 
-             '`':'`',
 
-             '/':'/',
 
-             '"':'"',
 
-             ''':"'"
 
-         },
 
-         reverseEntities = {},
 
-         escapeReg,
 
-         unEscapeReg,
 
-         // - # $ ^ * ( ) + [ ] { } | \ , . ?
 
-         escapeRegExp = /[\-#$\^*()+\[\]{}|\\,.?\s]/g;
 
-     (function () {
 
-         for (var k in htmlEntities) {
 
-             if (htmlEntities.hasOwnProperty(k)) {
 
-                 reverseEntities[htmlEntities[k]] = k;
 
-             }
 
-         }
 
-     })();
 
-     function getEscapeReg() {
 
-         if (escapeReg) {
 
-             return escapeReg
 
-         }
 
-         var str = EMPTY;
 
-         S.each(htmlEntities, function (entity) {
 
-             str += entity + '|';
 
-         });
 
-         str = str.slice(0, -1);
 
-         return escapeReg = new RegExp(str, "g");
 
-     }
 
-     function getUnEscapeReg() {
 
-         if (unEscapeReg) {
 
-             return unEscapeReg
 
-         }
 
-         var str = EMPTY;
 
-         S.each(reverseEntities, function (entity) {
 
-             str += entity + '|';
 
-         });
 
-         str += '&#(\\d{1,5});';
 
-         return unEscapeReg = new RegExp(str, "g");
 
-     }
 
-     function isValidParamValue(val) {
 
-         var t = typeof val;
 
-         // If the type of val is null, undefined, number, string, boolean, return true.
 
-         return nullOrUndefined(val) || (t !== 'object' && t !== 'function');
 
-     }
 
-     S.mix(S, {
 
-         /**
 
-          * stamp a object by guid
 
-          * @return guid associated with this object
 
-          */
 
-         stamp:function (o, readOnly, marker) {
 
-             if (!o) {
 
-                 return o
 
-             }
 
-             marker = marker || STAMP_MARKER;
 
-             var guid = o[marker];
 
-             if (guid) {
 
-                 return guid;
 
-             } else if (!readOnly) {
 
-                 try {
 
-                     guid = o[marker] = S.guid(marker);
 
-                 }
 
-                 catch (e) {
 
-                     guid = undefined;
 
-                 }
 
-             }
 
-             return guid;
 
-         },
 
-         noop:function () {
 
-         },
 
-         /**
 
-          * Determine the internal JavaScript [[Class]] of an object.
 
-          */
 
-         type:function (o) {
 
-             return nullOrUndefined(o) ?
 
-                 String(o) :
 
-                 class2type[toString.call(o)] || 'object';
 
-         },
 
-         isNullOrUndefined:nullOrUndefined,
 
-         isNull:function (o) {
 
-             return o === null;
 
-         },
 
-         isUndefined:function (o) {
 
-             return o === undefined;
 
-         },
 
-         /**
 
-          * Checks to see if an object is empty.
 
-          */
 
-         isEmptyObject:function (o) {
 
-             for (var p in o) {
 
-                 if (p !== undefined) {
 
-                     return FALSE;
 
-                 }
 
-             }
 
-             return TRUE;
 
-         },
 
-         /**
 
-          * Checks to see if an object is a plain object (created using "{}"
 
-          * or "new Object()" or "new FunctionClass()").
 
-          * Ref: http://lifesinger.org/blog/2010/12/thinking-of-isplainobject/
 
-          */
 
-         isPlainObject:function (o) {
 
-             /**
 
-              * note by yiminghe
 
-              * isPlainObject(node=document.getElementById("xx")) -> false
 
-              * toString.call(node) : ie678 == '[object Object]',other =='[object HTMLElement]'
 
-              * 'isPrototypeOf' in node : ie678 === false ,other === true
 
-              */
 
-             return o && toString.call(o) === '[object Object]' && 'isPrototypeOf' in o;
 
-         },
 
-         /**
 
-          * 两个目标是否内容相同
 
-          *
 
-          * @param a 比较目标1
 
-          * @param b 比较目标2
 
-          * @param [mismatchKeys] internal use
 
-          * @param [mismatchValues] internal use
 
-          */
 
-         equals:function (a, b, /*internal use*/mismatchKeys, /*internal use*/mismatchValues) {
 
-             // inspired by jasmine
 
-             mismatchKeys = mismatchKeys || [];
 
-             mismatchValues = mismatchValues || [];
 
-             if (a === b) {
 
-                 return TRUE;
 
-             }
 
-             if (a === undefined || a === null || b === undefined || b === null) {
 
-                 // need type coercion
 
-                 return nullOrUndefined(a) && nullOrUndefined(b);
 
-             }
 
-             if (a instanceof Date && b instanceof Date) {
 
-                 return a.getTime() == b.getTime();
 
-             }
 
-             if (S.isString(a) && S.isString(b)) {
 
-                 return (a == b);
 
-             }
 
-             if (S.isNumber(a) && S.isNumber(b)) {
 
-                 return (a == b);
 
-             }
 
-             if (typeof a === "object" && typeof b === "object") {
 
-                 return compareObjects(a, b, mismatchKeys, mismatchValues);
 
-             }
 
-             // Straight check
 
-             return (a === b);
 
-         },
 
-         /**
 
-          * Creates a deep copy of a plain object or array. Others are returned untouched.
 
-          * 稍微改改就和规范一样了 :)
 
-          * @param input
 
-          * @param {Function} filter filter function
 
-          * @refer http://www.w3.org/TR/html5/common-dom-interfaces.html#safe-passing-of-structured-data
 
-          */
 
-         clone:function (input, filter) {
 
-             // Let memory be an association list of pairs of objects,
 
-             // initially empty. This is used to handle duplicate references.
 
-             // In each pair of objects, one is called the source object
 
-             // and the other the destination object.
 
-             var memory = {},
 
-                 ret = cloneInternal(input, filter, memory);
 
-             S.each(memory, function (v) {
 
-                 // 清理在源对象上做的标记
 
-                 v = v.input;
 
-                 if (v[CLONE_MARKER]) {
 
-                     try {
 
-                         delete v[CLONE_MARKER];
 
-                     } catch (e) {
 
-                         S.log("delete CLONE_MARKER error : ");
 
-                         v[CLONE_MARKER] = undefined;
 
-                     }
 
-                 }
 
-             });
 
-             memory = null;
 
-             return ret;
 
-         },
 
-         /**
 
-          * Removes the whitespace from the beginning and end of a string.
 
-          */
 
-         trim:trim ?
 
-             function (str) {
 
-                 return nullOrUndefined(str) ? EMPTY : trim.call(str);
 
-             } :
 
-             function (str) {
 
-                 return nullOrUndefined(str) ? EMPTY : str.toString().replace(RE_TRIM, EMPTY);
 
-             },
 
-         /**
 
-          * Substitutes keywords in a string using an object/array.
 
-          * Removes undefined keywords and ignores escaped keywords.
 
-          */
 
-         substitute:function (str, o, regexp) {
 
-             if (!S.isString(str)
 
-                 || !S.isPlainObject(o)) {
 
-                 return str;
 
-             }
 
-             return str.replace(regexp || /\\?\{([^{}]+)\}/g, function (match, name) {
 
-                 if (match.charAt(0) === '\\') {
 
-                     return match.slice(1);
 
-                 }
 
-                 return (o[name] === undefined) ? EMPTY : o[name];
 
-             });
 
-         },
 
-         /**
 
-          * Executes the supplied function on each item in the array.
 
-          * @param object {Object} the object to iterate
 
-          * @param fn {Function} the function to execute on each item. The function
 
-          *        receives three arguments: the value, the index, the full array.
 
-          * @param {Object} [context]
 
-          */
 
-         each:function (object, fn, context) {
 
-             if (object) {
 
-                 var key,
 
-                     val,
 
-                     i = 0,
 
-                     length = object && object.length,
 
-                     isObj = length === undefined || S.type(object) === 'function';
 
-                 context = context || host;
 
-                 if (isObj) {
 
-                     for (key in object) {
 
-                         // can not use hasOwnProperty
 
-                         if (fn.call(context, object[key], key, object) === FALSE) {
 
-                             break;
 
-                         }
 
-                     }
 
-                 } else {
 
-                     for (val = object[0];
 
-                          i < length && fn.call(context, val, i, object) !== FALSE; val = object[++i]) {
 
-                     }
 
-                 }
 
-             }
 
-             return object;
 
-         },
 
-         /**
 
-          * Search for a specified value within an array.
 
-          */
 
-         indexOf:indexOf ?
 
-             function (item, arr) {
 
-                 return indexOf.call(arr, item);
 
-             } :
 
-             function (item, arr) {
 
-                 for (var i = 0, len = arr.length; i < len; ++i) {
 
-                     if (arr[i] === item) {
 
-                         return i;
 
-                     }
 
-                 }
 
-                 return -1;
 
-             },
 
-         /**
 
-          * Returns the index of the last item in the array
 
-          * that contains the specified value, -1 if the
 
-          * value isn't found.
 
-          */
 
-         lastIndexOf:(lastIndexOf) ?
 
-             function (item, arr) {
 
-                 return lastIndexOf.call(arr, item);
 
-             } :
 
-             function (item, arr) {
 
-                 for (var i = arr.length - 1; i >= 0; i--) {
 
-                     if (arr[i] === item) {
 
-                         break;
 
-                     }
 
-                 }
 
-                 return i;
 
-             },
 
-         /**
 
-          * Returns a copy of the array with the duplicate entries removed
 
-          * @param a {Array} the array to find the subset of uniques for
 
-          * @param override {Boolean}
 
-          *        if override is true, S.unique([a, b, a]) => [b, a]
 
-          *        if override is false, S.unique([a, b, a]) => [a, b]
 
-          * @return {Array} a copy of the array with duplicate entries removed
 
-          */
 
-         unique:function (a, override) {
 
-             var b = a.slice();
 
-             if (override) {
 
-                 b.reverse();
 
-             }
 
-             var i = 0,
 
-                 n,
 
-                 item;
 
-             while (i < b.length) {
 
-                 item = b[i];
 
-                 while ((n = S.lastIndexOf(item, b)) !== i) {
 
-                     b.splice(n, 1);
 
-                 }
 
-                 i += 1;
 
-             }
 
-             if (override) {
 
-                 b.reverse();
 
-             }
 
-             return b;
 
-         },
 
-         /**
 
-          * Search for a specified value index within an array.
 
-          */
 
-         inArray:function (item, arr) {
 
-             return S.indexOf(item, arr) > -1;
 
-         },
 
-         /**
 
-          * Executes the supplied function on each item in the array.
 
-          * Returns a new array containing the items that the supplied
 
-          * function returned true for.
 
-          * @param arr {Array} the array to iterate
 
-          * @param fn {Function} the function to execute on each item
 
-          * @param context {Object} optional context object
 
-          * @return {Array} The items on which the supplied function
 
-          *         returned true. If no items matched an empty array is
 
-          *         returned.
 
-          */
 
-         filter:filter ?
 
-             function (arr, fn, context) {
 
-                 return filter.call(arr, fn, context || this);
 
-             } :
 
-             function (arr, fn, context) {
 
-                 var ret = [];
 
-                 S.each(arr, function (item, i, arr) {
 
-                     if (fn.call(context || this, item, i, arr)) {
 
-                         ret.push(item);
 
-                     }
 
-                 });
 
-                 return ret;
 
-             },
 
-         // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map
 
-         map:map ?
 
-             function (arr, fn, context) {
 
-                 return map.call(arr, fn, context || this);
 
-             } :
 
-             function (arr, fn, context) {
 
-                 var len = arr.length,
 
-                     res = new Array(len);
 
-                 for (var i = 0; i < len; i++) {
 
-                     var el = S.isString(arr) ? arr.charAt(i) : arr[i];
 
-                     if (el
 
-                         ||
 
-                         //ie<9 in invalid when typeof arr == string
 
-                         i in arr) {
 
-                         res[i] = fn.call(context || this, el, i, arr);
 
-                     }
 
-                 }
 
-                 return res;
 
-             },
 
-         /**
 
-          * @refer  https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/reduce
 
-          */
 
-         reduce:/*
 
-          NaN ?
 
-          reduce ? function(arr, callback, initialValue) {
 
-          return arr.reduce(callback, initialValue);
 
-          } : */function (arr, callback, initialValue) {
 
-             var len = arr.length;
 
-             if (typeof callback !== "function") {
 
-                 throw new TypeError("callback is not function!");
 
-             }
 
-             // no value to return if no initial value and an empty array
 
-             if (len === 0 && arguments.length == 2) {
 
-                 throw new TypeError("arguments invalid");
 
-             }
 
-             var k = 0;
 
-             var accumulator;
 
-             if (arguments.length >= 3) {
 
-                 accumulator = arguments[2];
 
-             }
 
-             else {
 
-                 do {
 
-                     if (k in arr) {
 
-                         accumulator = arr[k++];
 
-                         break;
 
-                     }
 
-                     // if array contains no values, no initial value to return
 
-                     k += 1;
 
-                     if (k >= len) {
 
-                         throw new TypeError();
 
-                     }
 
-                 }
 
-                 while (TRUE);
 
-             }
 
-             while (k < len) {
 
-                 if (k in arr) {
 
-                     accumulator = callback.call(undefined, accumulator, arr[k], k, arr);
 
-                 }
 
-                 k++;
 
-             }
 
-             return accumulator;
 
-         },
 
-         every:every ?
 
-             function (arr, fn, context) {
 
-                 return every.call(arr, fn, context || this);
 
-             } :
 
-             function (arr, fn, context) {
 
-                 var len = arr && arr.length || 0;
 
-                 for (var i = 0; i < len; i++) {
 
-                     if (i in arr && !fn.call(context, arr[i], i, arr)) {
 
-                         return FALSE;
 
-                     }
 
-                 }
 
-                 return TRUE;
 
-             },
 
-         some:some ?
 
-             function (arr, fn, context) {
 
-                 return some.call(arr, fn, context || this);
 
-             } :
 
-             function (arr, fn, context) {
 
-                 var len = arr && arr.length || 0;
 
-                 for (var i = 0; i < len; i++) {
 
-                     if (i in arr && fn.call(context, arr[i], i, arr)) {
 
-                         return TRUE;
 
-                     }
 
-                 }
 
-                 return FALSE;
 
-             },
 
-         /**
 
-          * it is not same with native bind
 
-          * @refer https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
 
-          */
 
-         bind:function (fn, obj) {
 
-             var slice = [].slice,
 
-                 args = slice.call(arguments, 2),
 
-                 fNOP = function () {
 
-                 },
 
-                 bound = function () {
 
-                     return fn.apply(this instanceof fNOP ? this : obj,
 
-                         args.concat(slice.call(arguments)));
 
-                 };
 
-             fNOP.prototype = fn.prototype;
 
-             bound.prototype = new fNOP();
 
-             return bound;
 
-         },
 
-         /**
 
-          * Gets current date in milliseconds.
 
-          * @refer  https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/now
 
-          * http://j-query.blogspot.com/2011/02/timing-ecmascript-5-datenow-function.html
 
-          * http://kangax.github.com/es5-compat-table/
 
-          */
 
-         now:Date.now || function () {
 
-             return +new Date();
 
-         },
 
-         /**
 
-          * frequently used in taobao cookie about nick
 
-          */
 
-         fromUnicode:function (str) {
 
-             return str.replace(/\\u([a-f\d]{4})/ig, function (m, u) {
 
-                 return  String.fromCharCode(parseInt(u, HEX_BASE));
 
-             });
 
-         },
 
-         /**
 
-          * escape string to html
 
-          * @refer   http://yiminghe.javaeye.com/blog/788929
 
-          *          http://wonko.com/post/html-escaping
 
-          * @param str {string} text2html show
 
-          */
 
-         escapeHTML:function (str) {
 
-             return str.replace(getEscapeReg(), function (m) {
 
-                 return reverseEntities[m];
 
-             });
 
-         },
 
-         escapeRegExp:function (str) {
 
-             return str.replace(escapeRegExp, '\\$&');
 
-         },
 
-         /**
 
-          * unescape html to string
 
-          * @param str {string} html2text
 
-          */
 
-         unEscapeHTML:function (str) {
 
-             return str.replace(getUnEscapeReg(), function (m, n) {
 
-                 return htmlEntities[m] || String.fromCharCode(+n);
 
-             });
 
-         },
 
-         /**
 
-          * Converts object to a true array.
 
-          * @param o {object|Array} array like object or array
 
-          * @return {Array}
 
-          */
 
-         makeArray:function (o) {
 
-             if (nullOrUndefined(o)) {
 
-                 return [];
 
-             }
 
-             if (S.isArray(o)) {
 
-                 return o;
 
-             }
 
-             // The strings and functions also have 'length'
 
-             if (typeof o.length !== 'number' || S.isString(o) || S.isFunction(o)) {
 
-                 return [o];
 
-             }
 
-             var ret = [];
 
-             for (var i = 0, l = o.length; i < l; i++) {
 
-                 ret[i] = o[i];
 
-             }
 
-             return ret;
 
-         },
 
-         /**
 
-          * Creates a serialized string of an array or object.
 
-          * @return {String}
 
-          * <code>
 
-          * {foo: 1, bar: 2}    // -> 'foo=1&bar=2'
 
-          * {foo: 1, bar: [2, 3]}    // -> 'foo=1&bar=2&bar=3'
 
-          * {foo: '', bar: 2}    // -> 'foo=&bar=2'
 
-          * {foo: undefined, bar: 2}    // -> 'foo=undefined&bar=2'
 
-          * {foo: true, bar: 2}    // -> 'foo=true&bar=2'
 
-          * </code>
 
-          */
 
-         param:function (o, sep, eq, arr) {
 
-             if (!S.isPlainObject(o)) {
 
-                 return EMPTY;
 
-             }
 
-             sep = sep || SEP;
 
-             eq = eq || EQ;
 
-             if (S.isUndefined(arr)) {
 
-                 arr = TRUE;
 
-             }
 
-             var buf = [], key, val;
 
-             for (key in o) {
 
-                 if (o.hasOwnProperty(key)) {
 
-                     val = o[key];
 
-                     key = encode(key);
 
-                     // val is valid non-array value
 
-                     if (isValidParamValue(val)) {
 
-                         buf.push(key, eq, encode(val + EMPTY), sep);
 
-                     }
 
-                     // val is not empty array
 
-                     else if (S.isArray(val) && val.length) {
 
-                         for (var i = 0, len = val.length; i < len; ++i) {
 
-                             if (isValidParamValue(val[i])) {
 
-                                 buf.push(key,
 
-                                     (arr ? encode("[]") : EMPTY),
 
-                                     eq, encode(val[i] + EMPTY), sep);
 
-                             }
 
-                         }
 
-                     }
 
-                     // ignore other cases, including empty array, Function, RegExp, Date etc.
 
-                 }
 
-             }
 
-             buf.pop();
 
-             return buf.join(EMPTY);
 
-         },
 
-         /**
 
-          * Parses a URI-like query string and returns an object composed of parameter/value pairs.
 
-          * <code>
 
-          * 'section=blog&id=45'        // -> {section: 'blog', id: '45'}
 
-          * 'section=blog&tag=js&tag=doc' // -> {section: 'blog', tag: ['js', 'doc']}
 
-          * 'tag=ruby%20on%20rails'        // -> {tag: 'ruby on rails'}
 
-          * 'id=45&raw'        // -> {id: '45', raw: ''}
 
-          * </code>
 
-          */
 
-         unparam:function (str, sep, eq) {
 
-             if (typeof str !== 'string'
 
-                 || (str = S.trim(str)).length === 0) {
 
-                 return {};
 
-             }
 
-             sep = sep || SEP;
 
-             eq = eq || EQ;
 
-             var ret = {},
 
-                 pairs = str.split(sep),
 
-                 pair, key, val,
 
-                 i = 0, len = pairs.length;
 
-             for (; i < len; ++i) {
 
-                 pair = pairs[i].split(eq);
 
-                 key = decode(pair[0]);
 
-                 try {
 
-                     val = decode(pair[1] || EMPTY);
 
-                 } catch (e) {
 
-                     S.log(e + "decodeURIComponent error : " + pair[1], "error");
 
-                     val = pair[1] || EMPTY;
 
-                 }
 
-                 if (S.endsWith(key, "[]")) {
 
-                     key = key.substring(0, key.length - 2);
 
-                 }
 
-                 if (hasOwnProperty.call(ret, key)) {
 
-                     if (S.isArray(ret[key])) {
 
-                         ret[key].push(val);
 
-                     } else {
 
-                         ret[key] = [ret[key], val];
 
-                     }
 
-                 } else {
 
-                     ret[key] = val;
 
-                 }
 
-             }
 
-             return ret;
 
-         },
 
-         /**
 
-          * Executes the supplied function in the context of the supplied
 
-          * object 'when' milliseconds later. Executes the function a
 
-          * single time unless periodic is set to true.
 
-          * @param fn {Function|String} the function to execute or the name of the method in
 
-          *        the 'o' object to execute.
 
-          * @param when {Number} the number of milliseconds to wait until the fn is executed.
 
-          * @param periodic {Boolean} if true, executes continuously at supplied interval
 
-          *        until canceled.
 
-          * @param context {Object} the context object.
 
-          * @param [data] that is provided to the function. This accepts either a single
 
-          *        item or an array. If an array is provided, the function is executed with
 
-          *        one parameter for each array item. If you need to pass a single array
 
-          *        parameter, it needs to be wrapped in an array [myarray].
 
-          * @return {Object} a timer object. Call the cancel() method on this object to stop
 
-          *         the timer.
 
-          */
 
-         later:function (fn, when, periodic, context, data) {
 
-             when = when || 0;
 
-             var m = fn,
 
-                 d = S.makeArray(data),
 
-                 f,
 
-                 r;
 
-             if (S.isString(fn)) {
 
-                 m = context[fn];
 
-             }
 
-             if (!m) {
 
-                 S.error('method undefined');
 
-             }
 
-             f = function () {
 
-                 m.apply(context, d);
 
-             };
 
-             r = (periodic) ? setInterval(f, when) : setTimeout(f, when);
 
-             return {
 
-                 id:r,
 
-                 interval:periodic,
 
-                 cancel:function () {
 
-                     if (this.interval) {
 
-                         clearInterval(r);
 
-                     } else {
 
-                         clearTimeout(r);
 
-                     }
 
-                 }
 
-             };
 
-         },
 
-         startsWith:function (str, prefix) {
 
-             return str.lastIndexOf(prefix, 0) === 0;
 
-         },
 
-         endsWith:function (str, suffix) {
 
-             var ind = str.length - suffix.length;
 
-             return ind >= 0 && str.indexOf(suffix, ind) == ind;
 
-         },
 
-         /**
 
-          * Based on YUI3
 
-          * Throttles a call to a method based on the time between calls.
 
-          * @param  {function} fn The function call to throttle.
 
-          * @param {object} context ontext fn to run
 
-          * @param {Number} ms The number of milliseconds to throttle the method call.
 
-          *              Passing a -1 will disable the throttle. Defaults to 150.
 
-          * @return {function} Returns a wrapped function that calls fn throttled.
 
-          */
 
-         throttle:function (fn, ms, context) {
 
-             ms = ms || 150;
 
-             if (ms === -1) {
 
-                 return (function () {
 
-                     fn.apply(context || this, arguments);
 
-                 });
 
-             }
 
-             var last = S.now();
 
-             return (function () {
 
-                 var now = S.now();
 
-                 if (now - last > ms) {
 
-                     last = now;
 
-                     fn.apply(context || this, arguments);
 
-                 }
 
-             });
 
-         },
 
-         /**
 
-          * buffers a call between  a fixed time
 
-          * @param {function} fn
 
-          * @param {object} [context]
 
-          * @param {Number} ms
 
-          */
 
-         buffer:function (fn, ms, context) {
 
-             ms = ms || 150;
 
-             if (ms === -1) {
 
-                 return (function () {
 
-                     fn.apply(context || this, arguments);
 
-                 });
 
-             }
 
-             var bufferTimer = null;
 
-             function f() {
 
-                 f.stop();
 
-                 bufferTimer = S.later(fn, ms, FALSE, context || this);
 
-             }
 
-             f.stop = function () {
 
-                 if (bufferTimer) {
 
-                     bufferTimer.cancel();
 
-                     bufferTimer = 0;
 
-                 }
 
-             };
 
-             return f;
 
-         }
 
-     });
 
-     // for idea ..... auto-hint
 
-     S.mix(S, {
 
-         isBoolean:isValidParamValue,
 
-         isNumber:isValidParamValue,
 
-         isString:isValidParamValue,
 
-         isFunction:isValidParamValue,
 
-         isArray:isValidParamValue,
 
-         isDate:isValidParamValue,
 
-         isRegExp:isValidParamValue,
 
-         isObject:isValidParamValue
 
-     });
 
-     S.each('Boolean Number String Function Array Date RegExp Object'.split(' '),
 
-         function (name, lc) {
 
-             // populate the class2type map
 
-             class2type['[object ' + name + ']'] = (lc = name.toLowerCase());
 
-             // add isBoolean/isNumber/...
 
-             S['is' + name] = function (o) {
 
-                 return S.type(o) == lc;
 
-             }
 
-         });
 
-     function nullOrUndefined(o) {
 
-         return S.isNull(o) || S.isUndefined(o);
 
-     }
 
-     function cloneInternal(input, f, memory) {
 
-         var destination = input,
 
-             isArray,
 
-             isPlainObject,
 
-             k,
 
-             stamp;
 
-         if (!input) {
 
-             return destination;
 
-         }
 
-         // If input is the source object of a pair of objects in memory,
 
-         // then return the destination object in that pair of objects .
 
-         // and abort these steps.
 
-         if (input[CLONE_MARKER]) {
 
-             // 对应的克隆后对象
 
-             return memory[input[CLONE_MARKER]].destination;
 
-         } else if (typeof input === "object") {
 
-             // 引用类型要先记录
 
-             var constructor = input.constructor;
 
-             if (S.inArray(constructor, [Boolean, String, Number, Date, RegExp])) {
 
-                 destination = new constructor(input.valueOf());
 
-             }
 
-             // ImageData , File, Blob , FileList .. etc
 
-             else if (isArray = S.isArray(input)) {
 
-                 destination = f ? S.filter(input, f) : input.concat();
 
-             } else if (isPlainObject = S.isPlainObject(input)) {
 
-                 destination = {};
 
-             }
 
-             // Add a mapping from input (the source object)
 
-             // to output (the destination object) to memory.
 
-             // 做标记
 
-             input[CLONE_MARKER] = (stamp = S.guid());
 
-             // 存储源对象以及克隆后的对象
 
-             memory[stamp] = {destination:destination, input:input};
 
-         }
 
-         // If input is an Array object or an Object object,
 
-         // then, for each enumerable property in input,
 
-         // add a new property to output having the same name,
 
-         // and having a value created from invoking the internal structured cloning algorithm recursively
 
-         // with the value of the property as the "input" argument and memory as the "memory" argument.
 
-         // The order of the properties in the input and output objects must be the same.
 
-         // clone it
 
-         if (isArray) {
 
-             for (var i = 0; i < destination.length; i++) {
 
-                 destination[i] = cloneInternal(destination[i], f, memory);
 
-             }
 
-         } else if (isPlainObject) {
 
-             for (k in input) {
 
-                 if (input.hasOwnProperty(k)) {
 
-                     if (k !== CLONE_MARKER &&
 
-                         (!f || (f.call(input, input[k], k, input) !== FALSE))) {
 
-                         destination[k] = cloneInternal(input[k], f, memory);
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-         return destination;
 
-     }
 
-     function compareObjects(a, b, mismatchKeys, mismatchValues) {
 
-         // 两个比较过了,无需再比较,防止循环比较
 
-         if (a[COMPARE_MARKER] === b && b[COMPARE_MARKER] === a) {
 
-             return TRUE;
 
-         }
 
-         a[COMPARE_MARKER] = b;
 
-         b[COMPARE_MARKER] = a;
 
-         var hasKey = function (obj, keyName) {
 
-             return (obj !== null && obj !== undefined) && obj[keyName] !== undefined;
 
-         };
 
-         for (var property in b) {
 
-             if (b.hasOwnProperty(property)) {
 
-                 if (!hasKey(a, property) && hasKey(b, property)) {
 
-                     mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
 
-                 }
 
-             }
 
-         }
 
-         for (property in a) {
 
-             if (a.hasOwnProperty(property)) {
 
-                 if (!hasKey(b, property) && hasKey(a, property)) {
 
-                     mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
 
-                 }
 
-             }
 
-         }
 
-         for (property in b) {
 
-             if (b.hasOwnProperty(property)) {
 
-                 if (property == COMPARE_MARKER) {
 
-                     continue;
 
-                 }
 
-                 if (!S.equals(a[property], b[property], mismatchKeys, mismatchValues)) {
 
-                     mismatchValues.push("'" + property + "' was '" + (b[property] ? (b[property].toString()) : b[property])
 
-                         + "' in expected, but was '" +
 
-                         (a[property] ? (a[property].toString()) : a[property]) + "' in actual.");
 
-                 }
 
-             }
 
-         }
 
-         if (S.isArray(a) && S.isArray(b) && a.length != b.length) {
 
-             mismatchValues.push("arrays were not the same length");
 
-         }
 
-         delete a[COMPARE_MARKER];
 
-         delete b[COMPARE_MARKER];
 
-         return (mismatchKeys.length === 0 && mismatchValues.length === 0);
 
-     }
 
- })(KISSY, undefined);
 
- /**
 
-  * setup data structure for kissy loader
 
-  * @author yiminghe@gmail.com
 
-  */
 
- (function(S){
 
-     if("require" in this) {
 
-         return;
 
-     }
 
-     S.__loader={};
 
-     S.__loaderUtils={};
 
-     S.__loaderData={};
 
- })(KISSY);/**
 
-  * map mechanism
 
-  * @author yiminghe@gmail.com
 
-  */
 
- (function (S, loader) {
 
-     if ("require" in this) {
 
-         return;
 
-     }
 
-     /**
 
-      * modify current module path
 
-      * @param rules
 
-      * @example
 
-      *      [
 
-      *          [/(.+-)min(.js(\?t=\d+)?)$/,"$1$2"],
 
-      *          [/(.+-)min(.js(\?t=\d+)?)$/,function(_,m1,m2){
 
-      *              return m1+m2;
 
-      *          }]
 
-      *      ]
 
-      */
 
-     S.configs.map = function (rules) {
 
-         S.Config.mappedRules = (S.Config.mappedRules || []).concat(rules);
 
-     };
 
-     S.mix(loader, {
 
-         __getMappedPath:function (path) {
 
-             var __mappedRules = S.Config.mappedRules || [];
 
-             for (var i = 0; i < __mappedRules.length; i++) {
 
-                 var m, rule = __mappedRules[i];
 
-                 if (m = path.match(rule[0])) {
 
-                     return path.replace(rule[0], rule[1]);
 
-                 }
 
-             }
 
-             return path;
 
-         }
 
-     });
 
- })(KISSY, KISSY.__loader);/**
 
-  * combine mechanism
 
-  * @author yiminghe@gmail.com
 
-  */
 
- (function (S, loader) {
 
-     if ("require" in this) {
 
-         return;
 
-     }
 
-     var combines;
 
-     /**
 
-      * compress 'from module' to 'to module'
 
-      * {
 
-      *   core:['dom','ua','event','node','json','ajax','anim','base','cookie']
 
-      * }
 
-      */
 
-     combines = S.configs.combines = function (from, to) {
 
-         var cs;
 
-         if (S.isObject(from)) {
 
-             S.each(from, function (v, k) {
 
-                 S.each(v, function (v2) {
 
-                     combines(v2, k);
 
-                 });
 
-             });
 
-             return;
 
-         }
 
-         cs = S.Config.combines = S.Config.combines || {};
 
-         if (to) {
 
-             cs[from] = to;
 
-         } else {
 
-             return cs[from] || from;
 
-         }
 
-     };
 
-     S.mix(loader, {
 
-         __getCombinedMod:function (modName) {
 
-             var cs;
 
-             cs = S.Config.combines = S.Config.combines || {};
 
-             return cs[modName] || modName;
 
-         }
 
-     });
 
- })(KISSY, KISSY.__loader);/**
 
-  * status constants
 
-  * @author yiminghe@gmail.com
 
-  */
 
- (function(S, data) {
 
-     if ("require" in this) {
 
-         return;
 
-     }
 
-     // 脚本(loadQueue)/模块(mod) 公用状态
 
-     S.mix(data, {
 
-         "INIT":0,
 
-         "LOADING" : 1,
 
-         "LOADED" : 2,
 
-         "ERROR" : 3,
 
-         // 模块特有
 
-         "ATTACHED" : 4
 
-     });
 
- })(KISSY, KISSY.__loaderData);/**
 
-  * utils for kissy loader
 
-  * @author yiminghe@gmail.com
 
-  */
 
- (function(S, loader, utils) {
 
-     if ("require" in this) {
 
-         return;
 
-     }
 
-     var ua = navigator.userAgent,doc = document;
 
-     S.mix(utils, {
 
-         docHead:function() {
 
-             return doc.getElementsByTagName('head')[0] || doc.documentElement;
 
-         },
 
-         isWebKit:!!ua.match(/AppleWebKit/),
 
-         IE : !!ua.match(/MSIE/),
 
-         isCss:function(url) {
 
-             return /\.css(?:\?|$)/i.test(url);
 
-         },
 
-         isLinkNode:function(n) {
 
-             return n.nodeName.toLowerCase() == 'link';
 
-         },
 
-         /**
 
-          * resolve relative part of path
 
-          * x/../y/z -> y/z
 
-          * x/./y/z -> x/y/z
 
-          * @param path uri path
 
-          * @return {string} resolved path
 
-          * @description similar to path.normalize in nodejs
 
-          */
 
-         normalizePath:function(path) {
 
-             var paths = path.split("/"),
 
-                 re = [],
 
-                 p;
 
-             for (var i = 0; i < paths.length; i++) {
 
-                 p = paths[i];
 
-                 if (p == ".") {
 
-                 } else if (p == "..") {
 
-                     re.pop();
 
-                 } else {
 
-                     re.push(p);
 
-                 }
 
-             }
 
-             return re.join("/");
 
-         },
 
-         /**
 
-          * 根据当前模块以及依赖模块的相对路径,得到依赖模块的绝对路径
 
-          * @param moduleName 当前模块
 
-          * @param depName 依赖模块
 
-          * @return {string|Array} 依赖模块的绝对路径
 
-          * @description similar to path.resolve in nodejs
 
-          */
 
-         normalDepModuleName:function normalDepModuleName(moduleName, depName) {
 
-             if (!depName) {
 
-                 return depName;
 
-             }
 
-             if (S.isArray(depName)) {
 
-                 for (var i = 0; i < depName.length; i++) {
 
-                     depName[i] = normalDepModuleName(moduleName, depName[i]);
 
-                 }
 
-                 return depName;
 
-             }
 
-             if (startsWith(depName, "../") || startsWith(depName, "./")) {
 
-                 var anchor = "",index;
 
-                 // x/y/z -> x/y/
 
-                 if ((index = moduleName.lastIndexOf("/")) != -1) {
 
-                     anchor = moduleName.substring(0, index + 1);
 
-                 }
 
-                 return normalizePath(anchor + depName);
 
-             } else if (depName.indexOf("./") != -1
 
-                 || depName.indexOf("../") != -1) {
 
-                 return normalizePath(depName);
 
-             } else {
 
-                 return depName;
 
-             }
 
-         },
 
-         //去除后缀名,要考虑时间戳?
 
-         removePostfix:function (path) {
 
-             return path.replace(/(-min)?\.js[^/]*$/i, "");
 
-         },
 
-         /**
 
-          * 路径正则化,不能是相对地址
 
-          * 相对地址则转换成相对页面的绝对地址
 
-          * 用途:
 
-          * package path 相对地址则相对于当前页面获取绝对地址
 
-          */
 
-         normalBasePath:function (path) {
 
-             path = S.trim(path);
 
-             // path 为空时,不能变成 "/"
 
-             if (path && path.charAt(path.length - 1) != '/') {
 
-                 path += "/";
 
-             }
 
-             /**
 
-              * 一定要正则化,防止出现 ../ 等相对路径
 
-              * 考虑本地路径
 
-              */
 
-             if (!path.match(/^(http(s)?)|(file):/i)
 
-                 && !startsWith(path, "/")) {
 
-                 path = loader.__pagePath + path;
 
-             }
 
-             return normalizePath(path);
 
-         },
 
-         /**
 
-          * 相对路径文件名转换为绝对路径
 
-          * @param path
 
-          */
 
-         absoluteFilePath:function(path) {
 
-             path = utils.normalBasePath(path);
 
-             return path.substring(0, path.length - 1);
 
-         },
 
-         //http://wiki.commonjs.org/wiki/Packages/Mappings/A
 
-         //如果模块名以 / 结尾,自动加 index
 
-         indexMapping:function (names) {
 
-             for (var i = 0; i < names.length; i++) {
 
-                 if (names[i].match(/\/$/)) {
 
-                     names[i] += "index";
 
-                 }
 
-             }
 
-             return names;
 
-         }
 
-     });
 
-     var startsWith = S.startsWith,normalizePath = utils.normalizePath;
 
- })(KISSY, KISSY.__loader, KISSY.__loaderUtils);/**
 
-  * script/css load across browser
 
-  * @author  yiminghe@gmail.com
 
-  */
 
- (function(S, utils) {
 
-     if ("require" in this) {
 
-         return;
 
-     }
 
-     var CSS_POLL_INTERVAL = 30,
 
-         /**
 
-          * central poll for link node
 
-          */
 
-             timer = 0,
 
-         monitors = {
 
-             /**
 
-              * node.id:[callback]
 
-              */
 
-         };
 
-     function startCssTimer() {
 
-         if (!timer) {
 
-             S.log("start css polling");
 
-             cssPoll();
 
-         }
 
-     }
 
-     // single thread is ok
 
-     function cssPoll() {
 
-         for (var url in monitors) {
 
-             var callbacks = monitors[url],
 
-                 node = callbacks.node,
 
-                 loaded = 0;
 
-             if (utils.isWebKit) {
 
-                 if (node['sheet']) {
 
-                     S.log("webkit loaded : " + url);
 
-                     loaded = 1;
 
-                 }
 
-             } else if (node['sheet']) {
 
-                 try {
 
-                     var cssRules;
 
-                     if (cssRules = node['sheet'].cssRules) {
 
-                         S.log('firefox  ' + cssRules + ' loaded : ' + url);
 
-                         loaded = 1;
 
-                     }
 
-                 } catch(ex) {
 
-                     // S.log('firefox  ' + ex.name + ' ' + ex.code + ' ' + url);
 
-                     // if (ex.name === 'NS_ERROR_DOM_SECURITY_ERR') {
 
-                     if (ex.code === 1000) {
 
-                         S.log('firefox  ' + ex.name + ' loaded : ' + url);
 
-                         loaded = 1;
 
-                     }
 
-                 }
 
-             }
 
-             if (loaded) {
 
-                 for (var i = 0; i < callbacks.length; i++) {
 
-                     callbacks[i].call(node);
 
-                 }
 
-                 delete monitors[url];
 
-             }
 
-         }
 
-         if (S.isEmptyObject(monitors)) {
 
-             timer = 0;
 
-             S.log("end css polling");
 
-         } else {
 
-             timer = setTimeout(cssPoll, CSS_POLL_INTERVAL);
 
-         }
 
-     }
 
-     S.mix(utils, {
 
-         scriptOnload:document.addEventListener ?
 
-             function(node, callback) {
 
-                 if (utils.isLinkNode(node)) {
 
-                     return utils.styleOnload(node, callback);
 
-                 }
 
-                 node.addEventListener('load', callback, false);
 
-             } :
 
-             function(node, callback) {
 
-                 if (utils.isLinkNode(node)) {
 
-                     return utils.styleOnload(node, callback);
 
-                 }
 
-                 var oldCallback = node.onreadystatechange;
 
-                 node.onreadystatechange = function() {
 
-                     var rs = node.readyState;
 
-                     if (/loaded|complete/i.test(rs)) {
 
-                         node.onreadystatechange = null;
 
-                         oldCallback && oldCallback();
 
-                         callback.call(this);
 
-                     }
 
-                 };
 
-             },
 
-         /**
 
-          * monitor css onload across browsers
 
-          * 暂时不考虑如何判断失败,如 404 等
 
-          * @refer
 
-          *  - firefox 不可行(结论4错误):
 
-          *    - http://yearofmoo.com/2011/03/cross-browser-stylesheet-preloading/
 
-          *  - 全浏览器兼容
 
-          *    - http://lifesinger.org/lab/2011/load-js-css/css-preload.html
 
-          *  - 其他
 
-          *    - http://www.zachleat.com/web/load-css-dynamically/
 
-          */
 
-         styleOnload:window.attachEvent ?
 
-             // ie/opera
 
-             function(node, callback) {
 
-                 // whether to detach using function wrapper?
 
-                 function t() {
 
-                     node.detachEvent('onload', t);
 
-                     S.log('ie/opera loaded : ' + node.href);
 
-                     callback.call(node);
 
-                 }
 
-                 node.attachEvent('onload', t);
 
-             } :
 
-             // refer : http://lifesinger.org/lab/2011/load-js-css/css-preload.html
 
-             // 暂时不考虑如何判断失败,如 404 等
 
-             function(node, callback) {
 
-                 var href = node.href,arr;
 
-                 arr = monitors[href] = monitors[href] || [];
 
-                 arr.node = node;
 
-                 arr.push(callback);
 
-                 startCssTimer();
 
-             }
 
-     });
 
- })(KISSY, KISSY.__loaderUtils);/**
 
-  * getScript support for css and js callback after load
 
-  * @author  lifesinger@gmail.com,yiminghe@gmail.com
 
-  */
 
- (function(S, utils) {
 
-     if ("require" in this) {
 
-         return;
 
-     }
 
-     var MILLISECONDS_OF_SECOND = 1000,
 
-         scriptOnload = utils.scriptOnload;
 
-     S.mix(S, {
 
-         /**
 
-          * load  a css file from server using http get ,after css file load ,execute success callback
 
-          * @param url css file url
 
-          * @param success callback
 
-          * @param charset
 
-          */
 
-         getStyle:function(url, success, charset) {
 
-             var doc = document,
 
-                 head = utils.docHead(),
 
-                 node = doc.createElement('link'),
 
-                 config = success;
 
-             if (S.isPlainObject(config)) {
 
-                 success = config.success;
 
-                 charset = config.charset;
 
-             }
 
-             node.href = url;
 
-             node.rel = 'stylesheet';
 
-             if (charset) {
 
-                 node.charset = charset;
 
-             }
 
-             if (success) {
 
-                 utils.scriptOnload(node, success);
 
-             }
 
-             head.appendChild(node);
 
-             return node;
 
-         },
 
-         /**
 
-          * Load a JavaScript/Css file from the server using a GET HTTP request, then execute it.
 
-          * <code>
 
-          *  getScript(url, success, charset);
 
-          *  or
 
-          *  getScript(url, {
 
-          *      charset: string
 
-          *      success: fn,
 
-          *      error: fn,
 
-          *      timeout: number
 
-          *  });
 
-          * </code>
 
-          */
 
-         getScript:function(url, success, charset) {
 
-             if (utils.isCss(url)) {
 
-                 return S.getStyle(url, success, charset);
 
-             }
 
-             var doc = document,
 
-                 head = doc.head || doc.getElementsByTagName("head")[0],
 
-                 node = doc.createElement('script'),
 
-                 config = success,
 
-                 error,
 
-                 timeout,
 
-                 timer;
 
-             if (S.isPlainObject(config)) {
 
-                 success = config.success;
 
-                 error = config.error;
 
-                 timeout = config.timeout;
 
-                 charset = config.charset;
 
-             }
 
-             function clearTimer() {
 
-                 if (timer) {
 
-                     timer.cancel();
 
-                     timer = undefined;
 
-                 }
 
-             }
 
-             node.src = url;
 
-             node.async = true;
 
-             if (charset) {
 
-                 node.charset = charset;
 
-             }
 
-             if (success || error) {
 
-                 scriptOnload(node, function() {
 
-                     clearTimer();
 
-                     S.isFunction(success) && success.call(node);
 
-                 });
 
-                 if (S.isFunction(error)) {
 
-                     //标准浏览器
 
-                     if (doc.addEventListener) {
 
-                         node.addEventListener("error", function() {
 
-                             clearTimer();
 
-                             error.call(node);
 
-                         }, false);
 
-                     }
 
-                     timer = S.later(function() {
 
-                         timer = undefined;
 
-                         error();
 
-                     }, (timeout || this.Config.timeout) * MILLISECONDS_OF_SECOND);
 
-                 }
 
-             }
 
-             head.insertBefore(node, head.firstChild);
 
-             return node;
 
-         }
 
-     });
 
- })(KISSY, KISSY.__loaderUtils);/**
 
-  * add module definition
 
-  * @author  yiminghe@gmail.com,lifesinger@gmail.com
 
-  */
 
- (function(S, loader, utils, data) {
 
-     if ("require" in this) {
 
-         return;
 
-     }
 
-     var IE = utils.IE,
 
-         ATTACHED = data.ATTACHED,
 
-         mix = S.mix;
 
-     mix(loader, {
 
-         /**
 
-          * Registers a module.
 
-          * @param name {String} module name
 
-          * @param def {Function|Object} entry point into the module that is used to bind module to KISSY
 
-          * @param config {Object}
 
-          * <code>
 
-          * KISSY.add('module-name', function(S){ }, {requires: ['mod1']});
 
-          * </code>
 
-          * <code>
 
-          * KISSY.add({
 
-          *     'mod-name': {
 
-          *         fullpath: 'url',
 
-          *         requires: ['mod1','mod2']
 
-          *     }
 
-          * });
 
-          * </code>
 
-          * @return {KISSY}
 
-          */
 
-         add: function(name, def, config) {
 
-             var self = this,
 
-                 mods = self.Env.mods,
 
-                 o;
 
-             // S.add(name, config) => S.add( { name: config } )
 
-             if (S.isString(name)
 
-                 && !config
 
-                 && S.isPlainObject(def)) {
 
-                 o = {};
 
-                 o[name] = def;
 
-                 name = o;
 
-             }
 
-             // S.add( { name: config } )
 
-             if (S.isPlainObject(name)) {
 
-                 S.each(name, function(v, k) {
 
-                     v.name = k;
 
-                     if (mods[k]) {
 
-                         // 保留之前添加的配置
 
-                         mix(v, mods[k], false);
 
-                     }
 
-                 });
 
-                 mix(mods, name);
 
-                 return self;
 
-             }
 
-             // S.add(name[, fn[, config]])
 
-             if (S.isString(name)) {
 
-                 var host;
 
-                 if (config && ( host = config.host )) {
 
-                     var hostMod = mods[host];
 
-                     if (!hostMod) {
 
-                         S.log("module " + host + " can not be found !", "error");
 
-                         //S.error("module " + host + " can not be found !");
 
-                         return self;
 
-                     }
 
-                     if (self.__isAttached(host)) {
 
-                         def.call(self, self);
 
-                     } else {
 
-                         //该 host 模块纯虚!
 
-                         hostMod.fns = hostMod.fns || [];
 
-                         hostMod.fns.push(def);
 
-                     }
 
-                     return self;
 
-                 }
 
-                 self.__registerModule(name, def, config);
 
-                 //显示指定 add 不 attach
 
-                 if (config && config['attach'] === false) {
 
-                     return self;
 
-                 }
 
-                 // 和 1.1.7 以前版本保持兼容,不得已而为之
 
-                 var mod = mods[name];
 
-                 var requires = utils.normalDepModuleName(name, mod.requires);
 
-                 if (self.__isAttached(requires)) {
 
-                     //S.log(mod.name + " is attached when add !");
 
-                     self.__attachMod(mod);
 
-                 }
 
-                 //调试用,为什么不在 add 时 attach
 
-                 else if (this.Config.debug && !mod) {
 
-                     var i,modNames;
 
-                     i = (modNames = S.makeArray(requires)).length - 1;
 
-                     for (; i >= 0; i--) {
 
-                         var requireName = modNames[i];
 
-                         var requireMod = mods[requireName] || {};
 
-                         if (requireMod.status !== ATTACHED) {
 
-                             S.log(mod.name + " not attached when added : depends " + requireName);
 
-                         }
 
-                     }
 
-                 }
 
-                 return self;
 
-             }
 
-             // S.add(fn,config);
 
-             if (S.isFunction(name)) {
 
-                 config = def;
 
-                 def = name;
 
-                 if (IE) {
 
-                     /*
 
-                      Kris Zyp
 
-                      2010年10月21日, 上午11时34分
 
-                      We actually had some discussions off-list, as it turns out the required
 
-                      technique is a little different than described in this thread. Briefly,
 
-                      to identify anonymous modules from scripts:
 
-                      * In non-IE browsers, the onload event is sufficient, it always fires
 
-                      immediately after the script is executed.
 
-                      * In IE, if the script is in the cache, it actually executes *during*
 
-                      the DOM insertion of the script tag, so you can keep track of which
 
-                      script is being requested in case define() is called during the DOM
 
-                      insertion.
 
-                      * In IE, if the script is not in the cache, when define() is called you
 
-                      can iterate through the script tags and the currently executing one will
 
-                      have a script.readyState == "interactive"
 
-                      See RequireJS source code if you need more hints.
 
-                      Anyway, the bottom line from a spec perspective is that it is
 
-                      implemented, it works, and it is possible. Hope that helps.
 
-                      Kris
 
-                      */
 
-                     // http://groups.google.com/group/commonjs/browse_thread/thread/5a3358ece35e688e/43145ceccfb1dc02#43145ceccfb1dc02
 
-                     // use onload to get module name is not right in ie
 
-                     name = self.__findModuleNameByInteractive();
 
-                     S.log("old_ie get modname by interactive : " + name);
 
-                     self.__registerModule(name, def, config);
 
-                     self.__startLoadModuleName = null;
 
-                     self.__startLoadTime = 0;
 
-                 } else {
 
-                     // 其他浏览器 onload 时,关联模块名与模块定义
 
-                     self.__currentModule = {
 
-                         def:def,
 
-                         config:config
 
-                     };
 
-                 }
 
-                 return self;
 
-             }
 
-             S.log("invalid format for KISSY.add !", "error");
 
-             return self;
 
-         }
 
-     });
 
- })(KISSY, KISSY.__loader, KISSY.__loaderUtils, KISSY.__loaderData);
 
- /**
 
-  * @refer
 
-  *  - https://github.com/amdjs/amdjs-api/wiki/AMD
 
-  **//**
 
-  * build full path from relative path and base path
 
-  * @author  lifesinger@gmail.com,yiminghe@gmail.com
 
-  */
 
- (function (S, loader, utils, data) {
 
-     if ("require" in this) {
 
-         return;
 
-     }
 
-     S.mix(loader, {
 
-         __buildPath:function (mod, base) {
 
-             var self = this,
 
-                 Config = self.Config;
 
-             base = base || Config.base;
 
-             build("fullpath", "path");
 
-             if (mod["cssfullpath"] !== data.LOADED) {
 
-                 build("cssfullpath", "csspath");
 
-             }
 
-             function build(fullpath, path) {
 
-                 if (!mod[fullpath] && mod[path]) {
 
-                     //如果是 ./ 或 ../ 则相对当前模块路径
 
-                     mod[path] = utils.normalDepModuleName(mod.name, mod[path]);
 
-                     mod[fullpath] = base + mod[path];
 
-                 }
 
-                 // debug 模式下,加载非 min 版
 
-                 if (mod[fullpath] && Config.debug) {
 
-                     mod[fullpath] = mod[fullpath].replace(/-min/ig, "");
 
-                 }
 
-                 //刷新客户端缓存,加时间戳 tag
 
-                 if (mod[fullpath]
 
-                     && !(mod[fullpath].match(/\?t=/))
 
-                     && mod.tag) {
 
-                     mod[fullpath] += "?t=" + mod.tag;
 
-                 }
 
-                 if (mod[fullpath]) {
 
-                     mod[fullpath] = self.__getMappedPath(mod[fullpath]);
 
-                 }
 
-             }
 
-         }
 
-     });
 
- })(KISSY, KISSY.__loader, KISSY.__loaderUtils, KISSY.__loaderData);/**
 
-  * logic for config.global , mainly for kissy.editor
 
-  * @author  lifesinger@gmail.com,yiminghe@gmail.com
 
-  */
 
- (function(S, loader) {
 
-     if ("require" in this) {
 
-         return;
 
-     }
 
-     S.mix(loader, {
 
-         // 按需从 global 迁移模块定义到当前 loader 实例,并根据 global 设置 fullpath
 
-         __mixMod: function(name, global) {
 
-             // 从 __mixMods 调用过来时,可能本实例没有该模块的数据结构
 
-             var self = this,
 
-                 mods = self.Env.mods,
 
-                 gMods = global.Env.mods,
 
-                 mod = mods[name] || {},
 
-                 status = mod.status;
 
-             if (gMods[name]) {
 
-                 S.mix(mod, S.clone(gMods[name]));
 
-                 // status 属于实例,当有值时,不能被覆盖。
 
-                 // 1. 只有没有初始值时,才从 global 上继承
 
-                 // 2. 初始值为 0 时,也从 global 上继承
 
-                 // 其他都保存自己的状态
 
-                 if (status) {
 
-                     mod.status = status;
 
-                 }
 
-             }
 
-             // 来自 global 的 mod, path 也应该基于 global
 
-             self.__buildPath(mod, global.Config.base);
 
-             mods[name] = mod;
 
-         }
 
-     });
 
- })(KISSY, KISSY.__loader);/**
 
-  * for ie ,find current executive script ,then infer module name
 
-  * @author yiminghe@gmail.com
 
-  */
 
- (function (S, loader, utils) {
 
-     if ("require" in this) {
 
-         return;
 
-     }
 
-     S.mix(loader, {
 
-         //ie 特有,找到当前正在交互的脚本,根据脚本名确定模块名
 
-         // 如果找不到,返回发送前那个脚本
 
-         __findModuleNameByInteractive:function () {
 
-             var self = this,
 
-                 scripts = document.getElementsByTagName("script"),
 
-                 re,
 
-                 script;
 
-             for (var i = 0; i < scripts.length; i++) {
 
-                 script = scripts[i];
 
-                 if (script.readyState == "interactive") {
 
-                     re = script;
 
-                     break;
 
-                 }
 
-             }
 
-             if (!re) {
 
-                 // sometimes when read module file from cache , interactive status is not triggered
 
-                 // module code is executed right after inserting into dom
 
-                 // i has to preserve module name before insert module script into dom , then get it back here
 
-                 S.log("can not find interactive script,time diff : " + (+new Date() - self.__startLoadTime), "error");
 
-                 S.log("old_ie get modname from cache : " + self.__startLoadModuleName);
 
-                 return self.__startLoadModuleName;
 
-                 //S.error("找不到 interactive 状态的 script");
 
-             }
 
-             // src 必定是绝对路径
 
-             // or re.hasAttribute ? re.src :  re.getAttribute('src', 4);
 
-             // http://msdn.microsoft.com/en-us/library/ms536429(VS.85).aspx
 
-             var src = utils.absoluteFilePath(re.src);
 
-             // S.log("interactive src :" + src);
 
-             // 注意:模块名不包含后缀名以及参数,所以去除
 
-             // 系统模块去除系统路径
 
-             // 需要 base norm , 防止 base 被指定为相对路径
 
-             self.Config.base = utils.normalBasePath(self.Config.base);
 
-             if (src.lastIndexOf(self.Config.base, 0)
 
-                 === 0) {
 
-                 return utils.removePostfix(src.substring(self.Config.base.length));
 
-             }
 
-             var packages = self.Config.packages;
 
-             //外部模块去除包路径,得到模块名
 
-             for (var p in packages) {
 
-                 if (packages.hasOwnProperty(p)) {
 
-                     var p_path = packages[p].path;
 
-                     if (packages.hasOwnProperty(p) &&
 
-                         src.lastIndexOf(p_path, 0) === 0) {
 
-                         return utils.removePostfix(src.substring(p_path.length));
 
-                     }
 
-                 }
 
-             }
 
-             S.log("interactive script does not have package config :" + src, "error");
 
-         }
 
-     });
 
- })(KISSY, KISSY.__loader, KISSY.__loaderUtils);/**
 
-  * load a single mod (js or css)
 
-  * @author  lifesinger@gmail.com,yiminghe@gmail.com
 
-  */
 
- (function(S, loader, utils, data) {
 
-     if ("require" in this) {
 
-         return;
 
-     }
 
-     var IE = utils.IE,
 
-         LOADING = data.LOADING,
 
-         LOADED = data.LOADED,
 
-         ERROR = data.ERROR,
 
-         ATTACHED = data.ATTACHED;
 
-     S.mix(loader, {
 
-         /**
 
-          * Load a single module.
 
-          */
 
-         __load: function(mod, callback, cfg) {
 
-             var self = this,
 
-                 url = mod['fullpath'],
 
-                 isCss = utils.isCss(url),
 
-                 // 这个是全局的,防止多实例对同一模块的重复下载
 
-                 loadQueque = S.Env._loadQueue,
 
-                 status = loadQueque[url],
 
-                 node = status;
 
-             mod.status = mod.status || 0;
 
-             // 可能已经由其它模块触发加载
 
-             if (mod.status < LOADING && status) {
 
-                 // 该模块是否已经载入到 global ?
 
-                 mod.status = status === LOADED ? LOADED : LOADING;
 
-             }
 
-             // 1.20 兼容 1.1x 处理:加载 cssfullpath 配置的 css 文件
 
-             // 仅发出请求,不做任何其它处理
 
-             if (S.isString(mod["cssfullpath"])) {
 
-                 S.getScript(mod["cssfullpath"]);
 
-                 mod["cssfullpath"] = mod.csspath = LOADED;
 
-             }
 
-             if (mod.status < LOADING && url) {
 
-                 mod.status = LOADING;
 
-                 if (IE && !isCss) {
 
-                     self.__startLoadModuleName = mod.name;
 
-                     self.__startLoadTime = Number(+new Date());
 
-                 }
 
-                 node = S.getScript(url, {
 
-                     success: function() {
 
-                         if (isCss) {
 
-                         } else {
 
-                             //载入 css 不需要这步了
 
-                             //标准浏览器下:外部脚本执行后立即触发该脚本的 load 事件,ie9 还是不行
 
-                             if (self.__currentModule) {
 
-                                 S.log("standard browser get modname after load : " + mod.name);
 
-                                 self.__registerModule(mod.name, self.__currentModule.def,
 
-                                     self.__currentModule.config);
 
-                                 self.__currentModule = null;
 
-                             }
 
-                             // 模块载入后,如果需要也要混入对应 global 上模块定义
 
-                             mixGlobal();
 
-                             if (mod.fns && mod.fns.length > 0) {
 
-                             } else {
 
-                                 _modError();
 
-                             }
 
-                         }
 
-                         if (mod.status != ERROR) {
 
-                             S.log(mod.name + ' is loaded.', 'info');
 
-                         }
 
-                         _scriptOnComplete();
 
-                     },
 
-                     error: function() {
 
-                         _modError();
 
-                         _scriptOnComplete();
 
-                     },
 
-                     charset: mod.charset
 
-                 });
 
-                 loadQueque[url] = node;
 
-             }
 
-             // 已经在加载中,需要添加回调到 script onload 中
 
-             // 注意:没有考虑 error 情形
 
-             else if (mod.status === LOADING) {
 
-                 utils.scriptOnload(node, function() {
 
-                     // 模块载入后,如果需要也要混入对应 global 上模块定义
 
-                     mixGlobal();
 
-                     _scriptOnComplete();
 
-                 });
 
-             }
 
-             // 是内嵌代码,或者已经 loaded
 
-             else {
 
-                 // 也要混入对应 global 上模块定义
 
-                 mixGlobal();
 
-                 callback();
 
-             }
 
-             function _modError() {
 
-                 S.log(mod.name + ' is not loaded! can not find module in path : ' + mod['fullpath'], 'error');
 
-                 mod.status = ERROR;
 
-             }
 
-             function mixGlobal() {
 
-                 // 对于动态下载下来的模块,loaded 后,global 上有可能更新 mods 信息
 
-                 // 需要同步到 instance 上去
 
-                 // 注意:要求 mod 对应的文件里,仅修改该 mod 信息
 
-                 if (cfg.global) {
 
-                     self.__mixMod(mod.name, cfg.global);
 
-                 }
 
-             }
 
-             function _scriptOnComplete() {
 
-                 loadQueque[url] = LOADED;
 
-                 if (mod.status !== ERROR) {
 
-                     // 注意:当多个模块依赖同一个下载中的模块A下,模块A仅需 attach 一次
 
-                     // 因此要加上下面的 !== 判断,否则会出现重复 attach,
 
-                     // 比如编辑器里动态加载时,被依赖的模块会重复
 
-                     if (mod.status !== ATTACHED) {
 
-                         mod.status = LOADED;
 
-                     }
 
-                     callback();
 
-                 }
 
-             }
 
-         }
 
-     });
 
- })(KISSY, KISSY.__loader, KISSY.__loaderUtils, KISSY.__loaderData);/**
 
-  * @module loader
 
-  * @author lifesinger@gmail.com,yiminghe@gmail.com,lijing00333@163.com
 
-  * @description: constant member and common method holder
 
-  */
 
- (function(S, loader, data) {
 
-     if ("require" in this) {
 
-         return;
 
-     }
 
-     var ATTACHED = data.ATTACHED,
 
-         mix = S.mix;
 
-     mix(loader, {
 
-         // 当前页面所在的目录
 
-         // http://xx.com/y/z.htm#!/f/g
 
-         // ->
 
-         // http://xx.com/y/
 
-         __pagePath:location.href.replace(location.hash, "").replace(/[^/]*$/i, ""),
 
-         //firefox,ie9,chrome 如果add没有模块名,模块定义先暂存这里
 
-         __currentModule:null,
 
-         //ie6,7,8开始载入脚本的时间
 
-         __startLoadTime:0,
 
-         //ie6,7,8开始载入脚本对应的模块名
 
-         __startLoadModuleName:null,
 
-         __isAttached: function(modNames) {
 
-             var mods = this.Env.mods,
 
-                 ret = true;
 
-             S.each(modNames, function(name) {
 
-                 var mod = mods[name];
 
-                 if (!mod || mod.status !== ATTACHED) {
 
-                     ret = false;
 
-                     return ret;
 
-                 }
 
-             });
 
-             return ret;
 
-         }
 
-     });
 
- })(KISSY, KISSY.__loader, KISSY.__loaderData);
 
- /**
 
-  * 2011-01-04 chengyu<yiminghe@gmail.com> refactor:
 
-  *
 
-  * adopt requirejs :
 
-  *
 
-  * 1. packages(cfg) , cfg :{
 
-  *    name : 包名,用于指定业务模块前缀
 
-  *    path: 前缀包名对应的路径
 
-  *    charset: 该包下所有文件的编码
 
-  *
 
-  * 2. add(moduleName,function(S,depModule){return function(){}},{requires:["depModuleName"]});
 
-  *    moduleName add 时可以不写
 
-  *    depModuleName 可以写相对地址 (./ , ../),相对于 moduleName
 
-  *
 
-  * 3. S.use(["dom"],function(S,DOM){
 
-  *    });
 
-  *    依赖注入,发生于 add 和 use 时期
 
-  *
 
-  * 4. add,use 不支持 css loader ,getScript 仍然保留支持
 
-  *
 
-  * 5. 部分更新模块文件代码 x/y?t=2011 ,加载过程中注意去除事件戳,仅在载入文件时使用
 
-  *
 
-  * demo : http://lite-ext.googlecode.com/svn/trunk/lite-ext/playground/module_package/index.html
 
-  *
 
-  * 2011-03-01 yiminghe@gmail.com note:
 
-  *
 
-  * compatibility
 
-  *
 
-  * 1. 保持兼容性,不得已而为之
 
-  *      支持 { host : }
 
-  *      如果 requires 都已经 attached,支持 add 后立即 attach
 
-  *      支持 { attach : false } 显示控制 add 时是否 attach
 
-  *      支持 { global : Editor } 指明模块来源
 
-  *
 
-  *
 
-  * 2011-05-04 初步拆分文件,tmd 乱了
 
-  */
 
- /**
 
-  * package mechanism
 
-  * @author yiminghe@gmail.com
 
-  */
 
- (function (S, loader, utils) {
 
-     if ("require" in this) {
 
-         return;
 
-     }
 
-     /**
 
-      * 包声明
 
-      * biz -> .
 
-      * 表示遇到 biz/x
 
-      * 在当前网页路径找 biz/x.js
 
-      */
 
-     S.configs.packages = function (cfgs) {
 
-         var ps;
 
-         ps = S.Config.packages = S.Config.packages || {};
 
-         S.each(cfgs, function (cfg) {
 
-             ps[cfg.name] = cfg;
 
-             //注意正则化
 
-             cfg.path = cfg.path && utils.normalBasePath(cfg.path);
 
-             cfg.tag = cfg.tag && encodeURIComponent(cfg.tag);
 
-         });
 
-     };
 
-     S.mix(loader, {
 
-         __getPackagePath:function (mod) {
 
-             //缓存包路径,未申明的包的模块都到核心模块中找
 
-             if (mod.packagepath) {
 
-                 return mod.packagepath;
 
-             }
 
-             var self = this,
 
-                 //一个模块合并到了另一个模块文件中去
 
-                 modName = S.__getCombinedMod(mod.name),
 
-                 packages = self.Config.packages || {},
 
-                 pName = "",
 
-                 p_def;
 
-             for (var p in packages) {
 
-                 if (packages.hasOwnProperty(p)) {
 
-                     if (S.startsWith(modName, p) &&
 
-                         p.length > pName) {
 
-                         pName = p;
 
-                     }
 
-                 }
 
-             }
 
-             p_def = packages[pName];
 
-             mod.charset = p_def && p_def.charset || mod.charset;
 
-             if (p_def) {
 
-                 mod.tag = p_def.tag;
 
-             } else {
 
-                 // kissy 自身组件的事件戳后缀
 
-                 mod.tag = encodeURIComponent(S.Config.tag || S.buildTime);
 
-             }
 
-             return mod.packagepath = (p_def && p_def.path) || self.Config.base;
 
-         }
 
-     });
 
- })(KISSY, KISSY.__loader, KISSY.__loaderUtils);/**
 
-  * register module ,associate module name with module factory(definition)
 
-  * @author  yiminghe@gmail.com,lifesinger@gmail.com
 
-  */
 
- (function(S, loader,data) {
 
-     if ("require" in this) {
 
-         return;
 
-     }
 
-     var LOADED = data.LOADED,
 
-         mix = S.mix;
 
-     mix(loader, {
 
-         //注册模块,将模块和定义 factory 关联起来
 
-         __registerModule:function(name, def, config) {
 
-             config = config || {};
 
-             var self = this,
 
-                 mods = self.Env.mods,
 
-                 mod = mods[name] || {};
 
-             // 注意:通过 S.add(name[, fn[, config]]) 注册的代码,无论是页面中的代码,
 
-             // 还是 js 文件里的代码,add 执行时,都意味着该模块已经 LOADED
 
-             mix(mod, { name: name, status: LOADED });
 
-             if (mod.fns && mod.fns.length) {
 
-                 S.log(name + " is defined more than once");
 
-                 //S.error(name + " is defined more than once");
 
-             }
 
-             //支持 host,一个模块多个 add factory
 
-             mod.fns = mod.fns || [];
 
-             mod.fns.push(def);
 
-             mix((mods[name] = mod), config);
 
-         }
 
-     });
 
- })(KISSY, KISSY.__loader, KISSY.__loaderData);/**
 
-  * use and attach mod
 
-  * @author  yiminghe@gmail.com,lifesinger@gmail.com
 
-  */
 
- (function (S, loader, utils, data) {
 
-     if ("require" in this) {
 
-         return;
 
-     }
 
-     var LOADED = data.LOADED,
 
-         ATTACHED = data.ATTACHED;
 
-     S.mix(loader, {
 
-         /**
 
-          * Start load specific mods, and fire callback when these mods and requires are attached.
 
-          * <code>
 
-          * S.use('mod-name', callback, config);
 
-          * S.use('mod1,mod2', callback, config);
 
-          * </code>
 
-          */
 
-         use:function (modNames, callback, cfg) {
 
-             modNames = modNames.replace(/\s+/g, "").split(',');
 
-             utils.indexMapping(modNames);
 
-             cfg = cfg || {};
 
-             var self = this,
 
-                 fired;
 
-             // 已经全部 attached, 直接执行回调即可
 
-             if (self.__isAttached(modNames)) {
 
-                 var mods = self.__getModules(modNames);
 
-                 callback && callback.apply(self, mods);
 
-                 return;
 
-             }
 
-             // 有尚未 attached 的模块
 
-             S.each(modNames, function (modName) {
 
-                 // 从 name 开始调用,防止不存在模块
 
-                 self.__attachModByName(modName, function () {
 
-                     if (!fired &&
 
-                         self.__isAttached(modNames)) {
 
-                         fired = true;
 
-                         var mods = self.__getModules(modNames);
 
-                         callback && callback.apply(self, mods);
 
-                     }
 
-                 }, cfg);
 
-             });
 
-             return self;
 
-         },
 
-         __getModules:function (modNames) {
 
-             var self = this,
 
-                 mods = [self];
 
-             S.each(modNames, function (modName) {
 
-                 if (!utils.isCss(modName)) {
 
-                     mods.push(self.require(modName));
 
-                 }
 
-             });
 
-             return mods;
 
-         },
 
-         /**
 
-          * get module's value defined by define function
 
-          * @param {string} moduleName
 
-          */
 
-         require:function (moduleName) {
 
-             var self = this,
 
-                 mods = self.Env.mods,
 
-                 mod = mods[moduleName],
 
-                 re = self['onRequire'] && self['onRequire'](mod);
 
-             if (re !== undefined) {
 
-                 return re;
 
-             }
 
-             return mod && mod.value;
 
-         },
 
-         // 加载指定模块名模块,如果不存在定义默认定义为内部模块
 
-         __attachModByName:function (modName, callback, cfg) {
 
-             var self = this,
 
-                 mods = self.Env.mods;
 
-             var mod = mods[modName];
 
-             //没有模块定义
 
-             if (!mod) {
 
-                 // 默认 js/css 名字
 
-                 // 不指定 .js 默认为 js
 
-                 // 指定为 css 载入 .css
 
-                 var componentJsName = self.Config['componentJsName'] ||
 
-                     function (m) {
 
-                         var suffix = "js", match;
 
-                         if (match = m.match(/(.+)\.(js|css)$/i)) {
 
-                             suffix = match[2];
 
-                             m = match[1];
 
-                         }
 
-                         return m + '-min.' + suffix;
 
-                     },
 
-                     path = componentJsName(S.__getCombinedMod(modName));
 
-                 mod = {
 
-                     path:path,
 
-                     charset:'utf-8'
 
-                 };
 
-                 //添加模块定义
 
-                 mods[modName] = mod;
 
-             }
 
-             mod.name = modName;
 
-             if (mod && mod.status === ATTACHED) {
 
-                 return;
 
-             }
 
-             // 先从 global 里取
 
-             if (cfg.global) {
 
-                 self.__mixMod(modName, cfg.global);
 
-             }
 
-             self.__attach(mod, callback, cfg);
 
-         },
 
-         /**
 
-          * Attach a module and all required modules.
 
-          */
 
-         __attach:function (mod, callback, cfg) {
 
-             var self = this,
 
-                 r,
 
-                 rMod,
 
-                 i,
 
-                 attached = 0,
 
-                 mods = self.Env.mods,
 
-                 //复制一份当前的依赖项出来,防止 add 后修改!
 
-                 requires = (mod['requires'] || []).concat();
 
-             mod['requires'] = requires;
 
-             /**
 
-              * check cyclic dependency between mods
 
-              */
 
-             function cyclicCheck() {
 
-                 var __allRequires,
 
-                     myName = mod.name,
 
-                     r, r2, rmod,
 
-                     r__allRequires,
 
-                     requires = mod.requires;
 
-                 // one mod's all requires mods to run its callback
 
-                 __allRequires = mod.__allRequires = mod.__allRequires || {};
 
-                 for (var i = 0; i < requires.length; i++) {
 
-                     r = requires[i];
 
-                     rmod = mods[r];
 
-                     __allRequires[r] = 1;
 
-                     if (rmod && (r__allRequires = rmod.__allRequires)) {
 
-                         for (r2 in r__allRequires) {
 
-                             if (r__allRequires.hasOwnProperty(r2)) {
 
-                                 __allRequires[r2] = 1;
 
-                             }
 
-                         }
 
-                     }
 
-                 }
 
-                 if (__allRequires[myName]) {
 
-                     var t = [];
 
-                     for (r in __allRequires) {
 
-                         if (__allRequires.hasOwnProperty(r)) {
 
-                             t.push(r);
 
-                         }
 
-                     }
 
-                     S.error("find cyclic dependency by mod " + myName + " between mods : " + t.join(","));
 
-                 }
 
-             }
 
-             if (S.Config.debug) {
 
-                 cyclicCheck();
 
-             }
 
-             // attach all required modules
 
-             for (i = 0; i < requires.length; i++) {
 
-                 r = requires[i] = utils.normalDepModuleName(mod.name, requires[i]);
 
-                 rMod = mods[r];
 
-                 if (rMod && rMod.status === ATTACHED) {
 
-                     //no need
 
-                 } else {
 
-                     self.__attachModByName(r, fn, cfg);
 
-                 }
 
-             }
 
-             // load and attach this module
 
-             self.__buildPath(mod, self.__getPackagePath(mod));
 
-             self.__load(mod, function () {
 
-                 // add 可能改了 config,这里重新取下
 
-                 mod['requires'] = mod['requires'] || [];
 
-                 var newRequires = mod['requires'],
 
-                     needToLoad = [];
 
-                 //本模块下载成功后串行下载 require
 
-                 for (i = 0; i < newRequires.length; i++) {
 
-                     r = newRequires[i] = utils.normalDepModuleName(mod.name, newRequires[i]);
 
-                     var rMod = mods[r],
 
-                         inA = S.inArray(r, requires);
 
-                     //已经处理过了或将要处理
 
-                     if (rMod &&
 
-                         rMod.status === ATTACHED
 
-                         //已经正在处理了
 
-                         || inA) {
 
-                         //no need
 
-                     } else {
 
-                         //新增的依赖项
 
-                         needToLoad.push(r);
 
-                     }
 
-                 }
 
-                 if (needToLoad.length) {
 
-                     for (i = 0; i < needToLoad.length; i++) {
 
-                         self.__attachModByName(needToLoad[i], fn, cfg);
 
-                     }
 
-                 } else {
 
-                     fn();
 
-                 }
 
-             }, cfg);
 
-             function fn() {
 
-                 if (!attached &&
 
-                     self.__isAttached(mod['requires'])) {
 
-                     if (mod.status === LOADED) {
 
-                         self.__attachMod(mod);
 
-                     }
 
-                     if (mod.status === ATTACHED) {
 
-                         attached = 1;
 
-                         callback();
 
-                     }
 
-                 }
 
-             }
 
-         },
 
-         __attachMod:function (mod) {
 
-             var self = this,
 
-                 fns = mod.fns;
 
-             if (fns) {
 
-                 S.each(fns, function (fn) {
 
-                     var value;
 
-                     if (S.isFunction(fn)) {
 
-                         value = fn.apply(self, self.__getModules(mod['requires']));
 
-                     } else {
 
-                         value = fn;
 
-                     }
 
-                     mod.value = mod.value || value;
 
-                 });
 
-             }
 
-             mod.status = ATTACHED;
 
-         }
 
-     });
 
- })(KISSY, KISSY.__loader, KISSY.__loaderUtils, KISSY.__loaderData);/**
 
-  *  mix loader into S and infer KISSy baseUrl if not set
 
-  *  @author  lifesinger@gmail.com,yiminghe@gmail.com
 
-  */
 
- (function (S, loader, utils) {
 
-     if ("require" in this) {
 
-         return;
 
-     }
 
-     S.mix(S, loader);
 
-     /**
 
-      * get base from src
 
-      * @param src script source url
 
-      * @return base for kissy
 
-      * @example:
 
-      *   http://a.tbcdn.cn/s/kissy/1.1.6/??kissy-min.js,suggest/suggest-pkg-min.js
 
-      *   http://a.tbcdn.cn/??s/kissy/1.1.6/kissy-min.js,s/kissy/1.1.5/suggest/suggest-pkg-min.js
 
-      *   http://a.tbcdn.cn/??s/kissy/1.1.6/suggest/suggest-pkg-min.js,s/kissy/1.1.5/kissy-min.js
 
-      *   http://a.tbcdn.cn/s/kissy/1.1.6/kissy-min.js?t=20101215.js
 
-      * @notice: custom combo rules, such as yui3:
 
-      *  <script src="path/to/kissy" data-combo-prefix="combo?" data-combo-sep="&"></script>
 
-      */
 
-         // notice: timestamp
 
-     var baseReg = /^(.*)(seed|kissy)(-aio)?(-min)?\.js[^/]*/i,
 
-         baseTestReg = /(seed|kissy)(-aio)?(-min)?\.js/i;
 
-     function getBaseUrl(script) {
 
-         var src = utils.absoluteFilePath(script.src),
 
-             prefix = script.getAttribute('data-combo-prefix') || '??',
 
-             sep = script.getAttribute('data-combo-sep') || ',',
 
-             parts = src.split(sep),
 
-             base,
 
-             part0 = parts[0],
 
-             index = part0.indexOf(prefix);
 
-         // no combo
 
-         if (index == -1) {
 
-             base = src.replace(baseReg, '$1');
 
-         } else {
 
-             base = part0.substring(0, index);
 
-             var part01 = part0.substring(index + 2, part0.length);
 
-             // combo first
 
-             // notice use match better than test
 
-             if (part01.match(baseTestReg)) {
 
-                 base += part01.replace(baseReg, '$1');
 
-             }
 
-             // combo after first
 
-             else {
 
-                 S.each(parts, function (part) {
 
-                     if (part.match(baseTestReg)) {
 
-                         base += part.replace(baseReg, '$1');
 
-                         return false;
 
-                     }
 
-                 });
 
-             }
 
-         }
 
-         return base;
 
-     }
 
-     /**
 
-      * Initializes loader.
 
-      */
 
-     S.__initLoader = function () {
 
-         var self = this;
 
-         self.Env.mods = self.Env.mods || {}; // all added mods
 
-     };
 
-     S.Env._loadQueue = {}; // information for loading and loaded mods
 
-     S.__initLoader();
 
-     (function () {
 
-         // get base from current script file path
 
-         var scripts = document.getElementsByTagName('script'),
 
-             currentScript = scripts[scripts.length - 1],
 
-             base = getBaseUrl(currentScript);
 
-         S.Config.base = utils.normalBasePath(base);
 
-         // the default timeout for getScript
 
-         S.Config.timeout = 10;
 
-     })();
 
-     S.mix(S.configs, {
 
-         base:function (base) {
 
-             S.Config.base = utils.normalBasePath(base);
 
-         },
 
-         timeout:function (v) {
 
-             S.Config.timeout = v;
 
-         },
 
-         debug:function (v) {
 
-             S.Config.debug = v;
 
-         }
 
-     });
 
-     // for S.app working properly
 
-     S.each(loader, function (v, k) {
 
-         S.__APP_MEMBERS.push(k);
 
-     });
 
-     S.__APP_INIT_METHODS.push('__initLoader');
 
- })(KISSY, KISSY.__loader, KISSY.__loaderUtils);/**
 
-  * @module  web.js
 
-  * @author  lifesinger@gmail.com,yiminghe@gmail.com
 
-  * @description this code can only run at browser environment
 
-  */
 
- (function(S, undefined) {
 
-     var win = S.__HOST,
 
-         doc = win['document'],
 
-         docElem = doc.documentElement,
 
-         EMPTY = '',
 
-         // Is the DOM ready to be used? Set to true once it occurs.
 
-         isReady = false,
 
-         // The functions to execute on DOM ready.
 
-         readyList = [],
 
-         // The number of poll times.
 
-         POLL_RETRYS = 500,
 
-         // The poll interval in milliseconds.
 
-         POLL_INTERVAL = 40,
 
-         // #id or id
 
-         RE_IDSTR = /^#?([\w-]+)$/,
 
-         RE_NOT_WHITE = /\S/;
 
-     S.mix(S, {
 
-         /**
 
-          * A crude way of determining if an object is a window
 
-          */
 
-         isWindow: function(o) {
 
-             return S.type(o) === 'object'
 
-                 && 'setInterval' in o
 
-                 && 'document' in o
 
-                 && o.document.nodeType == 9;
 
-         },
 
-         parseXML: function(data) {
 
-             var xml;
 
-             try {
 
-                 // Standard
 
-                 if (window.DOMParser) {
 
-                     xml = new DOMParser().parseFromString(data, "text/xml");
 
-                 } else { // IE
 
-                     xml = new ActiveXObject("Microsoft.XMLDOM");
 
-                     xml.async = "false";
 
-                     xml.loadXML(data);
 
-                 }
 
-             } catch(e) {
 
-                 S.log("parseXML error : ");
 
-                 S.log(e);
 
-                 xml = undefined;
 
-             }
 
-             if (!xml || !xml.documentElement || xml.getElementsByTagName("parsererror").length) {
 
-                 S.error("Invalid XML: " + data);
 
-             }
 
-             return xml;
 
-         },
 
-         /**
 
-          * Evalulates a script in a global context.
 
-          */
 
-         globalEval: function(data) {
 
-             if (data && RE_NOT_WHITE.test(data)) {
 
-                 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
 
-                 ( window.execScript || function(data) {
 
-                     window[ "eval" ].call(window, data);
 
-                 } )(data);
 
-             }
 
-         },
 
-         /**
 
-          * Specify a function to execute when the DOM is fully loaded.
 
-          * @param fn {Function} A function to execute after the DOM is ready
 
-          * <code>
 
-          * KISSY.ready(function(S){ });
 
-          * </code>
 
-          * @return {KISSY}
 
-          */
 
-         ready: function(fn) {
 
-             // If the DOM is already ready
 
-             if (isReady) {
 
-                 // Execute the function immediately
 
-                 fn.call(win, this);
 
-             } else {
 
-                 // Remember the function for later
 
-                 readyList.push(fn);
 
-             }
 
-             return this;
 
-         },
 
-         /**
 
-          * Executes the supplied callback when the item with the supplied id is found.
 
-          * @param id <String> The id of the element, or an array of ids to look for.
 
-          * @param fn <Function> What to execute when the element is found.
 
-          */
 
-         available: function(id, fn) {
 
-             id = (id + EMPTY).match(RE_IDSTR)[1];
 
-             if (!id || !S.isFunction(fn)) {
 
-                 return;
 
-             }
 
-             var retryCount = 1,
 
-                 node,
 
-                 timer = S.later(function() {
 
-                     if ((node = doc.getElementById(id)) && (fn(node) || 1) ||
 
-                         ++retryCount > POLL_RETRYS) {
 
-                         timer.cancel();
 
-                     }
 
-                 }, POLL_INTERVAL, true);
 
-         }
 
-     });
 
-     /**
 
-      * Binds ready events.
 
-      */
 
-     function _bindReady() {
 
-         var doScroll = docElem.doScroll,
 
-             eventType = doScroll ? 'onreadystatechange' : 'DOMContentLoaded',
 
-             COMPLETE = 'complete',
 
-             fire = function() {
 
-                 _fireReady();
 
-             };
 
-         // Catch cases where ready() is called after the
 
-         // browser event has already occurred.
 
-         if (doc.readyState === COMPLETE) {
 
-             return fire();
 
-         }
 
-         // w3c mode
 
-         if (doc.addEventListener) {
 
-             function domReady() {
 
-                 doc.removeEventListener(eventType, domReady, false);
 
-                 fire();
 
-             }
 
-             doc.addEventListener(eventType, domReady, false);
 
-             // A fallback to window.onload, that will always work
 
-             win.addEventListener('load', fire, false);
 
-         }
 
-         // IE event model is used
 
-         else {
 
-             function stateChange() {
 
-                 if (doc.readyState === COMPLETE) {
 
-                     doc.detachEvent(eventType, stateChange);
 
-                     fire();
 
-                 }
 
-             }
 
-             // ensure firing before onload, maybe late but safe also for iframes
 
-             doc.attachEvent(eventType, stateChange);
 
-             // A fallback to window.onload, that will always work.
 
-             win.attachEvent('onload', fire);
 
-             // If IE and not a frame
 
-             // continually check to see if the document is ready
 
-             var notframe = false;
 
-             try {
 
-                 notframe = (win['frameElement'] === null);
 
-             } catch(e) {
 
-                 S.log("frameElement error : ");
 
-                 S.log(e);
 
-             }
 
-             if (doScroll && notframe) {
 
-                 function readyScroll() {
 
-                     try {
 
-                         // Ref: http://javascript.nwbox.com/IEContentLoaded/
 
-                         doScroll('left');
 
-                         fire();
 
-                     } catch(ex) {
 
-                         //S.log("detect document ready : " + ex);
 
-                         setTimeout(readyScroll, POLL_INTERVAL);
 
-                     }
 
-                 }
 
-                 readyScroll();
 
-             }
 
-         }
 
-         return 0;
 
-     }
 
-     /**
 
-      * Executes functions bound to ready event.
 
-      */
 
-     function _fireReady() {
 
-         if (isReady) {
 
-             return;
 
-         }
 
-         // Remember that the DOM is ready
 
-         isReady = true;
 
-         // If there are functions bound, to execute
 
-         if (readyList) {
 
-             // Execute all of them
 
-             var fn, i = 0;
 
-             while (fn = readyList[i++]) {
 
-                 fn.call(win, S);
 
-             }
 
-             // Reset the list of functions
 
-             readyList = null;
 
-         }
 
-     }
 
-     // If url contains '?ks-debug', debug mode will turn on automatically.
 
-     if (location && (location.search || EMPTY).indexOf('ks-debug') !== -1) {
 
-         S.Config.debug = true;
 
-     }
 
-     /**
 
-      * bind on start
 
-      * in case when you bind but the DOMContentLoaded has triggered
 
-      * then you has to wait onload
 
-      * worst case no callback at all
 
-      */
 
-     _bindReady();
 
- })(KISSY, undefined);
 
- /**
 
-  * 声明 kissy 核心中所包含的模块,动态加载时将直接从 core.js 中加载核心模块
 
-  * @description: 为了和 1.1.7 及以前版本保持兼容,务实与创新,兼容与革新 !
 
-  * @author yiminghe@gmail.com
 
-  */
 
- (function (S) {
 
-     S.config({
 
-         'combines':{
 
-             'core':['dom', 'ua', 'event', 'node', 'json', 'ajax', 'anim', 'base', 'cookie']
 
-         }
 
-     });
 
- })(KISSY);
 
- /**
 
-  combined files : 
 
- D:\code\kissy_git\kissy1.2\src\ua\base.js
 
- D:\code\kissy_git\kissy1.2\src\ua\extra.js
 
- D:\code\kissy_git\kissy1.2\src\ua.js
 
- D:\code\kissy_git\kissy1.2\src\dom\base.js
 
- D:\code\kissy_git\kissy1.2\src\dom\attr.js
 
- D:\code\kissy_git\kissy1.2\src\dom\class.js
 
- D:\code\kissy_git\kissy1.2\src\dom\create.js
 
- D:\code\kissy_git\kissy1.2\src\dom\data.js
 
- D:\code\kissy_git\kissy1.2\src\dom\insertion.js
 
- D:\code\kissy_git\kissy1.2\src\dom\offset.js
 
- D:\code\kissy_git\kissy1.2\src\dom\style.js
 
- D:\code\kissy_git\kissy1.2\src\dom\selector.js
 
- D:\code\kissy_git\kissy1.2\src\dom\style-ie.js
 
- D:\code\kissy_git\kissy1.2\src\dom\traversal.js
 
- D:\code\kissy_git\kissy1.2\src\dom.js
 
- D:\code\kissy_git\kissy1.2\src\event\keycodes.js
 
- D:\code\kissy_git\kissy1.2\src\event\object.js
 
- D:\code\kissy_git\kissy1.2\src\event\utils.js
 
- D:\code\kissy_git\kissy1.2\src\event\base.js
 
- D:\code\kissy_git\kissy1.2\src\event\target.js
 
- D:\code\kissy_git\kissy1.2\src\event\focusin.js
 
- D:\code\kissy_git\kissy1.2\src\event\hashchange.js
 
- D:\code\kissy_git\kissy1.2\src\event\valuechange.js
 
- D:\code\kissy_git\kissy1.2\src\event\delegate.js
 
- D:\code\kissy_git\kissy1.2\src\event\mouseenter.js
 
- D:\code\kissy_git\kissy1.2\src\event\submit.js
 
- D:\code\kissy_git\kissy1.2\src\event\change.js
 
- D:\code\kissy_git\kissy1.2\src\event\mousewheel.js
 
- D:\code\kissy_git\kissy1.2\src\event.js
 
- D:\code\kissy_git\kissy1.2\src\node\base.js
 
- D:\code\kissy_git\kissy1.2\src\node\attach.js
 
- D:\code\kissy_git\kissy1.2\src\node\override.js
 
- D:\code\kissy_git\kissy1.2\src\anim\easing.js
 
- D:\code\kissy_git\kissy1.2\src\anim\manager.js
 
- D:\code\kissy_git\kissy1.2\src\anim\fx.js
 
- D:\code\kissy_git\kissy1.2\src\anim\queue.js
 
- D:\code\kissy_git\kissy1.2\src\anim\base.js
 
- D:\code\kissy_git\kissy1.2\src\anim\color.js
 
- D:\code\kissy_git\kissy1.2\src\anim.js
 
- D:\code\kissy_git\kissy1.2\src\node\anim.js
 
- D:\code\kissy_git\kissy1.2\src\node.js
 
- D:\code\kissy_git\kissy1.2\src\json\json2.js
 
- D:\code\kissy_git\kissy1.2\src\json.js
 
- D:\code\kissy_git\kissy1.2\src\ajax\form-serializer.js
 
- D:\code\kissy_git\kissy1.2\src\ajax\xhrobject.js
 
- D:\code\kissy_git\kissy1.2\src\ajax\base.js
 
- D:\code\kissy_git\kissy1.2\src\ajax\xhrbase.js
 
- D:\code\kissy_git\kissy1.2\src\ajax\subdomain.js
 
- D:\code\kissy_git\kissy1.2\src\ajax\xdr.js
 
- D:\code\kissy_git\kissy1.2\src\ajax\xhr.js
 
- D:\code\kissy_git\kissy1.2\src\ajax\script.js
 
- D:\code\kissy_git\kissy1.2\src\ajax\jsonp.js
 
- D:\code\kissy_git\kissy1.2\src\ajax\form.js
 
- D:\code\kissy_git\kissy1.2\src\ajax\iframe-upload.js
 
- D:\code\kissy_git\kissy1.2\src\ajax.js
 
- D:\code\kissy_git\kissy1.2\src\base\attribute.js
 
- D:\code\kissy_git\kissy1.2\src\base\base.js
 
- D:\code\kissy_git\kissy1.2\src\base.js
 
- D:\code\kissy_git\kissy1.2\src\cookie\base.js
 
- D:\code\kissy_git\kissy1.2\src\cookie.js
 
- D:\code\kissy_git\kissy1.2\src\core.js
 
- **/
 
- /**
 
-  * @module  ua
 
-  * @author  lifesinger@gmail.com
 
-  */
 
- KISSY.add('ua/base', function() {
 
-     var ua = navigator.userAgent,
 
-         EMPTY = '', MOBILE = 'mobile',
 
-         core = EMPTY, shell = EMPTY, m,
 
-         IE_DETECT_RANGE = [6, 9], v, end,
 
-         VERSION_PLACEHOLDER = '{{version}}',
 
-         IE_DETECT_TPL = '<!--[if IE ' + VERSION_PLACEHOLDER + ']><s></s><![endif]-->',
 
-         div = document.createElement('div'), s,
 
-         o = {
 
-             // browser core type
 
-             //webkit: 0,
 
-             //trident: 0,
 
-             //gecko: 0,
 
-             //presto: 0,
 
-             // browser type
 
-             //chrome: 0,
 
-             //safari: 0,
 
-             //firefox:  0,
 
-             //ie: 0,
 
-             //opera: 0
 
-             //mobile: '',
 
-             //core: '',
 
-             //shell: ''
 
-         },
 
-         numberify = function(s) {
 
-             var c = 0;
 
-             // convert '1.2.3.4' to 1.234
 
-             return parseFloat(s.replace(/\./g, function() {
 
-                 return (c++ === 0) ? '.' : '';
 
-             }));
 
-         };
 
-     // try to use IE-Conditional-Comment detect IE more accurately
 
-     // IE10 doesn't support this method, @ref: http://blogs.msdn.com/b/ie/archive/2011/07/06/html5-parsing-in-ie10.aspx
 
-     div.innerHTML = IE_DETECT_TPL.replace(VERSION_PLACEHOLDER, '');
 
-     s = div.getElementsByTagName('s');
 
-     if (s.length > 0) {
 
-         shell = 'ie';
 
-         o[core = 'trident'] = 0.1; // Trident detected, look for revision
 
-         // Get the Trident's accurate version
 
-         if ((m = ua.match(/Trident\/([\d.]*)/)) && m[1]) {
 
-             o[core] = numberify(m[1]);
 
-         }
 
-         // Detect the accurate version
 
-         // 注意:
 
-         //  o.shell = ie, 表示外壳是 ie
 
-         //  但 o.ie = 7, 并不代表外壳是 ie7, 还有可能是 ie8 的兼容模式
 
-         //  对于 ie8 的兼容模式,还要通过 documentMode 去判断。但此处不能让 o.ie = 8, 否则
 
-         //  很多脚本判断会失误。因为 ie8 的兼容模式表现行为和 ie7 相同,而不是和 ie8 相同
 
-         for (v = IE_DETECT_RANGE[0],end = IE_DETECT_RANGE[1]; v <= end; v++) {
 
-             div.innerHTML = IE_DETECT_TPL.replace(VERSION_PLACEHOLDER, v);
 
-             if (s.length > 0) {
 
-                 o[shell] = v;
 
-                 break;
 
-             }
 
-         }
 
-     } else {
 
-         // WebKit
 
-         if ((m = ua.match(/AppleWebKit\/([\d.]*)/)) && m[1]) {
 
-             o[core = 'webkit'] = numberify(m[1]);
 
-             // Chrome
 
-             if ((m = ua.match(/Chrome\/([\d.]*)/)) && m[1]) {
 
-                 o[shell = 'chrome'] = numberify(m[1]);
 
-             }
 
-             // Safari
 
-             else if ((m = ua.match(/\/([\d.]*) Safari/)) && m[1]) {
 
-                 o[shell = 'safari'] = numberify(m[1]);
 
-             }
 
-             // Apple Mobile
 
-             if (/ Mobile\//.test(ua)) {
 
-                 o[MOBILE] = 'apple'; // iPad, iPhone or iPod Touch
 
-             }
 
-             // Other WebKit Mobile Browsers
 
-             else if ((m = ua.match(/NokiaN[^\/]*|Android \d\.\d|webOS\/\d\.\d/))) {
 
-                 o[MOBILE] = m[0].toLowerCase(); // Nokia N-series, Android, webOS, ex: NokiaN95
 
-             }
 
-         }
 
-         // NOT WebKit
 
-         else {
 
-             // Presto
 
-             // ref: http://www.useragentstring.com/pages/useragentstring.php
 
-             if ((m = ua.match(/Presto\/([\d.]*)/)) && m[1]) {
 
-                 o[core = 'presto'] = numberify(m[1]);
 
-                 // Opera
 
-                 if ((m = ua.match(/Opera\/([\d.]*)/)) && m[1]) {
 
-                     o[shell = 'opera'] = numberify(m[1]); // Opera detected, look for revision
 
-                     if ((m = ua.match(/Opera\/.* Version\/([\d.]*)/)) && m[1]) {
 
-                         o[shell] = numberify(m[1]);
 
-                     }
 
-                     // Opera Mini
 
-                     if ((m = ua.match(/Opera Mini[^;]*/)) && m) {
 
-                         o[MOBILE] = m[0].toLowerCase(); // ex: Opera Mini/2.0.4509/1316
 
-                     }
 
-                     // Opera Mobile
 
-                     // ex: Opera/9.80 (Windows NT 6.1; Opera Mobi/49; U; en) Presto/2.4.18 Version/10.00
 
-                     // issue: 由于 Opera Mobile 有 Version/ 字段,可能会与 Opera 混淆,同时对于 Opera Mobile 的版本号也比较混乱
 
-                     else if ((m = ua.match(/Opera Mobi[^;]*/)) && m) {
 
-                         o[MOBILE] = m[0];
 
-                     }
 
-                 }
 
-                 // NOT WebKit or Presto
 
-             } else {
 
-                 // MSIE
 
-                 // 由于最开始已经使用了 IE 条件注释判断,因此落到这里的唯一可能性只有 IE10+
 
-                 if ((m = ua.match(/MSIE\s([^;]*)/)) && m[1]) {
 
-                     o[core = 'trident'] = 0.1; // Trident detected, look for revision
 
-                     o[shell = 'ie'] = numberify(m[1]);
 
-                     // Get the Trident's accurate version
 
-                     if ((m = ua.match(/Trident\/([\d.]*)/)) && m[1]) {
 
-                         o[core] = numberify(m[1]);
 
-                     }
 
-                     // NOT WebKit, Presto or IE
 
-                 } else {
 
-                     // Gecko
 
-                     if ((m = ua.match(/Gecko/))) {
 
-                         o[core = 'gecko'] = 0.1; // Gecko detected, look for revision
 
-                         if ((m = ua.match(/rv:([\d.]*)/)) && m[1]) {
 
-                             o[core] = numberify(m[1]);
 
-                         }
 
-                         // Firefox
 
-                         if ((m = ua.match(/Firefox\/([\d.]*)/)) && m[1]) {
 
-                             o[shell = 'firefox'] = numberify(m[1]);
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-     }
 
-     o.core = core;
 
-     o.shell = shell;
 
-     o._numberify = numberify;
 
-     return o;
 
- });
 
- /**
 
-  * NOTES:
 
-  *
 
-  * 2011.11.08
 
-  *  - ie < 10 使用条件注释判断内核,更精确 by gonghaocn@gmail.com
 
-  *
 
-  * 2010.03
 
-  *  - jQuery, YUI 等类库都推荐用特性探测替代浏览器嗅探。特性探测的好处是能自动适应未来设备和未知设备,比如
 
-  *    if(document.addEventListener) 假设 IE9 支持标准事件,则代码不用修改,就自适应了“未来浏览器”。
 
-  *    对于未知浏览器也是如此。但是,这并不意味着浏览器嗅探就得彻底抛弃。当代码很明确就是针对已知特定浏览器的,
 
-  *    同时并非是某个特性探测可以解决时,用浏览器嗅探反而能带来代码的简洁,同时也也不会有什么后患。总之,一切
 
-  *    皆权衡。
 
-  *  - UA.ie && UA.ie < 8 并不意味着浏览器就不是 IE8, 有可能是 IE8 的兼容模式。进一步的判断需要使用 documentMode.
 
-  *
 
-  * TODO:
 
-  *  - test mobile
 
-  *  - 3Q 大战后,360 去掉了 UA 信息中的 360 信息,需采用 res 方法去判断
 
-  *
 
-  */
 
- /**
 
-  * @module  ua-extra
 
-  * @author  gonghao<gonghao@ghsky.com>
 
-  */
 
- KISSY.add('ua/extra', function(S, UA) {
 
-     var ua = navigator.userAgent,
 
-         m, external, shell,
 
-         o = { },
 
-         numberify = UA._numberify;
 
-     /**
 
-      * 说明:
 
-      * @子涯总结的各国产浏览器的判断依据: http://spreadsheets0.google.com/ccc?key=tluod2VGe60_ceDrAaMrfMw&hl=zh_CN#gid=0
 
-      * 根据 CNZZ 2009 年度浏览器占用率报告,优化了判断顺序:http://www.tanmi360.com/post/230.htm
 
-      * 如果检测出浏览器,但是具体版本号未知用 0.1 作为标识
 
-      * 世界之窗 & 360 浏览器,在 3.x 以下的版本都无法通过 UA 或者特性检测进行判断,所以目前只要检测到 UA 关键字就认为起版本号为 3
 
-      */
 
-     // 360Browser
 
-     if (m = ua.match(/360SE/)) {
 
-         o[shell = 'se360'] = 3; // issue: 360Browser 2.x cannot be recognised, so if recognised default set verstion number to 3
 
-     }
 
-     // Maxthon
 
-     else if ((m = ua.match(/Maxthon/)) && (external = window.external)) {
 
-         // issue: Maxthon 3.x in IE-Core cannot be recognised and it doesn't have exact version number
 
-         // but other maxthon versions all have exact version number
 
-         shell = 'maxthon';
 
-         try {
 
-             o[shell] = numberify(external['max_version']);
 
-         } catch(ex) {
 
-             o[shell] = 0.1;
 
-         }
 
-     }
 
-     // TT
 
-     else if (m = ua.match(/TencentTraveler\s([\d.]*)/)) {
 
-         o[shell = 'tt'] = m[1] ? numberify(m[1]) : 0.1;
 
-     }
 
-     // TheWorld
 
-     else if (m = ua.match(/TheWorld/)) {
 
-         o[shell = 'theworld'] = 3; // issue: TheWorld 2.x cannot be recognised, so if recognised default set verstion number to 3
 
-     }
 
-     // Sougou
 
-     else if (m = ua.match(/SE\s([\d.]*)/)) {
 
-         o[shell = 'sougou'] = m[1] ? numberify(m[1]) : 0.1;
 
-     }
 
-     // If the browser has shell(no matter IE-core or Webkit-core or others), set the shell key
 
-     shell && (o.shell = shell);
 
-     S.mix(UA, o);
 
-     return UA;
 
- }, {
 
-     requires:["ua/base"]
 
- });
 
- KISSY.add("ua", function(S,UA) {
 
-     return UA;
 
- }, {
 
-     requires:["ua/extra"]
 
- });
 
- /**
 
-  * @module  dom
 
-  * @author  yiminghe@gmail.com,lifesinger@gmail.com
 
-  */
 
- KISSY.add('dom/base', function(S, UA, undefined) {
 
-     function nodeTypeIs(node, val) {
 
-         return node && node.nodeType === val;
 
-     }
 
-     var NODE_TYPE = {
 
-         /**
 
-          * enumeration of dom node type
 
-          * @type Number
 
-          */
 
-         ELEMENT_NODE : 1,
 
-         "ATTRIBUTE_NODE" : 2,
 
-         TEXT_NODE:3,
 
-         "CDATA_SECTION_NODE" : 4,
 
-         "ENTITY_REFERENCE_NODE": 5,
 
-         "ENTITY_NODE" : 6,
 
-         "PROCESSING_INSTRUCTION_NODE" :7,
 
-         COMMENT_NODE : 8,
 
-         DOCUMENT_NODE : 9,
 
-         "DOCUMENT_TYPE_NODE" : 10,
 
-         DOCUMENT_FRAGMENT_NODE : 11,
 
-         "NOTATION_NODE" : 12
 
-     };
 
-     var DOM = {
 
-         _isCustomDomain :function (win) {
 
-             win = win || window;
 
-             var domain = win.document.domain,
 
-                 hostname = win.location.hostname;
 
-             return domain != hostname &&
 
-                 domain != ( '[' + hostname + ']' );	// IPv6 IP support
 
-         },
 
-         _genEmptyIframeSrc:function(win) {
 
-             win = win || window;
 
-             if (UA['ie'] && DOM._isCustomDomain(win)) {
 
-                 return  'javascript:void(function(){' + encodeURIComponent("" +
 
-                     "document.open();" +
 
-                     "document.domain='" +
 
-                     win.document.domain
 
-                     + "';" +
 
-                     "document.close();") + "}())";
 
-             }
 
-         },
 
-         _NODE_TYPE:NODE_TYPE,
 
-         /**
 
-          * 是不是 element node
 
-          */
 
-         _isElementNode: function(elem) {
 
-             return nodeTypeIs(elem, DOM.ELEMENT_NODE);
 
-         },
 
-         /**
 
-          * elem 为 window 时,直接返回
 
-          * elem 为 document 时,返回关联的 window
 
-          * elem 为 undefined 时,返回当前 window
 
-          * 其它值,返回 false
 
-          */
 
-         _getWin: function(elem) {
 
-             return (elem && ('scrollTo' in elem) && elem['document']) ?
 
-                 elem :
 
-                 nodeTypeIs(elem, DOM.DOCUMENT_NODE) ?
 
-                     elem.defaultView || elem.parentWindow :
 
-                     (elem === undefined || elem === null) ?
 
-                         window : false;
 
-         },
 
-         _nodeTypeIs: nodeTypeIs,
 
-         // Ref: http://lifesinger.github.com/lab/2010/nodelist.html
 
-         _isNodeList:function(o) {
 
-             // 注1:ie 下,有 window.item, typeof node.item 在 ie 不同版本下,返回值不同
 
-             // 注2:select 等元素也有 item, 要用 !node.nodeType 排除掉
 
-             // 注3:通过 namedItem 来判断不可靠
 
-             // 注4:getElementsByTagName 和 querySelectorAll 返回的集合不同
 
-             // 注5: 考虑 iframe.contentWindow
 
-             return o && !o.nodeType && o.item && !o.setTimeout;
 
-         },
 
-         _nodeName:function(e, name) {
 
-             return e && e.nodeName.toLowerCase() === name.toLowerCase();
 
-         }
 
-     };
 
-     S.mix(DOM, NODE_TYPE);
 
-     return DOM;
 
- }, {
 
-     requires:['ua']
 
- });
 
- /**
 
-  * 2011-08
 
-  *  - 添加键盘枚举值,方便依赖程序清晰
 
-  */
 
- /**
 
-  * @module  dom-attr
 
-  * @author  yiminghe@gmail.com,lifesinger@gmail.com
 
-  */
 
- KISSY.add('dom/attr', function(S, DOM, UA, undefined) {
 
-         var doc = document,
 
-             docElement = doc.documentElement,
 
-             oldIE = !docElement.hasAttribute,
 
-             TEXT = docElement.textContent === undefined ?
 
-                 'innerText' : 'textContent',
 
-             EMPTY = '',
 
-             nodeName = DOM._nodeName,
 
-             isElementNode = DOM._isElementNode,
 
-             rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
 
-             rfocusable = /^(?:button|input|object|select|textarea)$/i,
 
-             rclickable = /^a(?:rea)?$/i,
 
-             rinvalidChar = /:|^on/,
 
-             rreturn = /\r/g,
 
-             attrFix = {
 
-             },
 
-             attrFn = {
 
-                 val: 1,
 
-                 css: 1,
 
-                 html: 1,
 
-                 text: 1,
 
-                 data: 1,
 
-                 width: 1,
 
-                 height: 1,
 
-                 offset: 1,
 
-                 scrollTop:1,
 
-                 scrollLeft:1
 
-             },
 
-             attrHooks = {
 
-                 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
 
-                 tabindex:{
 
-                     get:function(el) {
 
-                         // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
 
-                         var attributeNode = el.getAttributeNode("tabindex");
 
-                         return attributeNode && attributeNode.specified ?
 
-                             parseInt(attributeNode.value, 10) :
 
-                             rfocusable.test(el.nodeName) || rclickable.test(el.nodeName) && el.href ?
 
-                                 0 :
 
-                                 undefined;
 
-                     }
 
-                 },
 
-                 // 在标准浏览器下,用 getAttribute 获取 style 值
 
-                 // IE7- 下,需要用 cssText 来获取
 
-                 // 统一使用 cssText
 
-                 style:{
 
-                     get:function(el) {
 
-                         return el.style.cssText;
 
-                     },
 
-                     set:function(el, val) {
 
-                         el.style.cssText = val;
 
-                     }
 
-                 }
 
-             },
 
-             propFix = {
 
-                 tabindex: "tabIndex",
 
-                 readonly: "readOnly",
 
-                 "for": "htmlFor",
 
-                 "class": "className",
 
-                 maxlength: "maxLength",
 
-                 cellspacing: "cellSpacing",
 
-                 "cellpadding": "cellPadding",
 
-                 rowspan: "rowSpan",
 
-                 colspan: "colSpan",
 
-                 usemap: "useMap",
 
-                 frameborder: "frameBorder",
 
-                 "contenteditable": "contentEditable"
 
-             },
 
-             // Hook for boolean attributes
 
-             // if bool is false
 
-             //  - standard browser returns null
 
-             //  - ie<8 return false
 
-             //   - so norm to undefined
 
-             boolHook = {
 
-                 get: function(elem, name) {
 
-                     // 转发到 prop 方法
 
-                     return DOM.prop(elem, name) ?
 
-                         // 根据 w3c attribute , true 时返回属性名字符串
 
-                         name.toLowerCase() :
 
-                         undefined;
 
-                 },
 
-                 set: function(elem, value, name) {
 
-                     var propName;
 
-                     if (value === false) {
 
-                         // Remove boolean attributes when set to false
 
-                         DOM.removeAttr(elem, name);
 
-                     } else {
 
-                         // 直接设置 true,因为这是 bool 类属性
 
-                         propName = propFix[ name ] || name;
 
-                         if (propName in elem) {
 
-                             // Only set the IDL specifically if it already exists on the element
 
-                             elem[ propName ] = true;
 
-                         }
 
-                         elem.setAttribute(name, name.toLowerCase());
 
-                     }
 
-                     return name;
 
-                 }
 
-             },
 
-             propHooks = {},
 
-             // get attribute value from attribute node , only for ie
 
-             attrNodeHook = {
 
-             },
 
-             valHooks = {
 
-                 option: {
 
-                     get: function(elem) {
 
-                         // 当没有设定 value 时,标准浏览器 option.value === option.text
 
-                         // ie7- 下,没有设定 value 时,option.value === '', 需要用 el.attributes.value 来判断是否有设定 value
 
-                         var val = elem.attributes.value;
 
-                         return !val || val.specified ? elem.value : elem.text;
 
-                     }
 
-                 },
 
-                 select: {
 
-                     // 对于 select, 特别是 multiple type, 存在很严重的兼容性问题
 
-                     get: function(elem) {
 
-                         var index = elem.selectedIndex,
 
-                             options = elem.options,
 
-                             one = elem.type === "select-one";
 
-                         // Nothing was selected
 
-                         if (index < 0) {
 
-                             return null;
 
-                         } else if (one) {
 
-                             return DOM.val(options[index]);
 
-                         }
 
-                         // Loop through all the selected options
 
-                         var ret = [], i = 0, len = options.length;
 
-                         for (; i < len; ++i) {
 
-                             if (options[i].selected) {
 
-                                 ret.push(DOM.val(options[i]));
 
-                             }
 
-                         }
 
-                         // Multi-Selects return an array
 
-                         return ret;
 
-                     },
 
-                     set: function(elem, value) {
 
-                         var values = S.makeArray(value),
 
-                             opts = elem.options;
 
-                         S.each(opts, function(opt) {
 
-                             opt.selected = S.inArray(DOM.val(opt), values);
 
-                         });
 
-                         if (!values.length) {
 
-                             elem.selectedIndex = -1;
 
-                         }
 
-                         return values;
 
-                     }
 
-                 }};
 
-         function isTextNode(elem) {
 
-             return DOM._nodeTypeIs(elem, DOM.TEXT_NODE);
 
-         }
 
-         if (oldIE) {
 
-             // get attribute value from attribute node for ie
 
-             attrNodeHook = {
 
-                 get: function(elem, name) {
 
-                     var ret;
 
-                     ret = elem.getAttributeNode(name);
 
-                     // Return undefined if nodeValue is empty string
 
-                     return ret && ret.nodeValue !== "" ?
 
-                         ret.nodeValue :
 
-                         undefined;
 
-                 },
 
-                 set: function(elem, value, name) {
 
-                     // Check form objects in IE (multiple bugs related)
 
-                     // Only use nodeValue if the attribute node exists on the form
 
-                     var ret = elem.getAttributeNode(name);
 
-                     if (ret) {
 
-                         ret.nodeValue = value;
 
-                     } else {
 
-                         try {
 
-                             var attr = elem.ownerDocument.createAttribute(name);
 
-                             attr.value = value;
 
-                             elem.setAttributeNode(attr);
 
-                         }
 
-                         catch (e) {
 
-                             // It's a real failure only if setAttribute also fails.
 
-                             return elem.setAttribute(name, value, 0);
 
-                         }
 
-                     }
 
-                 }
 
-             };
 
-             // ie6,7 不区分 attribute 与 property
 
-             attrFix = propFix;
 
-             // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
 
-             attrHooks.tabIndex = attrHooks.tabindex;
 
-             // fix ie bugs
 
-             // 不光是 href, src, 还有 rowspan 等非 mapping 属性,也需要用第 2 个参数来获取原始值
 
-             // 注意 colSpan rowSpan 已经由 propFix 转为大写
 
-             S.each([ "href", "src", "width", "height","colSpan","rowSpan" ], function(name) {
 
-                 attrHooks[ name ] = {
 
-                     get: function(elem) {
 
-                         var ret = elem.getAttribute(name, 2);
 
-                         return ret === null ? undefined : ret;
 
-                     }
 
-                 };
 
-             });
 
-             // button 元素的 value 属性和其内容冲突
 
-             // <button value='xx'>zzz</button>
 
-             valHooks.button = attrHooks.value = attrNodeHook;
 
-         }
 
-         // Radios and checkboxes getter/setter
 
-         S.each([ "radio", "checkbox" ], function(r) {
 
-             valHooks[ r ] = {
 
-                 get: function(elem) {
 
-                     // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
 
-                     return elem.getAttribute("value") === null ? "on" : elem.value;
 
-                 },
 
-                 set: function(elem, value) {
 
-                     if (S.isArray(value)) {
 
-                         return elem.checked = S.inArray(DOM.val(elem), value);
 
-                     }
 
-                 }
 
-             };
 
-         });
 
-         function getProp(elem, name) {
 
-             name = propFix[ name ] || name;
 
-             var hook = propHooks[ name ];
 
-             if (hook && hook.get) {
 
-                 return hook.get(elem, name);
 
-             } else {
 
-                 return elem[ name ];
 
-             }
 
-         }
 
-         S.mix(DOM, {
 
-             /**
 
-              * 自定义属性不推荐使用,使用 .data
 
-              * @param selector
 
-              * @param name
 
-              * @param value
 
-              */
 
-             prop: function(selector, name, value) {
 
-                 // suports hash
 
-                 if (S.isPlainObject(name)) {
 
-                     for (var k in name) {
 
-                         DOM.prop(selector, k, name[k]);
 
-                     }
 
-                     return;
 
-                 }
 
-                 var elems = DOM.query(selector);
 
-                 // Try to normalize/fix the name
 
-                 name = propFix[ name ] || name;
 
-                 var hook = propHooks[ name ];
 
-                 if (value !== undefined) {
 
-                     elems.each(function(elem) {
 
-                         if (hook && hook.set) {
 
-                             hook.set(elem, value, name);
 
-                         } else {
 
-                             elem[ name ] = value;
 
-                         }
 
-                     });
 
-                 } else {
 
-                     if (elems.length) {
 
-                         return getProp(elems[0], name);
 
-                     }
 
-                 }
 
-             },
 
-             /**
 
-              * 是否其中一个元素包含指定 property
 
-              * @param selector
 
-              * @param name
 
-              */
 
-             hasProp:function(selector, name) {
 
-                 var elems = DOM.query(selector);
 
-                 for (var i = 0; i < elems.length; i++) {
 
-                     var el = elems[i];
 
-                     if (getProp(el, name) !== undefined) {
 
-                         return true;
 
-                     }
 
-                 }
 
-                 return false;
 
-             },
 
-             /**
 
-              * 不推荐使用,使用 .data .removeData
 
-              * @param selector
 
-              * @param name
 
-              */
 
-             removeProp:function(selector, name) {
 
-                 name = propFix[ name ] || name;
 
-                 DOM.query(selector).each(function(el) {
 
-                     try {
 
-                         el[ name ] = undefined;
 
-                         delete el[ name ];
 
-                     } catch(e) {
 
-                         S.log("delete el property error : ");
 
-                         S.log(e);
 
-                     }
 
-                 });
 
-             },
 
-             /**
 
-              * Gets the value of an attribute for the first element in the set of matched elements or
 
-              * Sets an attribute for the set of matched elements.
 
-              */
 
-             attr:function(selector, name, val, pass) {
 
-                 /*
 
-                  Hazards From Caja Note:
 
-                  - In IE[67], el.setAttribute doesn't work for attributes like
 
-                  'class' or 'for'.  IE[67] expects you to set 'className' or
 
-                  'htmlFor'.  Caja use setAttributeNode solves this problem.
 
-                  - In IE[67], <input> elements can shadow attributes.  If el is a
 
-                  form that contains an <input> named x, then el.setAttribute(x, y)
 
-                  will set x's value rather than setting el's attribute.  Using
 
-                  setAttributeNode solves this problem.
 
-                  - In IE[67], the style attribute can only be modified by setting
 
-                  el.style.cssText.  Neither setAttribute nor setAttributeNode will
 
-                  work.  el.style.cssText isn't bullet-proof, since it can be
 
-                  shadowed by <input> elements.
 
-                  - In IE[67], you can never change the type of an <button> element.
 
-                  setAttribute('type') silently fails, but setAttributeNode
 
-                  throws an exception.  caja : the silent failure. KISSY throws error.
 
-                  - In IE[67], you can never change the type of an <input> element.
 
-                  setAttribute('type') throws an exception.  We want the exception.
 
-                  - In IE[67], setAttribute is case-sensitive, unless you pass 0 as a
 
-                  3rd argument.  setAttributeNode is case-insensitive.
 
-                  - Trying to set an invalid name like ":" is supposed to throw an
 
-                  error.  In IE[678] and Opera 10, it fails without an error.
 
-                  */
 
-                 // suports hash
 
-                 if (S.isPlainObject(name)) {
 
-                     pass = val;
 
-                     for (var k in name) {
 
-                         DOM.attr(selector, k, name[k], pass);
 
-                     }
 
-                     return;
 
-                 }
 
-                 if (!(name = S.trim(name))) {
 
-                     return;
 
-                 }
 
-                 // attr functions
 
-                 if (pass && attrFn[name]) {
 
-                     return DOM[name](selector, val);
 
-                 }
 
-                 // scrollLeft
 
-                 name = name.toLowerCase();
 
-                 if (pass && attrFn[name]) {
 
-                     return DOM[name](selector, val);
 
-                 }
 
-                 var els = DOM.query(selector);
 
-                 if (val === undefined) {
 
-                     return DOM.__attr(els[0], name);
 
-                 } else {
 
-                     els.each(function(el) {
 
-                         DOM.__attr(el, name, val);
 
-                     });
 
-                 }
 
-             },
 
-             __attr:function(el, name, val) {
 
-                 if (!isElementNode(el)) {
 
-                     return;
 
-                 }
 
-                 // custom attrs
 
-                 name = attrFix[name] || name;
 
-                 var attrNormalizer,
 
-                     ret;
 
-                 // browsers index elements by id/name on forms, give priority to attributes.
 
-                 if (nodeName(el, "form")) {
 
-                     attrNormalizer = attrNodeHook;
 
-                 }
 
-                 else if (rboolean.test(name)) {
 
-                     attrNormalizer = boolHook;
 
-                 }
 
-                 // only old ie?
 
-                 else if (rinvalidChar.test(name)) {
 
-                     attrNormalizer = attrNodeHook;
 
-                 } else {
 
-                     attrNormalizer = attrHooks[name];
 
-                 }
 
-                 // getter
 
-                 if (val === undefined) {
 
-                     if (attrNormalizer && attrNormalizer.get) {
 
-                         return attrNormalizer.get(el, name);
 
-                     }
 
-                     ret = el.getAttribute(name);
 
-                     // standard browser non-existing attribute return null
 
-                     // ie<8 will return undefined , because it return property
 
-                     // so norm to undefined
 
-                     return ret === null ? undefined : ret;
 
-                 } else {
 
-                     if (attrNormalizer && attrNormalizer.set) {
 
-                         attrNormalizer.set(el, val, name);
 
-                     } else {
 
-                         // convert the value to a string (all browsers do this but IE)
 
-                         el.setAttribute(name, EMPTY + val);
 
-                     }
 
-                 }
 
-             },
 
-             /**
 
-              * Removes the attribute of the matched elements.
 
-              */
 
-             removeAttr: function(selector, name) {
 
-                 name = name.toLowerCase();
 
-                 name = attrFix[name] || name;
 
-                 DOM.query(selector).each(function(el) {
 
-                     if (isElementNode(el)) {
 
-                         var propName;
 
-                         el.removeAttribute(name);
 
-                         // Set corresponding property to false for boolean attributes
 
-                         if (rboolean.test(name) && (propName = propFix[ name ] || name) in el) {
 
-                             el[ propName ] = false;
 
-                         }
 
-                     }
 
-                 });
 
-             },
 
-             /**
 
-              * 是否其中一个元素包含指定属性
 
-              */
 
-             hasAttr: oldIE ?
 
-                 function(selector, name) {
 
-                     name = name.toLowerCase();
 
-                     var elems = DOM.query(selector);
 
-                     // from ppk :http://www.quirksmode.org/dom/w3c_core.html
 
-                     // IE5-7 doesn't return the value of a style attribute.
 
-                     // var $attr = el.attributes[name];
 
-                     for (var i = 0; i < elems.length; i++) {
 
-                         var el = elems[i];
 
-                         var $attr = el.getAttributeNode(name);
 
-                         if ($attr && $attr.specified) {
 
-                             return true;
 
-                         }
 
-                     }
 
-                     return false;
 
-                 }
 
-                 :
 
-                 function(selector, name) {
 
-                     var elems = DOM.query(selector);
 
-                     for (var i = 0; i < elems.length; i++) {
 
-                         var el = elems[i];
 
-                         //使用原生实现
 
-                         if (el.hasAttribute(name)) {
 
-                             return true;
 
-                         }
 
-                     }
 
-                     return false;
 
-                 },
 
-             /**
 
-              * Gets the current value of the first element in the set of matched or
 
-              * Sets the value of each element in the set of matched elements.
 
-              */
 
-             val : function(selector, value) {
 
-                 var hook, ret;
 
-                 //getter
 
-                 if (value === undefined) {
 
-                     var elem = DOM.get(selector);
 
-                     if (elem) {
 
-                         hook = valHooks[ elem.nodeName.toLowerCase() ] || valHooks[ elem.type ];
 
-                         if (hook && "get" in hook && (ret = hook.get(elem, "value")) !== undefined) {
 
-                             return ret;
 
-                         }
 
-                         ret = elem.value;
 
-                         return typeof ret === "string" ?
 
-                             // handle most common string cases
 
-                             ret.replace(rreturn, "") :
 
-                             // handle cases where value is null/undefined or number
 
-                             S.isNullOrUndefined(ret) ? "" : ret;
 
-                     }
 
-                     return;
 
-                 }
 
-                 DOM.query(selector).each(function(elem) {
 
-                     if (elem.nodeType !== 1) {
 
-                         return;
 
-                     }
 
-                     var val = value;
 
-                     // Treat null/undefined as ""; convert numbers to string
 
-                     if (S.isNullOrUndefined(val)) {
 
-                         val = "";
 
-                     } else if (typeof val === "number") {
 
-                         val += "";
 
-                     } else if (S.isArray(val)) {
 
-                         val = S.map(val, function (value) {
 
-                             return S.isNullOrUndefined(val) ? "" : value + "";
 
-                         });
 
-                     }
 
-                     hook = valHooks[ elem.nodeName.toLowerCase() ] || valHooks[ elem.type ];
 
-                     // If set returns undefined, fall back to normal setting
 
-                     if (!hook || !("set" in hook) || hook.set(elem, val, "value") === undefined) {
 
-                         elem.value = val;
 
-                     }
 
-                 });
 
-             },
 
-             /**
 
-              * Gets the text context of the first element in the set of matched elements or
 
-              * Sets the text content of the matched elements.
 
-              */
 
-             text: function(selector, val) {
 
-                 // getter
 
-                 if (val === undefined) {
 
-                     // supports css selector/Node/NodeList
 
-                     var el = DOM.get(selector);
 
-                     // only gets value on supported nodes
 
-                     if (isElementNode(el)) {
 
-                         return el[TEXT] || EMPTY;
 
-                     }
 
-                     else if (isTextNode(el)) {
 
-                         return el.nodeValue;
 
-                     }
 
-                     return undefined;
 
-                 }
 
-                 // setter
 
-                 else {
 
-                     DOM.query(selector).each(function(el) {
 
-                         if (isElementNode(el)) {
 
-                             el[TEXT] = val;
 
-                         }
 
-                         else if (isTextNode(el)) {
 
-                             el.nodeValue = val;
 
-                         }
 
-                     });
 
-                 }
 
-             }
 
-         });
 
-         return DOM;
 
-     }, {
 
-         requires:["./base","ua"]
 
-     }
 
- );
 
- /**
 
-  * NOTES:
 
-  * 承玉:2011-06-03
 
-  *  - 借鉴 jquery 1.6,理清 attribute 与 property
 
-  *
 
-  * 承玉:2011-01-28
 
-  *  - 处理 tabindex,顺便重构
 
-  *
 
-  * 2010.03
 
-  *  - 在 jquery/support.js 中,special attrs 里还有 maxlength, cellspacing,
 
-  *    rowspan, colspan, useap, frameboder, 但测试发现,在 Grade-A 级浏览器中
 
-  *    并无兼容性问题。
 
-  *  - 当 colspan/rowspan 属性值设置有误时,ie7- 会自动纠正,和 href 一样,需要传递
 
-  *    第 2 个参数来解决。jQuery 未考虑,存在兼容性 bug.
 
-  *  - jQuery 考虑了未显式设定 tabindex 时引发的兼容问题,kissy 里忽略(太不常用了)
 
-  *  - jquery/attributes.js: Safari mis-reports the default selected
 
-  *    property of an option 在 Safari 4 中已修复。
 
-  *
 
-  */
 
- /**
 
-  * @module  dom-class
 
-  * @author  lifesinger@gmail.com
 
-  */
 
- KISSY.add('dom/class', function(S, DOM, undefined) {
 
-     var SPACE = ' ',
 
-         REG_SPLIT = /[\.\s]\s*\.?/,
 
-         REG_CLASS = /[\n\t]/g;
 
-     function norm(elemClass) {
 
-         return (SPACE + elemClass + SPACE).replace(REG_CLASS, SPACE);
 
-     }
 
-     S.mix(DOM, {
 
-         __hasClass:function(el, cls) {
 
-             var className = el.className;
 
-             if (className) {
 
-                 className = norm(className);
 
-                 return className.indexOf(SPACE + cls + SPACE) > -1;
 
-             } else {
 
-                 return false;
 
-             }
 
-         },
 
-         /**
 
-          * Determine whether any of the matched elements are assigned the given class.
 
-          */
 
-         hasClass: function(selector, value) {
 
-             return batch(selector, value, function(elem, classNames, cl) {
 
-                 var elemClass = elem.className;
 
-                 if (elemClass) {
 
-                     var className = norm(elemClass),
 
-                         j = 0,
 
-                         ret = true;
 
-                     for (; j < cl; j++) {
 
-                         if (className.indexOf(SPACE + classNames[j] + SPACE) < 0) {
 
-                             ret = false;
 
-                             break;
 
-                         }
 
-                     }
 
-                     if (ret) {
 
-                         return true;
 
-                     }
 
-                 }
 
-             }, true);
 
-         },
 
-         /**
 
-          * Adds the specified class(es) to each of the set of matched elements.
 
-          */
 
-         addClass: function(selector, value) {
 
-             batch(selector, value, function(elem, classNames, cl) {
 
-                 var elemClass = elem.className;
 
-                 if (!elemClass) {
 
-                     elem.className = value;
 
-                 } else {
 
-                     var className = norm(elemClass),
 
-                         setClass = elemClass,
 
-                         j = 0;
 
-                     for (; j < cl; j++) {
 
-                         if (className.indexOf(SPACE + classNames[j] + SPACE) < 0) {
 
-                             setClass += SPACE + classNames[j];
 
-                         }
 
-                     }
 
-                     elem.className = S.trim(setClass);
 
-                 }
 
-             }, undefined);
 
-         },
 
-         /**
 
-          * Remove a single class, multiple classes, or all classes from each element in the set of matched elements.
 
-          */
 
-         removeClass: function(selector, value) {
 
-             batch(selector, value, function(elem, classNames, cl) {
 
-                 var elemClass = elem.className;
 
-                 if (elemClass) {
 
-                     if (!cl) {
 
-                         elem.className = '';
 
-                     } else {
 
-                         var className = norm(elemClass),
 
-                             j = 0,
 
-                             needle;
 
-                         for (; j < cl; j++) {
 
-                             needle = SPACE + classNames[j] + SPACE;
 
-                             // 一个 cls 有可能多次出现:'link link2 link link3 link'
 
-                             while (className.indexOf(needle) >= 0) {
 
-                                 className = className.replace(needle, SPACE);
 
-                             }
 
-                         }
 
-                         elem.className = S.trim(className);
 
-                     }
 
-                 }
 
-             }, undefined);
 
-         },
 
-         /**
 
-          * Replace a class with another class for matched elements.
 
-          * If no oldClassName is present, the newClassName is simply added.
 
-          */
 
-         replaceClass: function(selector, oldClassName, newClassName) {
 
-             DOM.removeClass(selector, oldClassName);
 
-             DOM.addClass(selector, newClassName);
 
-         },
 
-         /**
 
-          * Add or remove one or more classes from each element in the set of
 
-          * matched elements, depending on either the class's presence or the
 
-          * value of the switch argument.
 
-          * @param state {Boolean} optional boolean to indicate whether class
 
-          *        should be added or removed regardless of current state.
 
-          */
 
-         toggleClass: function(selector, value, state) {
 
-             var isBool = S.isBoolean(state), has;
 
-             batch(selector, value, function(elem, classNames, cl) {
 
-                 var j = 0, className;
 
-                 for (; j < cl; j++) {
 
-                     className = classNames[j];
 
-                     has = isBool ? !state : DOM.hasClass(elem, className);
 
-                     DOM[has ? 'removeClass' : 'addClass'](elem, className);
 
-                 }
 
-             }, undefined);
 
-         }
 
-     });
 
-     function batch(selector, value, fn, resultIsBool) {
 
-         if (!(value = S.trim(value))) {
 
-             return resultIsBool ? false : undefined;
 
-         }
 
-         var elems = DOM.query(selector),
 
-             len = elems.length,
 
-             tmp = value.split(REG_SPLIT),
 
-             elem,
 
-             ret;
 
-         var classNames = [];
 
-         for (var i = 0; i < tmp.length; i++) {
 
-             var t = S.trim(tmp[i]);
 
-             if (t) {
 
-                 classNames.push(t);
 
-             }
 
-         }
 
-         for (i = 0; i < len; i++) {
 
-             elem = elems[i];
 
-             if (DOM._isElementNode(elem)) {
 
-                 ret = fn(elem, classNames, classNames.length);
 
-                 if (ret !== undefined) {
 
-                     return ret;
 
-                 }
 
-             }
 
-         }
 
-         if (resultIsBool) {
 
-             return false;
 
-         }
 
-         return undefined;
 
-     }
 
-     return DOM;
 
- }, {
 
-     requires:["dom/base"]
 
- });
 
- /**
 
-  * NOTES:
 
-  *   - hasClass/addClass/removeClass 的逻辑和 jQuery 保持一致
 
-  *   - toggleClass 不支持 value 为 undefined 的情形(jQuery 支持)
 
-  */
 
- /**
 
-  * @module  dom-create
 
-  * @author  lifesinger@gmail.com,yiminghe@gmail.com
 
-  */
 
- KISSY.add('dom/create', function(S, DOM, UA, undefined) {
 
-         var doc = document,
 
-             ie = UA['ie'],
 
-             nodeTypeIs = DOM._nodeTypeIs,
 
-             isElementNode = DOM._isElementNode,
 
-             isString = S.isString,
 
-             DIV = 'div',
 
-             PARENT_NODE = 'parentNode',
 
-             DEFAULT_DIV = doc.createElement(DIV),
 
-             rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
 
-             RE_TAG = /<([\w:]+)/,
 
-             rleadingWhitespace = /^\s+/,
 
-             lostLeadingWhitespace = ie && ie < 9,
 
-             rhtml = /<|&#?\w+;/,
 
-             RE_SIMPLE_TAG = /^<(\w+)\s*\/?>(?:<\/\1>)?$/;
 
-         // help compression
 
-         function getElementsByTagName(el, tag) {
 
-             return el.getElementsByTagName(tag);
 
-         }
 
-         function cleanData(els) {
 
-             var Event = S.require("event");
 
-             if (Event) {
 
-                 Event.detach(els);
 
-             }
 
-             DOM.removeData(els);
 
-         }
 
-         S.mix(DOM, {
 
-             /**
 
-              * Creates a new HTMLElement using the provided html string.
 
-              */
 
-             create: function(html, props, ownerDoc, _trim/*internal*/) {
 
-                 if (isElementNode(html)
 
-                     || nodeTypeIs(html, DOM.TEXT_NODE)) {
 
-                     return DOM.clone(html);
 
-                 }
 
-                 var ret = null;
 
-                 if (!isString(html)) {
 
-                     return ret;
 
-                 }
 
-                 if (_trim === undefined) {
 
-                     _trim = true;
 
-                 }
 
-                 if (_trim) {
 
-                     html = S.trim(html);
 
-                 }
 
-                 if (!html) {
 
-                     return ret;
 
-                 }
 
-                 var creators = DOM._creators,
 
-                     holder,
 
-                     whitespaceMatch,
 
-                     context = ownerDoc || doc,
 
-                     m,
 
-                     tag = DIV,
 
-                     k,
 
-                     nodes;
 
-                 if (!rhtml.test(html)) {
 
-                     ret = context.createTextNode(html);
 
-                 }
 
-                 // 简单 tag, 比如 DOM.create('<p>')
 
-                 else if ((m = RE_SIMPLE_TAG.exec(html))) {
 
-                     ret = context.createElement(m[1]);
 
-                 }
 
-                 // 复杂情况,比如 DOM.create('<img src="sprite.png" />')
 
-                 else {
 
-                     // Fix "XHTML"-style tags in all browsers
 
-                     html = html.replace(rxhtmlTag, "<$1><" + "/$2>");
 
-                     if ((m = RE_TAG.exec(html)) && (k = m[1])) {
 
-                         tag = k.toLowerCase();
 
-                     }
 
-                     holder = (creators[tag] || creators[DIV])(html, context);
 
-                     // ie 把前缀空白吃掉了
 
-                     if (lostLeadingWhitespace && (whitespaceMatch = html.match(rleadingWhitespace))) {
 
-                         holder.insertBefore(context.createTextNode(whitespaceMatch[0]), holder.firstChild);
 
-                     }
 
-                     nodes = holder.childNodes;
 
-                     if (nodes.length === 1) {
 
-                         // return single node, breaking parentNode ref from "fragment"
 
-                         ret = nodes[0][PARENT_NODE].removeChild(nodes[0]);
 
-                     }
 
-                     else if (nodes.length) {
 
-                         // return multiple nodes as a fragment
 
-                         ret = nl2frag(nodes, context);
 
-                     } else {
 
-                         S.error(html + " : create node error");
 
-                     }
 
-                 }
 
-                 return attachProps(ret, props);
 
-             },
 
-             _creators: {
 
-                 div: function(html, ownerDoc) {
 
-                     var frag = ownerDoc && ownerDoc != doc ? ownerDoc.createElement(DIV) : DEFAULT_DIV;
 
-                     // html 为 <style></style> 时不行,必须有其他元素?
 
-                     frag['innerHTML'] = "m<div>" + html + "<" + "/div>";
 
-                     return frag.lastChild;
 
-                 }
 
-             },
 
-             /**
 
-              * Gets/Sets the HTML contents of the HTMLElement.
 
-              * @param {Boolean} loadScripts (optional) True to look for and process scripts (defaults to false).
 
-              * @param {Function} callback (optional) For async script loading you can be notified when the update completes.
 
-              */
 
-             html: function(selector, val, loadScripts, callback) {
 
-                 // supports css selector/Node/NodeList
 
-                 var els = DOM.query(selector),el = els[0];
 
-                 if (!el) {
 
-                     return
 
-                 }
 
-                 // getter
 
-                 if (val === undefined) {
 
-                     // only gets value on the first of element nodes
 
-                     if (isElementNode(el)) {
 
-                         return el['innerHTML'];
 
-                     } else {
 
-                         return null;
 
-                     }
 
-                 }
 
-                 // setter
 
-                 else {
 
-                     var success = false;
 
-                     val += "";
 
-                     // faster
 
-                     if (! val.match(/<(?:script|style)/i) &&
 
-                         (!lostLeadingWhitespace || !val.match(rleadingWhitespace)) &&
 
-                         !creatorsMap[ (val.match(RE_TAG) || ["",""])[1].toLowerCase() ]) {
 
-                         try {
 
-                             els.each(function(elem) {
 
-                                 if (isElementNode(elem)) {
 
-                                     cleanData(getElementsByTagName(elem, "*"));
 
-                                     elem.innerHTML = val;
 
-                                 }
 
-                             });
 
-                             success = true;
 
-                         } catch(e) {
 
-                             // a <= "<a>"
 
-                             // a.innerHTML='<p>1</p>';
 
-                         }
 
-                     }
 
-                     if (!success) {
 
-                         val = DOM.create(val, 0, el.ownerDocument, false);
 
-                         els.each(function(elem) {
 
-                             if (isElementNode(elem)) {
 
-                                 DOM.empty(elem);
 
-                                 DOM.append(val, elem, loadScripts);
 
-                             }
 
-                         });
 
-                     }
 
-                     callback && callback();
 
-                 }
 
-             },
 
-             /**
 
-              * Remove the set of matched elements from the DOM.
 
-              * 不要使用 innerHTML='' 来清除元素,可能会造成内存泄露,要使用 DOM.remove()
 
-              * @param selector 选择器或元素集合
 
-              * @param {Boolean} keepData 删除元素时是否保留其上的数据,用于离线操作,提高性能
 
-              */
 
-             remove: function(selector, keepData) {
 
-                 DOM.query(selector).each(function(el) {
 
-                     if (!keepData && isElementNode(el)) {
 
-                         // 清楚数据
 
-                         var elChildren = getElementsByTagName(el, "*");
 
-                         cleanData(elChildren);
 
-                         cleanData(el);
 
-                     }
 
-                     if (el.parentNode) {
 
-                         el.parentNode.removeChild(el);
 
-                     }
 
-                 });
 
-             },
 
-             /**
 
-              * clone node across browsers for the first node in selector
 
-              * @param selector 选择器或单个元素
 
-              * @param {Boolean} withDataAndEvent 复制节点是否包括和源节点同样的数据和事件
 
-              * @param {Boolean} deepWithDataAndEvent 复制节点的子孙节点是否包括和源节点子孙节点同样的数据和事件
 
-              * @refer https://developer.mozilla.org/En/DOM/Node.cloneNode
 
-              * @returns 复制后的节点
 
-              */
 
-             clone:function(selector, deep, withDataAndEvent, deepWithDataAndEvent) {
 
-                 var elem = DOM.get(selector);
 
-                 if (!elem) {
 
-                     return null;
 
-                 }
 
-                 // TODO
 
-                 // ie bug :
 
-                 // 1. ie<9 <script>xx</script> => <script></script>
 
-                 // 2. ie will execute external script
 
-                 var clone = elem.cloneNode(deep);
 
-                 if (isElementNode(elem) ||
 
-                     nodeTypeIs(elem, DOM.DOCUMENT_FRAGMENT_NODE)) {
 
-                     // IE copies events bound via attachEvent when using cloneNode.
 
-                     // Calling detachEvent on the clone will also remove the events
 
-                     // from the original. In order to get around this, we use some
 
-                     // proprietary methods to clear the events. Thanks to MooTools
 
-                     // guys for this hotness.
 
-                     if (isElementNode(elem)) {
 
-                         fixAttributes(elem, clone);
 
-                     }
 
-                     if (deep) {
 
-                         processAll(fixAttributes, elem, clone);
 
-                     }
 
-                 }
 
-                 // runtime 获得事件模块
 
-                 if (withDataAndEvent) {
 
-                     cloneWidthDataAndEvent(elem, clone);
 
-                     if (deep && deepWithDataAndEvent) {
 
-                         processAll(cloneWidthDataAndEvent, elem, clone);
 
-                     }
 
-                 }
 
-                 return clone;
 
-             },
 
-             empty:function(selector) {
 
-                 DOM.query(selector).each(function(el) {
 
-                     DOM.remove(el.childNodes);
 
-                 });
 
-             },
 
-             _nl2frag:nl2frag
 
-         });
 
-         function processAll(fn, elem, clone) {
 
-             if (nodeTypeIs(elem, DOM.DOCUMENT_FRAGMENT_NODE)) {
 
-                 var eCs = elem.childNodes,
 
-                     cloneCs = clone.childNodes,
 
-                     fIndex = 0;
 
-                 while (eCs[fIndex]) {
 
-                     if (cloneCs[fIndex]) {
 
-                         processAll(fn, eCs[fIndex], cloneCs[fIndex]);
 
-                     }
 
-                     fIndex++;
 
-                 }
 
-             } else if (isElementNode(elem)) {
 
-                 var elemChildren = getElementsByTagName(elem, "*"),
 
-                     cloneChildren = getElementsByTagName(clone, "*"),
 
-                     cIndex = 0;
 
-                 while (elemChildren[cIndex]) {
 
-                     if (cloneChildren[cIndex]) {
 
-                         fn(elemChildren[cIndex], cloneChildren[cIndex]);
 
-                     }
 
-                     cIndex++;
 
-                 }
 
-             }
 
-         }
 
-         // 克隆除了事件的 data
 
-         function cloneWidthDataAndEvent(src, dest) {
 
-             var Event = S.require('event');
 
-             if (isElementNode(dest) && !DOM.hasData(src)) {
 
-                 return;
 
-             }
 
-             var srcData = DOM.data(src);
 
-             // 浅克隆,data 也放在克隆节点上
 
-             for (var d in srcData) {
 
-                 DOM.data(dest, d, srcData[d]);
 
-             }
 
-             // 事件要特殊点
 
-             if (Event) {
 
-                 // _removeData 不需要?刚克隆出来本来就没
 
-                 Event._removeData(dest);
 
-                 Event._clone(src, dest);
 
-             }
 
-         }
 
-         // wierd ie cloneNode fix from jq
 
-         function fixAttributes(src, dest) {
 
-             // clearAttributes removes the attributes, which we don't want,
 
-             // but also removes the attachEvent events, which we *do* want
 
-             if (dest.clearAttributes) {
 
-                 dest.clearAttributes();
 
-             }
 
-             // mergeAttributes, in contrast, only merges back on the
 
-             // original attributes, not the events
 
-             if (dest.mergeAttributes) {
 
-                 dest.mergeAttributes(src);
 
-             }
 
-             var nodeName = dest.nodeName.toLowerCase(),
 
-                 srcChilds = src.childNodes;
 
-             // IE6-8 fail to clone children inside object elements that use
 
-             // the proprietary classid attribute value (rather than the type
 
-             // attribute) to identify the type of content to display
 
-             if (nodeName === "object" && !dest.childNodes.length) {
 
-                 for (var i = 0; i < srcChilds.length; i++) {
 
-                     dest.appendChild(srcChilds[i].cloneNode(true));
 
-                 }
 
-                 // dest.outerHTML = src.outerHTML;
 
-             } else if (nodeName === "input" && (src.type === "checkbox" || src.type === "radio")) {
 
-                 // IE6-8 fails to persist the checked state of a cloned checkbox
 
-                 // or radio button. Worse, IE6-7 fail to give the cloned element
 
-                 // a checked appearance if the defaultChecked value isn't also set
 
-                 if (src.checked) {
 
-                     dest['defaultChecked'] = dest.checked = src.checked;
 
-                 }
 
-                 // IE6-7 get confused and end up setting the value of a cloned
 
-                 // checkbox/radio button to an empty string instead of "on"
 
-                 if (dest.value !== src.value) {
 
-                     dest.value = src.value;
 
-                 }
 
-                 // IE6-8 fails to return the selected option to the default selected
 
-                 // state when cloning options
 
-             } else if (nodeName === "option") {
 
-                 dest.selected = src.defaultSelected;
 
-                 // IE6-8 fails to set the defaultValue to the correct value when
 
-                 // cloning other types of input fields
 
-             } else if (nodeName === "input" || nodeName === "textarea") {
 
-                 dest.defaultValue = src.defaultValue;
 
-             }
 
-             // Event data gets referenced instead of copied if the expando
 
-             // gets copied too
 
-             // 自定义 data 根据参数特殊处理,expando 只是个用于引用的属性
 
-             dest.removeAttribute(DOM.__EXPANDO);
 
-         }
 
-         // 添加成员到元素中
 
-         function attachProps(elem, props) {
 
-             if (S.isPlainObject(props)) {
 
-                 if (isElementNode(elem)) {
 
-                     DOM.attr(elem, props, true);
 
-                 }
 
-                 // document fragment
 
-                 else if (nodeTypeIs(elem, DOM.DOCUMENT_FRAGMENT_NODE)) {
 
-                     DOM.attr(elem.childNodes, props, true);
 
-                 }
 
-             }
 
-             return elem;
 
-         }
 
-         // 将 nodeList 转换为 fragment
 
-         function nl2frag(nodes, ownerDoc) {
 
-             var ret = null, i, len;
 
-             if (nodes
 
-                 && (nodes.push || nodes.item)
 
-                 && nodes[0]) {
 
-                 ownerDoc = ownerDoc || nodes[0].ownerDocument;
 
-                 ret = ownerDoc.createDocumentFragment();
 
-                 nodes = S.makeArray(nodes);
 
-                 for (i = 0,len = nodes.length; i < len; i++) {
 
-                     ret.appendChild(nodes[i]);
 
-                 }
 
-             }
 
-             else {
 
-                 S.log('Unable to convert ' + nodes + ' to fragment.');
 
-             }
 
-             return ret;
 
-         }
 
-         // only for gecko and ie
 
-         // 2010-10-22: 发现 chrome 也与 gecko 的处理一致了
 
-         //if (ie || UA['gecko'] || UA['webkit']) {
 
-         // 定义 creators, 处理浏览器兼容
 
-         var creators = DOM._creators,
 
-             create = DOM.create,
 
-             TABLE_OPEN = '<table>',
 
-             TABLE_CLOSE = '<' + '/table>',
 
-             RE_TBODY = /(?:\/(?:thead|tfoot|caption|col|colgroup)>)+\s*<tbody/,
 
-             creatorsMap = {
 
-                 option: 'select',
 
-                 optgroup:'select',
 
-                 area:'map',
 
-                 thead:'table',
 
-                 td: 'tr',
 
-                 th:'tr',
 
-                 tr: 'tbody',
 
-                 tbody: 'table',
 
-                 tfoot:'table',
 
-                 caption:'table',
 
-                 colgroup:'table',
 
-                 col: 'colgroup',
 
-                 legend: 'fieldset' // ie 支持,但 gecko 不支持
 
-             };
 
-         for (var p in creatorsMap) {
 
-             (function(tag) {
 
-                 creators[p] = function(html, ownerDoc) {
 
-                     return create('<' + tag + '>' + html + '<' + '/' + tag + '>', null, ownerDoc);
 
-                 }
 
-             })(creatorsMap[p]);
 
-         }
 
-         // IE7- adds TBODY when creating thead/tfoot/caption/col/colgroup elements
 
-         if (ie < 8) {
 
-             creators.tbody = function(html, ownerDoc) {
 
-                 var frag = create(TABLE_OPEN + html + TABLE_CLOSE, null, ownerDoc),
 
-                     tbody = frag.children['tags']('tbody')[0];
 
-                 if (frag.children.length > 1 && tbody && !RE_TBODY.test(html)) {
 
-                     tbody[PARENT_NODE].removeChild(tbody); // strip extraneous tbody
 
-                 }
 
-                 return frag;
 
-             };
 
-         }
 
-         // fix table elements
 
-         S.mix(creators, {
 
-             thead: creators.tbody,
 
-             tfoot: creators.tbody,
 
-             caption: creators.tbody,
 
-             colgroup: creators.tbody
 
-         });
 
-         //}
 
-         return DOM;
 
-     },
 
-     {
 
-         requires:["./base","ua"]
 
-     });
 
- /**
 
-  * 2011-10-13
 
-  * empty , html refactor
 
-  *
 
-  * 2011-08-22
 
-  * clone 实现,参考 jq
 
-  *
 
-  * 2011-08
 
-  *  remove 需要对子孙节点以及自身清除事件以及自定义 data
 
-  *  create 修改,支持 <style></style> ie 下直接创建
 
-  *  TODO: jquery clone ,clean 实现
 
-  *
 
-  * TODO:
 
-  *  - 研究 jQuery 的 buildFragment 和 clean
 
-  *  - 增加 cache, 完善 test cases
 
-  *  - 支持更多 props
 
-  *  - remove 时,是否需要移除事件,以避免内存泄漏?需要详细的测试。
 
-  */
 
- /**
 
-  * @fileOverview   dom-data
 
-  * @author  lifesinger@gmail.com,yiminghe@gmail.com
 
-  */
 
- KISSY.add('dom/data', function (S, DOM, undefined) {
 
-     var win = window,
 
-         EXPANDO = '_ks_data_' + S.now(), // 让每一份 kissy 的 expando 都不同
 
-         dataCache = { }, // 存储 node 节点的 data
 
-         winDataCache = { };    // 避免污染全局
 
-     // The following elements throw uncatchable exceptions if you
 
-     // attempt to add expando properties to them.
 
-     var noData = {
 
-     };
 
-     noData['applet'] = 1;
 
-     noData['object'] = 1;
 
-     noData['embed'] = 1;
 
-     var commonOps = {
 
-         hasData:function (cache, name) {
 
-             if (cache) {
 
-                 if (name !== undefined) {
 
-                     if (name in cache) {
 
-                         return true;
 
-                     }
 
-                 } else if (!S.isEmptyObject(cache)) {
 
-                     return true;
 
-                 }
 
-             }
 
-             return false;
 
-         }
 
-     };
 
-     var objectOps = {
 
-         hasData:function (ob, name) {
 
-             // 只判断当前窗口,iframe 窗口内数据直接放入全局变量
 
-             if (ob == win) {
 
-                 return objectOps.hasData(winDataCache, name);
 
-             }
 
-             // 直接建立在对象内
 
-             var thisCache = ob[EXPANDO];
 
-             return commonOps.hasData(thisCache, name);
 
-         },
 
-         data:function (ob, name, value) {
 
-             if (ob == win) {
 
-                 return objectOps.data(winDataCache, name, value);
 
-             }
 
-             var cache = ob[EXPANDO];
 
-             if (value !== undefined) {
 
-                 cache = ob[EXPANDO] = ob[EXPANDO] || {};
 
-                 cache[name] = value;
 
-             } else {
 
-                 if (name !== undefined) {
 
-                     return cache && cache[name];
 
-                 } else {
 
-                     cache = ob[EXPANDO] = ob[EXPANDO] || {};
 
-                     return cache;
 
-                 }
 
-             }
 
-         },
 
-         removeData:function (ob, name) {
 
-             if (ob == win) {
 
-                 return objectOps.removeData(winDataCache, name);
 
-             }
 
-             var cache = ob[EXPANDO];
 
-             if (name !== undefined) {
 
-                 delete cache[name];
 
-                 if (S.isEmptyObject(cache)) {
 
-                     objectOps.removeData(ob);
 
-                 }
 
-             } else {
 
-                 try {
 
-                     // ob maybe window in iframe
 
-                     // ie will throw error
 
-                     delete ob[EXPANDO];
 
-                 } catch (e) {
 
-                     ob[EXPANDO] = undefined;
 
-                 }
 
-             }
 
-         }
 
-     };
 
-     var domOps = {
 
-         hasData:function (elem, name) {
 
-             var key = elem[EXPANDO];
 
-             if (!key) {
 
-                 return false;
 
-             }
 
-             var thisCache = dataCache[key];
 
-             return commonOps.hasData(thisCache, name);
 
-         },
 
-         data:function (elem, name, value) {
 
-             if (noData[elem.nodeName.toLowerCase()]) {
 
-                 return undefined;
 
-             }
 
-             var key = elem[EXPANDO], cache;
 
-             if (!key) {
 
-                 // 根本不用附加属性
 
-                 if (name !== undefined &&
 
-                     value === undefined) {
 
-                     return undefined;
 
-                 }
 
-                 // 节点上关联键值也可以
 
-                 key = elem[EXPANDO] = S.guid();
 
-             }
 
-             cache = dataCache[key];
 
-             if (value !== undefined) {
 
-                 // 需要新建
 
-                 cache = dataCache[key] = dataCache[key] || {};
 
-                 cache[name] = value;
 
-             } else {
 
-                 if (name !== undefined) {
 
-                     return cache && cache[name];
 
-                 } else {
 
-                     // 需要新建
 
-                     cache = dataCache[key] = dataCache[key] || {};
 
-                     return cache;
 
-                 }
 
-             }
 
-         },
 
-         removeData:function (elem, name) {
 
-             var key = elem[EXPANDO], cache;
 
-             if (!key) {
 
-                 return;
 
-             }
 
-             cache = dataCache[key];
 
-             if (name !== undefined) {
 
-                 delete cache[name];
 
-                 if (S.isEmptyObject(cache)) {
 
-                     domOps.removeData(elem);
 
-                 }
 
-             } else {
 
-                 delete dataCache[key];
 
-                 try {
 
-                     delete elem[EXPANDO];
 
-                 } catch (e) {
 
-                     elem[EXPANDO] = undefined;
 
-                     //S.log("delete expando error : ");
 
-                     //S.log(e);
 
-                 }
 
-                 if (elem.removeAttribute) {
 
-                     elem.removeAttribute(EXPANDO);
 
-                 }
 
-             }
 
-         }
 
-     };
 
-     S.mix(DOM,
 
-         /**
 
-          * @lends DOM
 
-          */
 
-         {
 
-             __EXPANDO:EXPANDO,
 
-             /**
 
-              * whether any node has data
 
-              * @param {HTMLElement[]|String} selector 选择器或节点数组
 
-              * @param {String} name 数据键名
 
-              * @returns {boolean} 节点是否有关联数据键名的值
 
-              */
 
-             hasData:function (selector, name) {
 
-                 var ret = false, elems = DOM.query(selector);
 
-                 for (var i = 0; i < elems.length; i++) {
 
-                     var elem = elems[i];
 
-                     if (checkIsNode(elem)) {
 
-                         ret = domOps.hasData(elem, name);
 
-                     } else {
 
-                         ret = objectOps.hasData(elem, name);
 
-                     }
 
-                     if (ret) {
 
-                         return ret;
 
-                     }
 
-                 }
 
-                 return ret;
 
-             },
 
-             /**
 
-              * Store arbitrary data associated with the matched elements.
 
-              * @param {HTMLElement[]|String} selector 选择器或节点数组
 
-              * @param {String} [name] 数据键名
 
-              * @param {String} [data] 数据键值
 
-              * @returns 当不设置 data,设置 name 那么返回: 节点是否有关联数据键名的值
 
-              *          当不设置 data, name 那么返回: 节点的存储空间对象
 
-              *          当设置 data, name 那么进行设置操作,返回 undefined
 
-              */
 
-             data:function (selector, name, data) {
 
-                 // suports hash
 
-                 if (S.isPlainObject(name)) {
 
-                     for (var k in name) {
 
-                         DOM.data(selector, k, name[k]);
 
-                     }
 
-                     return undefined;
 
-                 }
 
-                 // getter
 
-                 if (data === undefined) {
 
-                     var elem = DOM.get(selector);
 
-                     if (checkIsNode(elem)) {
 
-                         return domOps.data(elem, name, data);
 
-                     } else if (elem) {
 
-                         return objectOps.data(elem, name, data);
 
-                     }
 
-                 }
 
-                 // setter
 
-                 else {
 
-                     DOM.query(selector).each(function (elem) {
 
-                         if (checkIsNode(elem)) {
 
-                             domOps.data(elem, name, data);
 
-                         } else {
 
-                             objectOps.data(elem, name, data);
 
-                         }
 
-                     });
 
-                 }
 
-                 return undefined;
 
-             },
 
-             /**
 
-              * Remove a previously-stored piece of data.
 
-              * @param {HTMLElement[]|String} selector 选择器或节点数组
 
-              * @param {String} [name] 数据键名,不设置时删除关联节点的所有键值对
 
-              */
 
-             removeData:function (selector, name) {
 
-                 DOM.query(selector).each(function (elem) {
 
-                     if (checkIsNode(elem)) {
 
-                         domOps.removeData(elem, name);
 
-                     } else {
 
-                         objectOps.removeData(elem, name);
 
-                     }
 
-                 });
 
-             }
 
-         });
 
-     function checkIsNode(elem) {
 
-         // note : 普通对象不要定义 nodeType 这种特殊属性!
 
-         return elem && elem.nodeType;
 
-     }
 
-     return DOM;
 
- }, {
 
-     requires:["./base"]
 
- });
 
- /**
 
-  * 承玉:2011-05-31
 
-  *  - 分层 ,节点和普通对象分开处理
 
-  **/
 
- /**
 
-  * @module  dom-insertion
 
-  * @author  yiminghe@gmail.com,lifesinger@gmail.com
 
-  */
 
- KISSY.add('dom/insertion', function(S, UA, DOM) {
 
-     var PARENT_NODE = 'parentNode',
 
-         rformEls = /^(?:button|input|object|select|textarea)$/i,
 
-         nodeName = DOM._nodeName,
 
-         makeArray = S.makeArray,
 
-         _isElementNode = DOM._isElementNode,
 
-         NEXT_SIBLING = 'nextSibling';
 
-     /**
 
-      ie 6,7 lose checked status when append to dom
 
-      var c=S.all("<input />");
 
-      c.attr("type","radio");
 
-      c.attr("checked",true);
 
-      S.all("#t").append(c);
 
-      alert(c[0].checked);
 
-      */
 
-     function fixChecked(ret) {
 
-         for (var i = 0; i < ret.length; i++) {
 
-             var el = ret[i];
 
-             if (el.nodeType == DOM.DOCUMENT_FRAGMENT_NODE) {
 
-                 fixChecked(el.childNodes);
 
-             } else if (nodeName(el, "input")) {
 
-                 fixCheckedInternal(el);
 
-             } else if (_isElementNode(el)) {
 
-                 var cs = el.getElementsByTagName("input");
 
-                 for (var j = 0; j < cs.length; j++) {
 
-                     fixChecked(cs[j]);
 
-                 }
 
-             }
 
-         }
 
-     }
 
-     function fixCheckedInternal(el) {
 
-         if (el.type === "checkbox" || el.type === "radio") {
 
-             // after insert , in ie6/7 checked is decided by defaultChecked !
 
-             el.defaultChecked = el.checked;
 
-         }
 
-     }
 
-     var rscriptType = /\/(java|ecma)script/i;
 
-     function isJs(el) {
 
-         return !el.type || rscriptType.test(el.type);
 
-     }
 
-     // extract script nodes and execute alone later
 
-     function filterScripts(nodes, scripts) {
 
-         var ret = [],i,el,nodeName;
 
-         for (i = 0; nodes[i]; i++) {
 
-             el = nodes[i];
 
-             nodeName = el.nodeName.toLowerCase();
 
-             if (el.nodeType == DOM.DOCUMENT_FRAGMENT_NODE) {
 
-                 ret.push.apply(ret, filterScripts(makeArray(el.childNodes), scripts));
 
-             } else if (nodeName === "script" && isJs(el)) {
 
-                 // remove script to make sure ie9 does not invoke when append
 
-                 if (el.parentNode) {
 
-                     el.parentNode.removeChild(el)
 
-                 }
 
-                 if (scripts) {
 
-                     scripts.push(el);
 
-                 }
 
-             } else {
 
-                 if (_isElementNode(el) &&
 
-                     // ie checkbox getElementsByTagName 后造成 checked 丢失
 
-                     !rformEls.test(nodeName)) {
 
-                     var tmp = [],
 
-                         s,
 
-                         j,
 
-                         ss = el.getElementsByTagName("script");
 
-                     for (j = 0; j < ss.length; j++) {
 
-                         s = ss[j];
 
-                         if (isJs(s)) {
 
-                             tmp.push(s);
 
-                         }
 
-                     }
 
-                     nodes.splice.apply(nodes, [i + 1,0].concat(tmp));
 
-                 }
 
-                 ret.push(el);
 
-             }
 
-         }
 
-         return ret;
 
-     }
 
-     // execute script
 
-     function evalScript(el) {
 
-         if (el.src) {
 
-             S.getScript(el.src);
 
-         } else {
 
-             var code = S.trim(el.text || el.textContent || el.innerHTML || "");
 
-             if (code) {
 
-                 S.globalEval(code);
 
-             }
 
-         }
 
-     }
 
-     // fragment is easier than nodelist
 
-     function insertion(newNodes, refNodes, fn, scripts) {
 
-         newNodes = DOM.query(newNodes);
 
-         if (scripts) {
 
-             scripts = [];
 
-         }
 
-         // filter script nodes ,process script separately if needed
 
-         newNodes = filterScripts(newNodes, scripts);
 
-         // Resets defaultChecked for any radios and checkboxes
 
-         // about to be appended to the DOM in IE 6/7
 
-         if (UA['ie'] < 8) {
 
-             fixChecked(newNodes);
 
-         }
 
-         refNodes = DOM.query(refNodes);
 
-         var newNodesLength = newNodes.length,
 
-             refNodesLength = refNodes.length;
 
-         if ((!newNodesLength &&
 
-             (!scripts || !scripts.length)) ||
 
-             !refNodesLength) {
 
-             return;
 
-         }
 
-         // fragment 插入速度快点
 
-         var newNode = DOM._nl2frag(newNodes),
 
-             clonedNode;
 
-         //fragment 一旦插入里面就空了,先复制下
 
-         if (refNodesLength > 1) {
 
-             clonedNode = DOM.clone(newNode, true);
 
-         }
 
-         for (var i = 0; i < refNodesLength; i++) {
 
-             var refNode = refNodes[i];
 
-             if (newNodesLength) {
 
-                 //refNodes 超过一个,clone
 
-                 var node = i > 0 ? DOM.clone(clonedNode, true) : newNode;
 
-                 fn(node, refNode);
 
-             }
 
-             if (scripts && scripts.length) {
 
-                 S.each(scripts, evalScript);
 
-             }
 
-         }
 
-     }
 
-     // loadScripts default to false to prevent xss
 
-     S.mix(DOM, {
 
-         /**
 
-          * Inserts the new node as the previous sibling of the reference node.
 
-          */
 
-         insertBefore: function(newNodes, refNodes, loadScripts) {
 
-             insertion(newNodes, refNodes, function(newNode, refNode) {
 
-                 if (refNode[PARENT_NODE]) {
 
-                     refNode[PARENT_NODE].insertBefore(newNode, refNode);
 
-                 }
 
-             }, loadScripts);
 
-         },
 
-         /**
 
-          * Inserts the new node as the next sibling of the reference node.
 
-          */
 
-         insertAfter: function(newNodes, refNodes, loadScripts) {
 
-             insertion(newNodes, refNodes, function(newNode, refNode) {
 
-                 if (refNode[PARENT_NODE]) {
 
-                     refNode[PARENT_NODE].insertBefore(newNode, refNode[NEXT_SIBLING]);
 
-                 }
 
-             }, loadScripts);
 
-         },
 
-         /**
 
-          * Inserts the new node as the last child.
 
-          */
 
-         appendTo: function(newNodes, parents, loadScripts) {
 
-             insertion(newNodes, parents, function(newNode, parent) {
 
-                 parent.appendChild(newNode);
 
-             }, loadScripts);
 
-         },
 
-         /**
 
-          * Inserts the new node as the first child.
 
-          */
 
-         prependTo:function(newNodes, parents, loadScripts) {
 
-             insertion(newNodes, parents, function(newNode, parent) {
 
-                 parent.insertBefore(newNode, parent.firstChild);
 
-             }, loadScripts);
 
-         }
 
-     });
 
-     var alias = {
 
-         "prepend":"prependTo",
 
-         "append":"appendTo",
 
-         "before":"insertBefore",
 
-         "after":"insertAfter"
 
-     };
 
-     for (var a in alias) {
 
-         DOM[a] = DOM[alias[a]];
 
-     }
 
-     return DOM;
 
- }, {
 
-     requires:["ua","./create"]
 
- });
 
- /**
 
-  * 2011-05-25
 
-  *  - 承玉:参考 jquery 处理多对多的情形 :http://api.jquery.com/append/
 
-  *      DOM.append(".multi1",".multi2");
 
-  *
 
-  */
 
- /**
 
-  * @module  dom-offset
 
-  * @author  lifesinger@gmail.com,yiminghe@gmail.com
 
-  */
 
- KISSY.add('dom/offset', function(S, DOM, UA, undefined) {
 
-     var win = window,
 
-         doc = document,
 
-         isIE = UA['ie'],
 
-         docElem = doc.documentElement,
 
-         isElementNode = DOM._isElementNode,
 
-         nodeTypeIs = DOM._nodeTypeIs,
 
-         getWin = DOM._getWin,
 
-         CSS1Compat = "CSS1Compat",
 
-         compatMode = "compatMode",
 
-         isStrict = doc[compatMode] === CSS1Compat,
 
-         MAX = Math.max,
 
-         PARSEINT = parseInt,
 
-         POSITION = 'position',
 
-         RELATIVE = 'relative',
 
-         DOCUMENT = 'document',
 
-         BODY = 'body',
 
-         DOC_ELEMENT = 'documentElement',
 
-         OWNER_DOCUMENT = 'ownerDocument',
 
-         VIEWPORT = 'viewport',
 
-         SCROLL = 'scroll',
 
-         CLIENT = 'client',
 
-         LEFT = 'left',
 
-         TOP = 'top',
 
-         isNumber = S.isNumber,
 
-         SCROLL_LEFT = SCROLL + 'Left',
 
-         SCROLL_TOP = SCROLL + 'Top',
 
-         GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect';
 
- //    ownerDocument 的判断不保证 elem 没有游离在 document 之外(比如 fragment)
 
- //    function inDocument(elem) {
 
- //        if (!elem) {
 
- //            return 0;
 
- //        }
 
- //        var doc = elem.ownerDocument;
 
- //        if (!doc) {
 
- //            return 0;
 
- //        }
 
- //        var html = doc.documentElement;
 
- //        if (html === elem) {
 
- //            return true;
 
- //        }
 
- //        else if (DOM.__contains(html, elem)) {
 
- //            return true;
 
- //        }
 
- //        return false;
 
- //    }
 
-     S.mix(DOM, {
 
-         /**
 
-          * Gets the current coordinates of the element, relative to the document.
 
-          * @param relativeWin The window to measure relative to. If relativeWin
 
-          *     is not in the ancestor frame chain of the element, we measure relative to
 
-          *     the top-most window.
 
-          */
 
-         offset: function(selector, val, relativeWin) {
 
-             // getter
 
-             if (val === undefined) {
 
-                 var elem = DOM.get(selector),ret;
 
-                 if (elem) {
 
-                     ret = getOffset(elem, relativeWin);
 
-                 }
 
-                 return ret;
 
-             }
 
-             // setter
 
-             DOM.query(selector).each(function(elem) {
 
-                 setOffset(elem, val);
 
-             });
 
-         },
 
-         /**
 
-          * Makes elem visible in the container
 
-          * @param elem
 
-          * @param container
 
-          * @param top
 
-          * @param hscroll
 
-          * @param {Boolean} auto whether adjust element automatically
 
-          *                       (it only scrollIntoView when element is out of view)
 
-          * @refer http://www.w3.org/TR/2009/WD-html5-20090423/editing.html#scrollIntoView
 
-          *        http://www.sencha.com/deploy/dev/docs/source/Element.scroll-more.html#scrollIntoView
 
-          *        http://yiminghe.javaeye.com/blog/390732
 
-          */
 
-         scrollIntoView: function(elem, container, top, hscroll, auto) {
 
-             if (!(elem = DOM.get(elem))) {
 
-                 return;
 
-             }
 
-             if (container) {
 
-                 container = DOM.get(container);
 
-             }
 
-             if (!container) {
 
-                 container = elem.ownerDocument;
 
-             }
 
-             if (auto !== true) {
 
-                 hscroll = hscroll === undefined ? true : !!hscroll;
 
-                 top = top === undefined ? true : !!top;
 
-             }
 
-             // document 归一化到 window
 
-             if (nodeTypeIs(container, DOM.DOCUMENT_NODE)) {
 
-                 container = getWin(container);
 
-             }
 
-             var isWin = !!getWin(container),
 
-                 elemOffset = DOM.offset(elem),
 
-                 eh = DOM.outerHeight(elem),
 
-                 ew = DOM.outerWidth(elem),
 
-                 containerOffset,
 
-                 ch,
 
-                 cw,
 
-                 containerScroll,
 
-                 diffTop,
 
-                 diffBottom,
 
-                 win,
 
-                 winScroll,
 
-                 ww,
 
-                 wh;
 
-             if (isWin) {
 
-                 win = container;
 
-                 wh = DOM.height(win);
 
-                 ww = DOM.width(win);
 
-                 winScroll = {
 
-                     left:DOM.scrollLeft(win),
 
-                     top:DOM.scrollTop(win)
 
-                 };
 
-                 // elem 相对 container 可视视窗的距离
 
-                 diffTop = {
 
-                     left: elemOffset[LEFT] - winScroll[LEFT],
 
-                     top: elemOffset[TOP] - winScroll[TOP]
 
-                 };
 
-                 diffBottom = {
 
-                     left:  elemOffset[LEFT] + ew - (winScroll[LEFT] + ww),
 
-                     top:elemOffset[TOP] + eh - (winScroll[TOP] + wh)
 
-                 };
 
-                 containerScroll = winScroll;
 
-             }
 
-             else {
 
-                 containerOffset = DOM.offset(container);
 
-                 ch = container.clientHeight;
 
-                 cw = container.clientWidth;
 
-                 containerScroll = {
 
-                     left:DOM.scrollLeft(container),
 
-                     top:DOM.scrollTop(container)
 
-                 };
 
-                 // elem 相对 container 可视视窗的距离
 
-                 // 注意边框 , offset 是边框到根节点
 
-                 diffTop = {
 
-                     left: elemOffset[LEFT] - containerOffset[LEFT] -
 
-                         (PARSEINT(DOM.css(container, 'borderLeftWidth')) || 0),
 
-                     top: elemOffset[TOP] - containerOffset[TOP] -
 
-                         (PARSEINT(DOM.css(container, 'borderTopWidth')) || 0)
 
-                 };
 
-                 diffBottom = {
 
-                     left:  elemOffset[LEFT] + ew -
 
-                         (containerOffset[LEFT] + cw +
 
-                             (PARSEINT(DOM.css(container, 'borderRightWidth')) || 0)) ,
 
-                     top:elemOffset[TOP] + eh -
 
-                         (containerOffset[TOP] + ch +
 
-                             (PARSEINT(DOM.css(container, 'borderBottomWidth')) || 0))
 
-                 };
 
-             }
 
-             if (diffTop.top < 0 || diffBottom.top > 0) {
 
-                 // 强制向上
 
-                 if (top === true) {
 
-                     DOM.scrollTop(container, containerScroll.top + diffTop.top);
 
-                 } else if (top === false) {
 
-                     DOM.scrollTop(container, containerScroll.top + diffBottom.top);
 
-                 } else {
 
-                     // 自动调整
 
-                     if (diffTop.top < 0) {
 
-                         DOM.scrollTop(container, containerScroll.top + diffTop.top);
 
-                     } else {
 
-                         DOM.scrollTop(container, containerScroll.top + diffBottom.top);
 
-                     }
 
-                 }
 
-             }
 
-             if (hscroll) {
 
-                 if (diffTop.left < 0 || diffBottom.left > 0) {
 
-                     // 强制向上
 
-                     if (top === true) {
 
-                         DOM.scrollLeft(container, containerScroll.left + diffTop.left);
 
-                     } else if (top === false) {
 
-                         DOM.scrollLeft(container, containerScroll.left + diffBottom.left);
 
-                     } else {
 
-                         // 自动调整
 
-                         if (diffTop.left < 0) {
 
-                             DOM.scrollLeft(container, containerScroll.left + diffTop.left);
 
-                         } else {
 
-                             DOM.scrollLeft(container, containerScroll.left + diffBottom.left);
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-         },
 
-         /**
 
-          * for idea autocomplete
 
-          */
 
-         docWidth:0,
 
-         docHeight:0,
 
-         viewportHeight:0,
 
-         viewportWidth:0
 
-     });
 
-     // http://old.jr.pl/www.quirksmode.org/viewport/compatibility.html
 
-     // http://www.quirksmode.org/dom/w3c_cssom.html
 
-     // add ScrollLeft/ScrollTop getter/setter methods
 
-     S.each(['Left', 'Top'], function(name, i) {
 
-         var method = SCROLL + name;
 
-         DOM[method] = function(elem, v) {
 
-             if (isNumber(elem)) {
 
-                 return arguments.callee(win, elem);
 
-             }
 
-             elem = DOM.get(elem);
 
-             var ret,
 
-                 w = getWin(elem),
 
-                 d;
 
-             if (w) {
 
-                 if (v !== undefined) {
 
-                     v = parseFloat(v);
 
-                     // 注意多 windw 情况,不能简单取 win
 
-                     var left = name == "Left" ? v : DOM.scrollLeft(w),
 
-                         top = name == "Top" ? v : DOM.scrollTop(w);
 
-                     w['scrollTo'](left, top);
 
-                 } else {
 
-                     //标准
 
-                     //chrome == body.scrollTop
 
-                     //firefox/ie9 == documentElement.scrollTop
 
-                     ret = w[ 'page' + (i ? 'Y' : 'X') + 'Offset'];
 
-                     if (!isNumber(ret)) {
 
-                         d = w[DOCUMENT];
 
-                         //ie6,7,8 standard mode
 
-                         ret = d[DOC_ELEMENT][method];
 
-                         if (!isNumber(ret)) {
 
-                             //quirks mode
 
-                             ret = d[BODY][method];
 
-                         }
 
-                     }
 
-                 }
 
-             } else if (isElementNode(elem)) {
 
-                 if (v !== undefined) {
 
-                     elem[method] = parseFloat(v)
 
-                 } else {
 
-                     ret = elem[method];
 
-                 }
 
-             }
 
-             return ret;
 
-         }
 
-     });
 
-     // add docWidth/Height, viewportWidth/Height getter methods
 
-     S.each(['Width', 'Height'], function(name) {
 
-         DOM['doc' + name] = function(refWin) {
 
-             refWin = DOM.get(refWin);
 
-             var w = getWin(refWin),
 
-                 d = w[DOCUMENT];
 
-             return MAX(
 
-                 //firefox chrome documentElement.scrollHeight< body.scrollHeight
 
-                 //ie standard mode : documentElement.scrollHeight> body.scrollHeight
 
-                 d[DOC_ELEMENT][SCROLL + name],
 
-                 //quirks : documentElement.scrollHeight 最大等于可视窗口多一点?
 
-                 d[BODY][SCROLL + name],
 
-                 DOM[VIEWPORT + name](d));
 
-         };
 
-         DOM[VIEWPORT + name] = function(refWin) {
 
-             refWin = DOM.get(refWin);
 
-             var prop = CLIENT + name,
 
-                 win = getWin(refWin),
 
-                 doc = win[DOCUMENT],
 
-                 body = doc[BODY],
 
-                 documentElement = doc[DOC_ELEMENT],
 
-                 documentElementProp = documentElement[prop];
 
-             // 标准模式取 documentElement
 
-             // backcompat 取 body
 
-             return doc[compatMode] === CSS1Compat
 
-                 && documentElementProp ||
 
-                 body && body[ prop ] || documentElementProp;
 
- //            return (prop in w) ?
 
- //                // 标准 = documentElement.clientHeight
 
- //                w[prop] :
 
- //                // ie 标准 documentElement.clientHeight , 在 documentElement.clientHeight 上滚动?
 
- //                // ie quirks body.clientHeight: 在 body 上?
 
- //                (isStrict ? d[DOC_ELEMENT][CLIENT + name] : d[BODY][CLIENT + name]);
 
-         }
 
-     });
 
-     function getClientPosition(elem) {
 
-         var box, x = 0, y = 0,
 
-             body = doc.body,
 
-             w = getWin(elem[OWNER_DOCUMENT]);
 
-         // 根据 GBS 最新数据,A-Grade Browsers 都已支持 getBoundingClientRect 方法,不用再考虑传统的实现方式
 
-         if (elem[GET_BOUNDING_CLIENT_RECT]) {
 
-             box = elem[GET_BOUNDING_CLIENT_RECT]();
 
-             // 注:jQuery 还考虑减去 docElem.clientLeft/clientTop
 
-             // 但测试发现,这样反而会导致当 html 和 body 有边距/边框样式时,获取的值不正确
 
-             // 此外,ie6 会忽略 html 的 margin 值,幸运地是没有谁会去设置 html 的 margin
 
-             x = box[LEFT];
 
-             y = box[TOP];
 
-             // ie 下应该减去窗口的边框吧,毕竟默认 absolute 都是相对窗口定位的
 
-             // 窗口边框标准是设 documentElement ,quirks 时设置 body
 
-             // 最好禁止在 body 和 html 上边框 ,但 ie < 9 html 默认有 2px ,减去
 
-             // 但是非 ie 不可能设置窗口边框,body html 也不是窗口 ,ie 可以通过 html,body 设置
 
-             // 标准 ie 下 docElem.clientTop 就是 border-top
 
-             // ie7 html 即窗口边框改变不了。永远为 2
 
-             // 但标准 firefox/chrome/ie9 下 docElem.clientTop 是窗口边框,即使设了 border-top 也为 0
 
-             var clientTop = isIE && doc['documentMode'] != 9
 
-                 && (isStrict ? docElem.clientTop : body.clientTop)
 
-                 || 0,
 
-                 clientLeft = isIE && doc['documentMode'] != 9
 
-                     && (isStrict ? docElem.clientLeft : body.clientLeft)
 
-                     || 0;
 
-             if (1 > 2) {
 
-             }
 
-             x -= clientLeft;
 
-             y -= clientTop;
 
-             // iphone/ipad/itouch 下的 Safari 获取 getBoundingClientRect 时,已经加入 scrollTop
 
-             if (UA.mobile == 'apple') {
 
-                 x -= DOM[SCROLL_LEFT](w);
 
-                 y -= DOM[SCROLL_TOP](w);
 
-             }
 
-         }
 
-         return { left: x, top: y };
 
-     }
 
-     function getPageOffset(el) {
 
-         var pos = getClientPosition(el);
 
-         var w = getWin(el[OWNER_DOCUMENT]);
 
-         pos.left += DOM[SCROLL_LEFT](w);
 
-         pos.top += DOM[SCROLL_TOP](w);
 
-         return pos;
 
-     }
 
-     // 获取 elem 相对 elem.ownerDocument 的坐标
 
-     function getOffset(el, relativeWin) {
 
-         var position = {left:0,top:0};
 
-         // Iterate up the ancestor frame chain, keeping track of the current window
 
-         // and the current element in that window.
 
-         var currentWin = getWin(el[OWNER_DOCUMENT]);
 
-         var currentEl = el;
 
-         relativeWin = relativeWin || currentWin;
 
-         do {
 
-             // if we're at the top window, we want to get the page offset.
 
-             // if we're at an inner frame, we only want to get the window position
 
-             // so that we can determine the actual page offset in the context of
 
-             // the outer window.
 
-             var offset = currentWin == relativeWin ?
 
-                 getPageOffset(currentEl) :
 
-                 getClientPosition(currentEl);
 
-             position.left += offset.left;
 
-             position.top += offset.top;
 
-         } while (currentWin && currentWin != relativeWin &&
 
-             (currentEl = currentWin['frameElement']) &&
 
-             (currentWin = currentWin.parent));
 
-         return position;
 
-     }
 
-     // 设置 elem 相对 elem.ownerDocument 的坐标
 
-     function setOffset(elem, offset) {
 
-         // set position first, in-case top/left are set even on static elem
 
-         if (DOM.css(elem, POSITION) === 'static') {
 
-             elem.style[POSITION] = RELATIVE;
 
-         }
 
-         var old = getOffset(elem), ret = { }, current, key;
 
-         for (key in offset) {
 
-             current = PARSEINT(DOM.css(elem, key), 10) || 0;
 
-             ret[key] = current + offset[key] - old[key];
 
-         }
 
-         DOM.css(elem, ret);
 
-     }
 
-     return DOM;
 
- }, {
 
-     requires:["./base","ua"]
 
- });
 
- /**
 
-  * 2011-05-24
 
-  *  - 承玉:
 
-  *  - 调整 docWidth , docHeight ,
 
-  *      viewportHeight , viewportWidth ,scrollLeft,scrollTop 参数,
 
-  *      便于放置到 Node 中去,可以完全摆脱 DOM,完全使用 Node
 
-  *
 
-  *
 
-  *
 
-  * TODO:
 
-  *  - 考虑是否实现 jQuery 的 position, offsetParent 等功能
 
-  *  - 更详细的测试用例(比如:测试 position 为 fixed 的情况)
 
-  */
 
- /**
 
-  * @module  dom
 
-  * @author  yiminghe@gmail.com,lifesinger@gmail.com
 
-  */
 
- KISSY.add('dom/style', function(S, DOM, UA, undefined) {
 
-     var doc = document,
 
-         docElem = doc.documentElement,
 
-         isIE = UA['ie'],
 
-         STYLE = 'style',
 
-         FLOAT = 'float',
 
-         CSS_FLOAT = 'cssFloat',
 
-         STYLE_FLOAT = 'styleFloat',
 
-         WIDTH = 'width',
 
-         HEIGHT = 'height',
 
-         AUTO = 'auto',
 
-         DISPLAY = 'display',
 
-         OLD_DISPLAY = DISPLAY + S.now(),
 
-         NONE = 'none',
 
-         PARSEINT = parseInt,
 
-         RE_NUMPX = /^-?\d+(?:px)?$/i,
 
-         cssNumber = {
 
-             "fillOpacity": 1,
 
-             "fontWeight": 1,
 
-             "lineHeight": 1,
 
-             "opacity": 1,
 
-             "orphans": 1,
 
-             "widows": 1,
 
-             "zIndex": 1,
 
-             "zoom": 1
 
-         },
 
-         RE_DASH = /-([a-z])/ig,
 
-         CAMELCASE_FN = function(all, letter) {
 
-             return letter.toUpperCase();
 
-         },
 
-         // 考虑 ie9 ...
 
-         rupper = /([A-Z]|^ms)/g,
 
-         EMPTY = '',
 
-         DEFAULT_UNIT = 'px',
 
-         CUSTOM_STYLES = {},
 
-         cssProps = {},
 
-         defaultDisplay = {};
 
-     // normalize reserved word float alternatives ("cssFloat" or "styleFloat")
 
-     if (docElem[STYLE][CSS_FLOAT] !== undefined) {
 
-         cssProps[FLOAT] = CSS_FLOAT;
 
-     }
 
-     else if (docElem[STYLE][STYLE_FLOAT] !== undefined) {
 
-         cssProps[FLOAT] = STYLE_FLOAT;
 
-     }
 
-     function camelCase(name) {
 
-         return name.replace(RE_DASH, CAMELCASE_FN);
 
-     }
 
-     var defaultDisplayDetectIframe,
 
-         defaultDisplayDetectIframeDoc;
 
-     // modified from jquery : bullet-proof method of getting default display
 
-     // fix domain problem in ie>6 , ie6 still access denied
 
-     function getDefaultDisplay(tagName) {
 
-         var body,
 
-             elem;
 
-         if (!defaultDisplay[ tagName ]) {
 
-             body = doc.body || doc.documentElement;
 
-             elem = doc.createElement(tagName);
 
-             DOM.prepend(elem, body);
 
-             var oldDisplay = DOM.css(elem, "display");
 
-             body.removeChild(elem);
 
-             // If the simple way fails,
 
-             // get element's real default display by attaching it to a temp iframe
 
-             if (oldDisplay === "none" || oldDisplay === "") {
 
-                 // No iframe to use yet, so create it
 
-                 if (!defaultDisplayDetectIframe) {
 
-                     defaultDisplayDetectIframe = doc.createElement("iframe");
 
-                     defaultDisplayDetectIframe.frameBorder =
 
-                         defaultDisplayDetectIframe.width =
 
-                             defaultDisplayDetectIframe.height = 0;
 
-                     DOM.prepend(defaultDisplayDetectIframe, body);
 
-                     var iframeSrc;
 
-                     if (iframeSrc = DOM._genEmptyIframeSrc()) {
 
-                         defaultDisplayDetectIframe.src = iframeSrc;
 
-                     }
 
-                 } else {
 
-                     DOM.prepend(defaultDisplayDetectIframe, body);
 
-                 }
 
-                 // Create a cacheable copy of the iframe document on first call.
 
-                 // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
 
-                 // document to it; WebKit & Firefox won't allow reusing the iframe document.
 
-                 if (!defaultDisplayDetectIframeDoc || !defaultDisplayDetectIframe.createElement) {
 
-                     try {
 
-                         defaultDisplayDetectIframeDoc = defaultDisplayDetectIframe.contentWindow.document;
 
-                         defaultDisplayDetectIframeDoc.write(( doc.compatMode === "CSS1Compat" ? "<!doctype html>" : "" )
 
-                             + "<html><head>" +
 
-                             (UA['ie'] && DOM._isCustomDomain() ?
 
-                                 "<script>document.domain = '" +
 
-                                     doc.domain
 
-                                     + "';</script>" : "")
 
-                             +
 
-                             "</head><body>");
 
-                         defaultDisplayDetectIframeDoc.close();
 
-                     } catch(e) {
 
-                         // ie6 need a breath , such as alert(8) or setTimeout;
 
-                         // 同时需要同步,所以无解,勉强返回
 
-                         return "block";
 
-                     }
 
-                 }
 
-                 elem = defaultDisplayDetectIframeDoc.createElement(tagName);
 
-                 defaultDisplayDetectIframeDoc.body.appendChild(elem);
 
-                 oldDisplay = DOM.css(elem, "display");
 
-                 body.removeChild(defaultDisplayDetectIframe);
 
-             }
 
-             // Store the correct default display
 
-             defaultDisplay[ tagName ] = oldDisplay;
 
-         }
 
-         return defaultDisplay[ tagName ];
 
-     }
 
-     S.mix(DOM, {
 
-         _camelCase:camelCase,
 
-         _cssNumber:cssNumber,
 
-         _CUSTOM_STYLES: CUSTOM_STYLES,
 
-         _cssProps:cssProps,
 
-         _getComputedStyle: function(elem, name) {
 
-             var val = "",
 
-                 computedStyle = {},
 
-                 d = elem.ownerDocument;
 
-             name = name.replace(rupper, "-$1").toLowerCase();
 
-             // https://github.com/kissyteam/kissy/issues/61
 
-             if (computedStyle = d.defaultView.getComputedStyle(elem, null)) {
 
-                 val = computedStyle.getPropertyValue(name) || computedStyle[name];
 
-             }
 
-             // 还没有加入到 document,就取行内
 
-             if (val == "" && !DOM.__contains(d.documentElement, elem)) {
 
-                 name = cssProps[name] || name;
 
-                 val = elem[STYLE][name];
 
-             }
 
-             return val;
 
-         },
 
-         /**
 
-          *  Get and set the style property on a DOM Node
 
-          */
 
-         style:function(selector, name, val) {
 
-             // suports hash
 
-             if (S.isPlainObject(name)) {
 
-                 for (var k in name) {
 
-                     DOM.style(selector, k, name[k]);
 
-                 }
 
-                 return;
 
-             }
 
-             if (val === undefined) {
 
-                 var elem = DOM.get(selector),ret = '';
 
-                 if (elem) {
 
-                     ret = style(elem, name, val);
 
-                 }
 
-                 return ret;
 
-             } else {
 
-                 DOM.query(selector).each(function(elem) {
 
-                     style(elem, name, val);
 
-                 });
 
-             }
 
-         },
 
-         /**
 
-          * (Gets computed style) or (sets styles) on the matches elements.
 
-          */
 
-         css: function(selector, name, val) {
 
-             // suports hash
 
-             if (S.isPlainObject(name)) {
 
-                 for (var k in name) {
 
-                     DOM.css(selector, k, name[k]);
 
-                 }
 
-                 return;
 
-             }
 
-             name = camelCase(name);
 
-             var hook = CUSTOM_STYLES[name];
 
-             // getter
 
-             if (val === undefined) {
 
-                 // supports css selector/Node/NodeList
 
-                 var elem = DOM.get(selector), ret = '';
 
-                 if (elem) {
 
-                     // If a hook was provided get the computed value from there
 
-                     if (hook && "get" in hook && (ret = hook.get(elem, true)) !== undefined) {
 
-                     } else {
 
-                         ret = DOM._getComputedStyle(elem, name);
 
-                     }
 
-                 }
 
-                 return ret === undefined ? '' : ret;
 
-             }
 
-             // setter
 
-             else {
 
-                 DOM.style(selector, name, val);
 
-             }
 
-         },
 
-         /**
 
-          * Show the matched elements.
 
-          */
 
-         show: function(selector) {
 
-             DOM.query(selector).each(function(elem) {
 
-                 elem[STYLE][DISPLAY] = DOM.data(elem, OLD_DISPLAY) || EMPTY;
 
-                 // 可能元素还处于隐藏状态,比如 css 里设置了 display: none
 
-                 if (DOM.css(elem, DISPLAY) === NONE) {
 
-                     var tagName = elem.tagName.toLowerCase(),
 
-                         old = getDefaultDisplay(tagName);
 
-                     DOM.data(elem, OLD_DISPLAY, old);
 
-                     elem[STYLE][DISPLAY] = old;
 
-                 }
 
-             });
 
-         },
 
-         /**
 
-          * Hide the matched elements.
 
-          */
 
-         hide: function(selector) {
 
-             DOM.query(selector).each(function(elem) {
 
-                 var style = elem[STYLE], old = style[DISPLAY];
 
-                 if (old !== NONE) {
 
-                     if (old) {
 
-                         DOM.data(elem, OLD_DISPLAY, old);
 
-                     }
 
-                     style[DISPLAY] = NONE;
 
-                 }
 
-             });
 
-         },
 
-         /**
 
-          * Display or hide the matched elements.
 
-          */
 
-         toggle: function(selector) {
 
-             DOM.query(selector).each(function(elem) {
 
-                 if (DOM.css(elem, DISPLAY) === NONE) {
 
-                     DOM.show(elem);
 
-                 } else {
 
-                     DOM.hide(elem);
 
-                 }
 
-             });
 
-         },
 
-         /**
 
-          * Creates a stylesheet from a text blob of rules.
 
-          * These rules will be wrapped in a STYLE tag and appended to the HEAD of the document.
 
-          * @param {String} cssText The text containing the css rules
 
-          * @param {String} id An id to add to the stylesheet for later removal
 
-          */
 
-         addStyleSheet: function(refWin, cssText, id) {
 
-             if (S.isString(refWin)) {
 
-                 id = cssText;
 
-                 cssText = refWin;
 
-                 refWin = window;
 
-             }
 
-             refWin = DOM.get(refWin);
 
-             var win = DOM._getWin(refWin),doc = win.document;
 
-             var elem;
 
-             if (id && (id = id.replace('#', EMPTY))) {
 
-                 elem = DOM.get('#' + id, doc);
 
-             }
 
-             // 仅添加一次,不重复添加
 
-             if (elem) {
 
-                 return;
 
-             }
 
-             elem = DOM.create('<style>', { id: id }, doc);
 
-             // 先添加到 DOM 树中,再给 cssText 赋值,否则 css hack 会失效
 
-             DOM.get('head', doc).appendChild(elem);
 
-             if (elem.styleSheet) { // IE
 
-                 elem.styleSheet.cssText = cssText;
 
-             } else { // W3C
 
-                 elem.appendChild(doc.createTextNode(cssText));
 
-             }
 
-         },
 
-         unselectable:function(selector) {
 
-             DOM.query(selector).each(function(elem) {
 
-                 if (UA['gecko']) {
 
-                     elem[STYLE]['MozUserSelect'] = 'none';
 
-                 }
 
-                 else if (UA['webkit']) {
 
-                     elem[STYLE]['KhtmlUserSelect'] = 'none';
 
-                 } else {
 
-                     if (UA['ie'] || UA['opera']) {
 
-                         var e,i = 0,
 
-                             els = elem.getElementsByTagName("*");
 
-                         elem.setAttribute("unselectable", 'on');
 
-                         while (( e = els[ i++ ] )) {
 
-                             switch (e.tagName.toLowerCase()) {
 
-                                 case 'iframe' :
 
-                                 case 'textarea' :
 
-                                 case 'input' :
 
-                                 case 'select' :
 
-                                     /* Ignore the above tags */
 
-                                     break;
 
-                                 default :
 
-                                     e.setAttribute("unselectable", 'on');
 
-                             }
 
-                         }
 
-                     }
 
-                 }
 
-             });
 
-         },
 
-         innerWidth:0,
 
-         innerHeight:0,
 
-         outerWidth:0,
 
-         outerHeight:0,
 
-         width:0,
 
-         height:0
 
-     });
 
-     function capital(str) {
 
-         return str.charAt(0).toUpperCase() + str.substring(1);
 
-     }
 
-     S.each([WIDTH,HEIGHT], function(name) {
 
-         DOM["inner" + capital(name)] = function(selector) {
 
-             var el = DOM.get(selector);
 
-             if (el) {
 
-                 return getWH(el, name, "padding");
 
-             } else {
 
-                 return null;
 
-             }
 
-         };
 
-         DOM["outer" + capital(name)] = function(selector, includeMargin) {
 
-             var el = DOM.get(selector);
 
-             if (el) {
 
-                 return getWH(el, name, includeMargin ? "margin" : "border");
 
-             } else {
 
-                 return null;
 
-             }
 
-         };
 
-         DOM[name] = function(selector, val) {
 
-             var ret = DOM.css(selector, name, val);
 
-             if (ret) {
 
-                 ret = parseFloat(ret);
 
-             }
 
-             return ret;
 
-         };
 
-     });
 
-     var cssShow = { position: "absolute", visibility: "hidden", display: "block" };
 
-     /**
 
-      * css height,width 永远都是计算值
 
-      */
 
-     S.each(["height", "width"], function(name) {
 
-         CUSTOM_STYLES[ name ] = {
 
-             get: function(elem, computed) {
 
-                 var val;
 
-                 if (computed) {
 
-                     if (elem.offsetWidth !== 0) {
 
-                         val = getWH(elem, name);
 
-                     } else {
 
-                         swap(elem, cssShow, function() {
 
-                             val = getWH(elem, name);
 
-                         });
 
-                     }
 
-                     return val + "px";
 
-                 }
 
-             },
 
-             set: function(elem, value) {
 
-                 if (RE_NUMPX.test(value)) {
 
-                     value = parseFloat(value);
 
-                     if (value >= 0) {
 
-                         return value + "px";
 
-                     }
 
-                 } else {
 
-                     return value;
 
-                 }
 
-             }
 
-         };
 
-     });
 
-     S.each(["left", "top"], function(name) {
 
-         CUSTOM_STYLES[ name ] = {
 
-             get: function(elem, computed) {
 
-                 if (computed) {
 
-                     var val = DOM._getComputedStyle(elem, name),offset;
 
-                     // 1. 当没有设置 style.left 时,getComputedStyle 在不同浏览器下,返回值不同
 
-                     //    比如:firefox 返回 0, webkit/ie 返回 auto
 
-                     // 2. style.left 设置为百分比时,返回值为百分比
 
-                     // 对于第一种情况,如果是 relative 元素,值为 0. 如果是 absolute 元素,值为 offsetLeft - marginLeft
 
-                     // 对于第二种情况,大部分类库都未做处理,属于“明之而不 fix”的保留 bug
 
-                     if (val === AUTO) {
 
-                         val = 0;
 
-                         if (S.inArray(DOM.css(elem, 'position'), ['absolute','fixed'])) {
 
-                             offset = elem[name === 'left' ? 'offsetLeft' : 'offsetTop'];
 
-                             // old-ie 下,elem.offsetLeft 包含 offsetParent 的 border 宽度,需要减掉
 
-                             if (isIE && document['documentMode'] != 9 || UA['opera']) {
 
-                                 // 类似 offset ie 下的边框处理
 
-                                 // 如果 offsetParent 为 html ,需要减去默认 2 px == documentElement.clientTop
 
-                                 // 否则减去 borderTop 其实也是 clientTop
 
-                                 // http://msdn.microsoft.com/en-us/library/aa752288%28v=vs.85%29.aspx
 
-                                 // ie<9 注意有时候 elem.offsetParent 为 null ...
 
-                                 // 比如 DOM.append(DOM.create("<div class='position:absolute'></div>"),document.body)
 
-                                 offset -= elem.offsetParent && elem.offsetParent['client' + (name == 'left' ? 'Left' : 'Top')]
 
-                                     || 0;
 
-                             }
 
-                             val = offset - (PARSEINT(DOM.css(elem, 'margin-' + name)) || 0);
 
-                         }
 
-                         val += "px";
 
-                     }
 
-                     return val;
 
-                 }
 
-             }
 
-         };
 
-     });
 
-     function swap(elem, options, callback) {
 
-         var old = {};
 
-         // Remember the old values, and insert the new ones
 
-         for (var name in options) {
 
-             old[ name ] = elem[STYLE][ name ];
 
-             elem[STYLE][ name ] = options[ name ];
 
-         }
 
-         callback.call(elem);
 
-         // Revert the old values
 
-         for (name in options) {
 
-             elem[STYLE][ name ] = old[ name ];
 
-         }
 
-     }
 
-     function style(elem, name, val) {
 
-         var style;
 
-         if (elem.nodeType === 3 || elem.nodeType === 8 || !(style = elem[STYLE])) {
 
-             return undefined;
 
-         }
 
-         name = camelCase(name);
 
-         var ret,hook = CUSTOM_STYLES[name];
 
-         name = cssProps[name] || name;
 
-         // setter
 
-         if (val !== undefined) {
 
-             // normalize unsetting
 
-             if (val === null || val === EMPTY) {
 
-                 val = EMPTY;
 
-             }
 
-             // number values may need a unit
 
-             else if (!isNaN(Number(val)) && !cssNumber[name]) {
 
-                 val += DEFAULT_UNIT;
 
-             }
 
-             if (hook && hook.set) {
 
-                 val = hook.set(elem, val);
 
-             }
 
-             if (val !== undefined) {
 
-                 // ie 无效值报错
 
-                 try {
 
-                     elem[STYLE][name] = val;
 
-                 } catch(e) {
 
-                     S.log("css set error :" + e);
 
-                 }
 
-             }
 
-             return undefined;
 
-         }
 
-         //getter
 
-         else {
 
-             // If a hook was provided get the non-computed value from there
 
-             if (hook && "get" in hook && (ret = hook.get(elem, false)) !== undefined) {
 
-             } else {
 
-                 // Otherwise just get the value from the style object
 
-                 ret = style[ name ];
 
-             }
 
-             return ret === undefined ? "" : ret;
 
-         }
 
-     }
 
-     /**
 
-      * 得到元素的大小信息
 
-      * @param elem
 
-      * @param name
 
-      * @param {String} extra    "padding" : (css width) + padding
 
-      *                          "border" : (css width) + padding + border
 
-      *                          "margin" : (css width) + padding + border + margin
 
-      */
 
-     function getWH(elem, name, extra) {
 
-         if (S.isWindow(elem)) {
 
-             return name == WIDTH ? DOM.viewportWidth(elem) : DOM.viewportHeight(elem);
 
-         } else if (elem.nodeType == 9) {
 
-             return name == WIDTH ? DOM.docWidth(elem) : DOM.docHeight(elem);
 
-         }
 
-         var which = name === WIDTH ? ['Left', 'Right'] : ['Top', 'Bottom'],
 
-             val = name === WIDTH ? elem.offsetWidth : elem.offsetHeight;
 
-         if (val > 0) {
 
-             if (extra !== "border") {
 
-                 S.each(which, function(w) {
 
-                     if (!extra) {
 
-                         val -= parseFloat(DOM.css(elem, "padding" + w)) || 0;
 
-                     }
 
-                     if (extra === "margin") {
 
-                         val += parseFloat(DOM.css(elem, extra + w)) || 0;
 
-                     } else {
 
-                         val -= parseFloat(DOM.css(elem, "border" + w + "Width")) || 0;
 
-                     }
 
-                 });
 
-             }
 
-             return val
 
-         }
 
-         // Fall back to computed then uncomputed css if necessary
 
-         val = DOM._getComputedStyle(elem, name);
 
-         if (val < 0 || S.isNullOrUndefined(val)) {
 
-             val = elem.style[ name ] || 0;
 
-         }
 
-         // Normalize "", auto, and prepare for extra
 
-         val = parseFloat(val) || 0;
 
-         // Add padding, border, margin
 
-         if (extra) {
 
-             S.each(which, function(w) {
 
-                 val += parseFloat(DOM.css(elem, "padding" + w)) || 0;
 
-                 if (extra !== "padding") {
 
-                     val += parseFloat(DOM.css(elem, "border" + w + "Width")) || 0;
 
-                 }
 
-                 if (extra === "margin") {
 
-                     val += parseFloat(DOM.css(elem, extra + w)) || 0;
 
-                 }
 
-             });
 
-         }
 
-         return val;
 
-     }
 
-     return DOM;
 
- }, {
 
-     requires:["dom/base","ua"]
 
- });
 
- /**
 
-  *
 
-  * 2011-08-19
 
-  *  - 调整结构,减少耦合
 
-  *  - fix css("height") == auto
 
-  *
 
-  * NOTES:
 
-  *  - Opera 下,color 默认返回 #XXYYZZ, 非 rgb(). 目前 jQuery 等类库均忽略此差异,KISSY 也忽略。
 
-  *  - Safari 低版本,transparent 会返回为 rgba(0, 0, 0, 0), 考虑低版本才有此 bug, 亦忽略。
 
-  *
 
-  *
 
-  *  - getComputedStyle 在 webkit 下,会舍弃小数部分,ie 下会四舍五入,gecko 下直接输出 float 值。
 
-  *
 
-  *  - color: blue 继承值,getComputedStyle, 在 ie 下返回 blue, opera 返回 #0000ff, 其它浏览器
 
-  *    返回 rgb(0, 0, 255)
 
-  *
 
-  *  - 总之:要使得返回值完全一致是不大可能的,jQuery/ExtJS/KISSY 未“追求完美”。YUI3 做了部分完美处理,但
 
-  *    依旧存在浏览器差异。
 
-  */
 
- /**
 
-  * @module  selector
 
-  * @author  lifesinger@gmail.com , yiminghe@gmail.com
 
-  */
 
- KISSY.add('dom/selector', function(S, DOM, undefined) {
 
-     var doc = document,
 
-         filter = S.filter,
 
-         require = function(selector) {
 
-             return S.require(selector);
 
-         },
 
-         isArray = S.isArray,
 
-         makeArray = S.makeArray,
 
-         isNodeList = DOM._isNodeList,
 
-         nodeName = DOM._nodeName,
 
-         push = Array.prototype.push,
 
-         SPACE = ' ',
 
-         COMMA = ',',
 
-         trim = S.trim,
 
-         ANY = '*',
 
-         REG_ID = /^#[\w-]+$/,
 
-         REG_QUERY = /^(?:#([\w-]+))?\s*([\w-]+|\*)?\.?([\w-]+)?$/;
 
-     /**
 
-      * Retrieves an Array of HTMLElement based on the given CSS selector.
 
-      * @param {String|Array} selector
 
-      * @param {String|Array<HTMLElement>|NodeList} context find elements matching selector under context
 
-      * @return {Array} The array of found HTMLElement
 
-      */
 
-     function query(selector, context) {
 
-         var ret,
 
-             i,
 
-             isSelectorString = typeof selector === 'string',
 
-             // optimize common usage
 
-             contexts = context === undefined ? [doc] : tuneContext(context);
 
-         if (isSelectorString) {
 
-             selector = trim(selector);
 
-             if (contexts.length == 1 && selector) {
 
-                 ret = quickFindBySelectorStr(selector, contexts[0]);
 
-             }
 
-         }
 
-         if (!ret) {
 
-             ret = [];
 
-             if (selector) {
 
-                 for (i = 0; i < contexts.length; i++) {
 
-                     push.apply(ret, queryByContexts(selector, contexts[i]));
 
-                 }
 
-                 //必要时去重排序
 
-                 if (ret.length > 1 &&
 
-                     // multiple contexts
 
-                     (contexts.length > 1 ||
 
-                         (isSelectorString &&
 
-                             // multiple selector
 
-                             selector.indexOf(COMMA) > -1))) {
 
-                     unique(ret);
 
-                 }
 
-             }
 
-         }
 
-         // attach each method
 
-         ret.each = function(f) {
 
-             var self = this,el,i;
 
-             for (i = 0; i < self.length; i++) {
 
-                 el = self[i];
 
-                 if (f(el, i) === false) {
 
-                     break;
 
-                 }
 
-             }
 
-         };
 
-         return ret;
 
-     }
 
-     function queryByContexts(selector, context) {
 
-         var ret = [],
 
-             isSelectorString = typeof selector === 'string';
 
-         if (isSelectorString && selector.match(REG_QUERY) ||
 
-             !isSelectorString) {
 
-             // 简单选择器自己处理
 
-             ret = queryBySimple(selector, context);
 
-         }
 
-         // 如果选择器有 , 分开递归一部分一部分来
 
-         else if (isSelectorString && selector.indexOf(COMMA) > -1) {
 
-             ret = queryBySelectors(selector, context);
 
-         }
 
-         else {
 
-             // 复杂了,交给 sizzle
 
-             ret = queryBySizzle(selector, context);
 
-         }
 
-         return ret;
 
-     }
 
-     // 交给 sizzle 模块处理
 
-     function queryBySizzle(selector, context) {
 
-         var ret = [],
 
-             sizzle = require("sizzle");
 
-         if (sizzle) {
 
-             sizzle(selector, context, ret);
 
-         } else {
 
-             // 原生不支持
 
-             error(selector);
 
-         }
 
-         return ret;
 
-     }
 
-     // 处理 selector 的每个部分
 
-     function queryBySelectors(selector, context) {
 
-         var ret = [],
 
-             i,
 
-             selectors = selector.split(/\s*,\s*/);
 
-         for (i = 0; i < selectors.length; i++) {
 
-             push.apply(ret, queryByContexts(selectors[i], context));
 
-         }
 
-         // 多部分选择器可能得到重复结果
 
-         return ret;
 
-     }
 
-     function quickFindBySelectorStr(selector, context) {
 
-         var ret,t,match,id,tag,cls;
 
-         // selector 为 #id 是最常见的情况,特殊优化处理
 
-         if (REG_ID.test(selector)) {
 
-             t = getElementById(selector.slice(1), context);
 
-             if (t) {
 
-                 // #id 无效时,返回空数组
 
-                 ret = [t];
 
-             } else {
 
-                 ret = [];
 
-             }
 
-         }
 
-         // selector 为支持列表中的其它 6 种
 
-         else {
 
-             match = REG_QUERY.exec(selector);
 
-             if (match) {
 
-                 // 获取匹配出的信息
 
-                 id = match[1];
 
-                 tag = match[2];
 
-                 cls = match[3];
 
-                 // 空白前只能有 id ,取出来作为 context
 
-                 context = (id ? getElementById(id, context) : context);
 
-                 if (context) {
 
-                     // #id .cls | #id tag.cls | .cls | tag.cls | #id.cls
 
-                     if (cls) {
 
-                         if (!id || selector.indexOf(SPACE) != -1) { // 排除 #id.cls
 
-                             ret = [].concat(getElementsByClassName(cls, tag, context));
 
-                         }
 
-                         // 处理 #id.cls
 
-                         else {
 
-                             t = getElementById(id, context);
 
-                             if (t && hasClass(t, cls)) {
 
-                                 ret = [t];
 
-                             }
 
-                         }
 
-                     }
 
-                     // #id tag | tag
 
-                     else if (tag) { // 排除空白字符串
 
-                         ret = getElementsByTagName(tag, context);
 
-                     }
 
-                 }
 
-                 ret = ret || [];
 
-             }
 
-         }
 
-         return ret;
 
-     }
 
-     // 最简单情况了,单个选择器部分,单个上下文
 
-     function queryBySimple(selector, context) {
 
-         var ret,
 
-             isSelectorString = typeof selector === 'string';
 
-         if (isSelectorString) {
 
-             ret = quickFindBySelectorStr(selector, context) || [];
 
-         }
 
-         // 传入的 selector 是 NodeList 或已是 Array
 
-         else if (selector && (isArray(selector) || isNodeList(selector))) {
 
-             // 只能包含在 context 里面
 
-             ret = filter(selector, function(s) {
 
-                 return testByContext(s, context);
 
-             });
 
-         }
 
-         // 传入的 selector 是 HTMLNode 查看约束
 
-         // 否则 window/document,原样返回
 
-         else if (selector && testByContext(selector, context)) {
 
-             ret = [selector];
 
-         }
 
-         return ret;
 
-     }
 
-     function testByContext(element, context) {
 
-         if (!element) {
 
-             return false;
 
-         }
 
-         // 防止 element 节点还没添加到 document ,但是也可以获取到 query(element) => [element]
 
-         // document 的上下文一律放行
 
-         // context == doc 意味着没有提供第二个参数,到这里只是想单纯包装原生节点,则不检测
 
-         if (context == doc) {
 
-             return true;
 
-         }
 
-         // 节点受上下文约束
 
-         return DOM.__contains(context, element);
 
-     }
 
-     var unique;
 
-     (function() {
 
-         var sortOrder,
 
-             t,
 
-             hasDuplicate,
 
-             baseHasDuplicate = true;
 
-         // Here we check if the JavaScript engine is using some sort of
 
- // optimization where it does not always call our comparision
 
- // function. If that is the case, discard the hasDuplicate value.
 
- //   Thus far that includes Google Chrome.
 
-         [0, 0].sort(function() {
 
-             baseHasDuplicate = false;
 
-             return 0;
 
-         });
 
-         // 排序去重
 
-         unique = function (elements) {
 
-             if (sortOrder) {
 
-                 hasDuplicate = baseHasDuplicate;
 
-                 elements.sort(sortOrder);
 
-                 if (hasDuplicate) {
 
-                     var i = 1,len = elements.length;
 
-                     while (i < len) {
 
-                         if (elements[i] === elements[ i - 1 ]) {
 
-                             elements.splice(i, 1);
 
-                         } else {
 
-                             i++;
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-             return elements;
 
-         };
 
-         // 貌似除了 ie 都有了...
 
-         if (doc.documentElement.compareDocumentPosition) {
 
-             sortOrder = t = function(a, b) {
 
-                 if (a == b) {
 
-                     hasDuplicate = true;
 
-                     return 0;
 
-                 }
 
-                 if (!a.compareDocumentPosition || !b.compareDocumentPosition) {
 
-                     return a.compareDocumentPosition ? -1 : 1;
 
-                 }
 
-                 return a.compareDocumentPosition(b) & 4 ? -1 : 1;
 
-             };
 
-         } else {
 
-             sortOrder = t = function(a, b) {
 
-                 // The nodes are identical, we can exit early
 
-                 if (a == b) {
 
-                     hasDuplicate = true;
 
-                     return 0;
 
-                     // Fallback to using sourceIndex (in IE) if it's available on both nodes
 
-                 } else if (a.sourceIndex && b.sourceIndex) {
 
-                     return a.sourceIndex - b.sourceIndex;
 
-                 }
 
-             };
 
-         }
 
-     })();
 
-     // 调整 context 为合理值
 
-     function tuneContext(context) {
 
-         // context 为 undefined 是最常见的情况,优先考虑
 
-         if (context === undefined) {
 
-             return [doc];
 
-         }
 
-         // 其他直接使用 query
 
-         return query(context, undefined);
 
-     }
 
-     // query #id
 
-     function getElementById(id, context) {
 
-         var doc = context,
 
-             el;
 
-         if (context.nodeType !== DOM.DOCUMENT_NODE) {
 
-             doc = context.ownerDocument;
 
-         }
 
-         el = doc.getElementById(id);
 
-         if (el && el.id === id) {
 
-             // optimize for common usage
 
-         }
 
-         else if (el && el.parentNode) {
 
-             // ie opera confuse name with id
 
-             // https://github.com/kissyteam/kissy/issues/67
 
-             // 不能直接 el.id ,否则 input shadow form attribute
 
-             if (DOM.__attr(el, "id") !== id) {
 
-                 // 直接在 context 下的所有节点找
 
-                 el = DOM.filter(ANY, "#" + id, context)[0] || null;
 
-             }
 
-             // ie 特殊情况下以及指明在 context 下找了,不需要再判断
 
-             // 如果指定了 context node , 还要判断 id 是否处于 context 内
 
-             else if (!testByContext(el, context)) {
 
-                 el = null;
 
-             }
 
-         } else {
 
-             el = null;
 
-         }
 
-         return el;
 
-     }
 
-     // query tag
 
-     function getElementsByTagName(tag, context) {
 
-         return context && makeArray(context.getElementsByTagName(tag)) || [];
 
-     }
 
-     (function() {
 
-         // Check to see if the browser returns only elements
 
-         // when doing getElementsByTagName('*')
 
-         // Create a fake element
 
-         var div = doc.createElement('div');
 
-         div.appendChild(doc.createComment(''));
 
-         // Make sure no comments are found
 
-         if (div.getElementsByTagName(ANY).length > 0) {
 
-             getElementsByTagName = function(tag, context) {
 
-                 var ret = makeArray(context.getElementsByTagName(tag));
 
-                 if (tag === ANY) {
 
-                     var t = [], i = 0,node;
 
-                     while ((node = ret[i++])) {
 
-                         // Filter out possible comments
 
-                         if (node.nodeType === 1) {
 
-                             t.push(node);
 
-                         }
 
-                     }
 
-                     ret = t;
 
-                 }
 
-                 return ret;
 
-             };
 
-         }
 
-     })();
 
-     // query .cls
 
-     var getElementsByClassName = doc.getElementsByClassName ? function(cls, tag, context) {
 
-         // query("#id1 xx","#id2")
 
-         // #id2 内没有 #id1 , context 为 null , 这里防御下
 
-         if (!context) {
 
-             return [];
 
-         }
 
-         var els = context.getElementsByClassName(cls),
 
-             ret,
 
-             i = 0,
 
-             len = els.length,
 
-             el;
 
-         if (tag && tag !== ANY) {
 
-             ret = [];
 
-             for (; i < len; ++i) {
 
-                 el = els[i];
 
-                 if (nodeName(el, tag)) {
 
-                     ret.push(el);
 
-                 }
 
-             }
 
-         } else {
 
-             ret = makeArray(els);
 
-         }
 
-         return ret;
 
-     } : ( doc.querySelectorAll ? function(cls, tag, context) {
 
-         // ie8 return staticNodeList 对象,[].concat 会形成 [ staticNodeList ] ,手动转化为普通数组
 
-         return context && makeArray(context.querySelectorAll((tag ? tag : '') + '.' + cls)) || [];
 
-     } : function(cls, tag, context) {
 
-         if (!context) {
 
-             return [];
 
-         }
 
-         var els = context.getElementsByTagName(tag || ANY),
 
-             ret = [],
 
-             i = 0,
 
-             len = els.length,
 
-             el;
 
-         for (; i < len; ++i) {
 
-             el = els[i];
 
-             if (hasClass(el, cls)) {
 
-                 ret.push(el);
 
-             }
 
-         }
 
-         return ret;
 
-     });
 
-     function hasClass(el, cls) {
 
-         return DOM.__hasClass(el, cls);
 
-     }
 
-     // throw exception
 
-     function error(msg) {
 
-         S.error('Unsupported selector: ' + msg);
 
-     }
 
-     S.mix(DOM, {
 
-         query: query,
 
-         get: function(selector, context) {
 
-             return query(selector, context)[0] || null;
 
-         },
 
-         unique:unique,
 
-         /**
 
-          * Filters an array of elements to only include matches of a filter.
 
-          * @param filter selector or fn
 
-          */
 
-         filter: function(selector, filter, context) {
 
-             var elems = query(selector, context),
 
-                 sizzle = require("sizzle"),
 
-                 match,
 
-                 tag,
 
-                 id,
 
-                 cls,
 
-                 ret = [];
 
-             // 默认仅支持最简单的 tag.cls 或 #id 形式
 
-             if (typeof filter === 'string' &&
 
-                 (filter = trim(filter)) &&
 
-                 (match = REG_QUERY.exec(filter))) {
 
-                 id = match[1];
 
-                 tag = match[2];
 
-                 cls = match[3];
 
-                 if (!id) {
 
-                     filter = function(elem) {
 
-                         var tagRe = true,clsRe = true;
 
-                         // 指定 tag 才进行判断
 
-                         if (tag) {
 
-                             tagRe = nodeName(elem, tag);
 
-                         }
 
-                         // 指定 cls 才进行判断
 
-                         if (cls) {
 
-                             clsRe = hasClass(elem, cls);
 
-                         }
 
-                         return clsRe && tagRe;
 
-                     }
 
-                 } else if (id && !tag && !cls) {
 
-                     filter = function(elem) {
 
-                         return DOM.__attr(elem, "id") === id;
 
-                     };
 
-                 }
 
-             }
 
-             if (S.isFunction(filter)) {
 
-                 ret = S.filter(elems, filter);
 
-             }
 
-             // 其它复杂 filter, 采用外部选择器
 
-             else if (filter && sizzle) {
 
-                 ret = sizzle.matches(filter, elems);
 
-             }
 
-             // filter 为空或不支持的 selector
 
-             else {
 
-                 error(filter);
 
-             }
 
-             return ret;
 
-         },
 
-         /**
 
-          * Returns true if the passed element(s) match the passed filter
 
-          */
 
-         test: function(selector, filter, context) {
 
-             var elements = query(selector, context);
 
-             return elements.length && (DOM.filter(elements, filter, context).length === elements.length);
 
-         }
 
-     });
 
-     return DOM;
 
- }, {
 
-     requires:["./base"]
 
- });
 
- /**
 
-  * NOTES:
 
-  *
 
-  * 2011.08.02
 
-  *  - 利用 sizzle 重构选择器
 
-  *  - 1.1.6 修正,原来 context 只支持 #id 以及 document
 
-  *    1.2 context 支持任意,和 selector 格式一致
 
-  *  - 简单选择器也和 jquery 保持一致 DOM.query("xx","yy") 支持
 
-  *    - context 不提供则为当前 document ,否则通过 query 递归取得
 
-  *    - 保证选择出来的节点(除了 document window)都是位于 context 范围内
 
-  *
 
-  *
 
-  * 2010.01
 
-  *  - 对 reg exec 的结果(id, tag, className)做 cache, 发现对性能影响很小,去掉。
 
-  *  - getElementById 使用频率最高,使用直达通道优化。
 
-  *  - getElementsByClassName 性能优于 querySelectorAll, 但 IE 系列不支持。
 
-  *  - instanceof 对性能有影响。
 
-  *  - 内部方法的参数,比如 cls, context 等的异常情况,已经在 query 方法中有保证,无需冗余“防卫”。
 
-  *  - query 方法中的条件判断考虑了“频率优先”原则。最有可能出现的情况放在前面。
 
-  *  - Array 的 push 方法可以用 j++ 来替代,性能有提升。
 
-  *  - 返回值策略和 Sizzle 一致,正常时,返回数组;其它所有情况,返回空数组。
 
-  *
 
-  *  - 从压缩角度考虑,还可以将 getElmentsByTagName 和 getElementsByClassName 定义为常量,
 
-  *    不过感觉这样做太“压缩控”,还是保留不替换的好。
 
-  *
 
-  *  - 调整 getElementsByClassName 的降级写法,性能最差的放最后。
 
-  *
 
-  * 2010.02
 
-  *  - 添加对分组选择器的支持(主要参考 Sizzle 的代码,代去除了对非 Grade A 级浏览器的支持)
 
-  *
 
-  * 2010.03
 
-  *  - 基于原生 dom 的两个 api: S.query 返回数组; S.get 返回第一个。
 
-  *    基于 Node 的 api: S.one, 在 Node 中实现。
 
-  *    基于 NodeList 的 api: S.all, 在 NodeList 中实现。
 
-  *    通过 api 的分层,同时满足初级用户和高级用户的需求。
 
-  *
 
-  * 2010.05
 
-  *  - 去掉给 S.query 返回值默认添加的 each 方法,保持纯净。
 
-  *  - 对于不支持的 selector, 采用外部耦合进来的 Selector.
 
-  *
 
-  * 2010.06
 
-  *  - 增加 filter 和 test 方法
 
-  *
 
-  * 2010.07
 
-  *  - 取消对 , 分组的支持,group 直接用 Sizzle
 
-  *
 
-  * 2010.08
 
-  *  - 给 S.query 的结果 attach each 方法
 
-  *
 
-  * 2011.05
 
-  *  - 承玉:恢复对简单分组支持
 
-  *
 
-  * Ref: http://ejohn.org/blog/selectors-that-people-actually-use/
 
-  * 考虑 2/8 原则,仅支持以下选择器:
 
-  * #id
 
-  * tag
 
-  * .cls
 
-  * #id tag
 
-  * #id .cls
 
-  * tag.cls
 
-  * #id tag.cls
 
-  * 注 1:REG_QUERY 还会匹配 #id.cls
 
-  * 注 2:tag 可以为 * 字符
 
-  * 注 3: 支持 , 号分组
 
-  *
 
-  *
 
-  * Bugs:
 
-  *  - S.query('#test-data *') 等带 * 号的选择器,在 IE6 下返回的值不对。jQuery 等类库也有此 bug, 诡异。
 
-  *
 
-  * References:
 
-  *  - http://ejohn.org/blog/selectors-that-people-actually-use/
 
-  *  - http://ejohn.org/blog/thoughts-on-queryselectorall/
 
-  *  - MDC: querySelector, querySelectorAll, getElementsByClassName
 
-  *  - Sizzle: http://github.com/jeresig/sizzle
 
-  *  - MINI: http://james.padolsey.com/javascript/mini/
 
-  *  - Peppy: http://jamesdonaghue.com/?p=40
 
-  *  - Sly: http://github.com/digitarald/sly
 
-  *  - XPath, TreeWalker:http://www.cnblogs.com/rubylouvre/archive/2009/07/24/1529640.html
 
-  *
 
-  *  - http://www.quirksmode.org/blog/archives/2006/01/contains_for_mo.html
 
-  *  - http://www.quirksmode.org/dom/getElementsByTagNames.html
 
-  *  - http://ejohn.org/blog/comparing-document-position/
 
-  *  - http://github.com/jeresig/sizzle/blob/master/sizzle.js
 
-  */
 
- /**
 
-  * @module  dom
 
-  * @author  lifesinger@gmail.com,yiminghe@gmail.com
 
-  */
 
- KISSY.add('dom/style-ie', function(S, DOM, UA, Style) {
 
-         var HUNDRED = 100;
 
-         // only for ie
 
-         if (!UA['ie']) {
 
-             return DOM;
 
-         }
 
-         var doc = document,
 
-             docElem = doc.documentElement,
 
-             OPACITY = 'opacity',
 
-             STYLE = 'style',
 
-             FILTER = "filter",
 
-             CURRENT_STYLE = 'currentStyle',
 
-             RUNTIME_STYLE = 'runtimeStyle',
 
-             LEFT = 'left',
 
-             PX = 'px',
 
-             CUSTOM_STYLES = Style._CUSTOM_STYLES,
 
-             RE_NUMPX = /^-?\d+(?:px)?$/i,
 
-             RE_NUM = /^-?\d/,
 
-             ropacity = /opacity=([^)]*)/,
 
-             ralpha = /alpha\([^)]*\)/i;
 
-         // use alpha filter for IE opacity
 
-         try {
 
-             if (S.isNullOrUndefined(docElem.style[OPACITY])) {
 
-                 CUSTOM_STYLES[OPACITY] = {
 
-                     get: function(elem, computed) {
 
-                         // 没有设置过 opacity 时会报错,这时返回 1 即可
 
-                         // 如果该节点没有添加到 dom ,取不到 filters 结构
 
-                         // val = elem[FILTERS]['DXImageTransform.Microsoft.Alpha'][OPACITY];
 
-                         return ropacity.test((
 
-                             computed && elem[CURRENT_STYLE] ?
 
-                                 elem[CURRENT_STYLE][FILTER] :
 
-                                 elem[STYLE][FILTER]) || "") ?
 
-                             ( parseFloat(RegExp.$1) / HUNDRED ) + "" :
 
-                             computed ? "1" : "";
 
-                     },
 
-                     set: function(elem, val) {
 
-                         val = parseFloat(val);
 
-                         var style = elem[STYLE],
 
-                             currentStyle = elem[CURRENT_STYLE],
 
-                             opacity = isNaN(val) ? "" : "alpha(" + OPACITY + "=" + val * HUNDRED + ")",
 
-                             filter = S.trim(currentStyle && currentStyle[FILTER] || style[FILTER] || "");
 
-                         // ie  has layout
 
-                         style.zoom = 1;
 
-                         // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute
 
-                         if (val >= 1 && S.trim(filter.replace(ralpha, "")) === "") {
 
-                             // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
 
-                             // if "filter:" is present at all, clearType is disabled, we want to avoid this
 
-                             // style.removeAttribute is IE Only, but so apparently is this code path...
 
-                             style.removeAttribute(FILTER);
 
-                             // if there there is no filter style applied in a css rule, we are done
 
-                             if (currentStyle && !currentStyle[FILTER]) {
 
-                                 return;
 
-                             }
 
-                         }
 
-                         // otherwise, set new filter values
 
-                         // 如果 >=1 就不设,就不能覆盖外部样式表定义的样式,一定要设
 
-                         style.filter = ralpha.test(filter) ?
 
-                             filter.replace(ralpha, opacity) :
 
-                             filter + (filter ? ", " : "") + opacity;
 
-                     }
 
-                 };
 
-             }
 
-         }
 
-         catch(ex) {
 
-             S.log('IE filters ActiveX is disabled. ex = ' + ex);
 
-         }
 
-         /**
 
-          * border fix
 
-          * ie 不设置数值,则 computed style 不返回数值,只返回 thick? medium ...
 
-          * (default is "medium")
 
-          */
 
-         var IE8 = UA['ie'] == 8,
 
-             BORDER_MAP = {
 
-             },
 
-             BORDERS = ["","Top","Left","Right","Bottom"];
 
-         BORDER_MAP['thin'] = IE8 ? '1px' : '2px';
 
-         BORDER_MAP['medium'] = IE8 ? '3px' : '4px';
 
-         BORDER_MAP['thick'] = IE8 ? '5px' : '6px';
 
-         S.each(BORDERS, function(b) {
 
-             var name = "border" + b + "Width",
 
-                 styleName = "border" + b + "Style";
 
-             CUSTOM_STYLES[name] = {
 
-                 get: function(elem, computed) {
 
-                     // 只有需要计算样式的时候才转换,否则取原值
 
-                     var currentStyle = computed ? elem[CURRENT_STYLE] : 0,
 
-                         current = currentStyle && String(currentStyle[name]) || undefined;
 
-                     // look up keywords if a border exists
 
-                     if (current && current.indexOf("px") < 0) {
 
-                         // 边框没有隐藏
 
-                         if (BORDER_MAP[current] && currentStyle[styleName] !== "none") {
 
-                             current = BORDER_MAP[current];
 
-                         } else {
 
-                             // otherwise no border
 
-                             current = 0;
 
-                         }
 
-                     }
 
-                     return current;
 
-                 }
 
-             };
 
-         });
 
-         // getComputedStyle for IE
 
-         if (!(doc.defaultView || { }).getComputedStyle && docElem[CURRENT_STYLE]) {
 
-             DOM._getComputedStyle = function(elem, name) {
 
-                 name = DOM._cssProps[name] || name;
 
-                 var ret = elem[CURRENT_STYLE] && elem[CURRENT_STYLE][name];
 
-                 // 当 width/height 设置为百分比时,通过 pixelLeft 方式转换的 width/height 值
 
-                 // 一开始就处理了! CUSTOM_STYLE["height"],CUSTOM_STYLE["width"] ,cssHook 解决@2011-08-19
 
-                 // 在 ie 下不对,需要直接用 offset 方式
 
-                 // borderWidth 等值也有问题,但考虑到 borderWidth 设为百分比的概率很小,这里就不考虑了
 
-                 // From the awesome hack by Dean Edwards
 
-                 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
 
-                 // If we're not dealing with a regular pixel number
 
-                 // but a number that has a weird ending, we need to convert it to pixels
 
-                 if ((!RE_NUMPX.test(ret) && RE_NUM.test(ret))) {
 
-                     // Remember the original values
 
-                     var style = elem[STYLE],
 
-                         left = style[LEFT],
 
-                         rsLeft = elem[RUNTIME_STYLE] && elem[RUNTIME_STYLE][LEFT];
 
-                     // Put in the new values to get a computed value out
 
-                     if (rsLeft) {
 
-                         elem[RUNTIME_STYLE][LEFT] = elem[CURRENT_STYLE][LEFT];
 
-                     }
 
-                     style[LEFT] = name === 'fontSize' ? '1em' : (ret || 0);
 
-                     ret = style['pixelLeft'] + PX;
 
-                     // Revert the changed values
 
-                     style[LEFT] = left;
 
-                     if (rsLeft) {
 
-                         elem[RUNTIME_STYLE][LEFT] = rsLeft;
 
-                     }
 
-                 }
 
-                 return ret === "" ? "auto" : ret;
 
-             };
 
-         }
 
-         return DOM;
 
-     },
 
-     {
 
-         requires:["./base","ua","./style"]
 
-     }
 
- );
 
- /**
 
-  * NOTES:
 
-  * 承玉: 2011.05.19 opacity in ie
 
-  *  - 如果节点是动态创建,设置opacity,没有加到 dom 前,取不到 opacity 值
 
-  *  - 兼容:border-width 值,ie 下有可能返回 medium/thin/thick 等值,其它浏览器返回 px 值。
 
-  *
 
-  *  - opacity 的实现,参考自 jquery
 
-  *
 
-  */
 
- /**
 
-  * @module  dom-traversal
 
-  * @author  lifesinger@gmail.com,yiminghe@gmail.com
 
-  */
 
- KISSY.add('dom/traversal', function(S, DOM, undefined) {
 
-     var isElementNode = DOM._isElementNode,
 
-         CONTAIN_MASK = 16;
 
-     S.mix(DOM, {
 
-         closest:function(selector, filter, context) {
 
-             return nth(selector, filter, 'parentNode', function(elem) {
 
-                 return elem.nodeType != DOM.DOCUMENT_FRAGMENT_NODE;
 
-             }, context, true);
 
-         },
 
-         /**
 
-          * Gets the parent node of the first matched element.
 
-          */
 
-         parent: function(selector, filter, context) {
 
-             return nth(selector, filter, 'parentNode', function(elem) {
 
-                 return elem.nodeType != DOM.DOCUMENT_FRAGMENT_NODE;
 
-             }, context);
 
-         },
 
-         first:function(selector, filter) {
 
-             var elem = DOM.get(selector);
 
-             return nth(elem && elem.firstChild, filter, 'nextSibling',
 
-                 undefined, undefined, true);
 
-         },
 
-         last:function(selector, filter) {
 
-             var elem = DOM.get(selector);
 
-             return nth(elem && elem.lastChild, filter, 'previousSibling',
 
-                 undefined, undefined, true);
 
-         },
 
-         /**
 
-          * Gets the following sibling of the first matched element.
 
-          */
 
-         next: function(selector, filter) {
 
-             return nth(selector, filter, 'nextSibling', undefined);
 
-         },
 
-         /**
 
-          * Gets the preceding sibling of the first matched element.
 
-          */
 
-         prev: function(selector, filter) {
 
-             return nth(selector, filter, 'previousSibling', undefined);
 
-         },
 
-         /**
 
-          * Gets the siblings of the first matched element.
 
-          */
 
-         siblings: function(selector, filter) {
 
-             return getSiblings(selector, filter, true);
 
-         },
 
-         /**
 
-          * Gets the children of the first matched element.
 
-          */
 
-         children: function(selector, filter) {
 
-             return getSiblings(selector, filter, undefined);
 
-         },
 
-         __contains:document.documentElement.contains ?
 
-             function(a, b) {
 
-                 if (a.nodeType == DOM.TEXT_NODE) {
 
-                     return false;
 
-                 }
 
-                 var precondition;
 
-                 if (b.nodeType == DOM.TEXT_NODE) {
 
-                     b = b.parentNode;
 
-                     // a 和 b父亲相等也就是返回 true
 
-                     precondition = true;
 
-                 } else if (b.nodeType == DOM.DOCUMENT_NODE) {
 
-                     // b === document
 
-                     // 没有任何元素能包含 document
 
-                     return false;
 
-                 } else {
 
-                     // a 和 b 相等返回 false
 
-                     precondition = a !== b;
 
-                 }
 
-                 // !a.contains => a===document
 
-                 // 注意原生 contains 判断时 a===b 也返回 true
 
-                 return precondition && (a.contains ? a.contains(b) : true);
 
-             } : (
 
-             document.documentElement.compareDocumentPosition ?
 
-                 function(a, b) {
 
-                     return !!(a.compareDocumentPosition(b) & CONTAIN_MASK);
 
-                 } :
 
-                 // it can not be true , pathetic browser
 
-                 0
 
-             ),
 
-         /**
 
-          * Check to see if a DOM node is within another DOM node.
 
-          */
 
-         contains:
 
-             function(a, b) {
 
-                 a = DOM.get(a);
 
-                 b = DOM.get(b);
 
-                 if (a && b) {
 
-                     return DOM.__contains(a, b);
 
-                 }
 
-             },
 
-         equals:function(n1, n2) {
 
-             n1 = DOM.query(n1);
 
-             n2 = DOM.query(n2);
 
-             if (n1.length != n2.length) {
 
-                 return false;
 
-             }
 
-             for (var i = n1.length; i >= 0; i--) {
 
-                 if (n1[i] != n2[i]) {
 
-                     return false;
 
-                 }
 
-             }
 
-             return true;
 
-         }
 
-     });
 
-     // 获取元素 elem 在 direction 方向上满足 filter 的第一个元素
 
-     // filter 可为 number, selector, fn array ,为数组时返回多个
 
-     // direction 可为 parentNode, nextSibling, previousSibling
 
-     // context : 到某个阶段不再查找直接返回
 
-     function nth(elem, filter, direction, extraFilter, context, includeSef) {
 
-         if (!(elem = DOM.get(elem))) {
 
-             return null;
 
-         }
 
-         if (filter === 0) {
 
-             return elem;
 
-         }
 
-         if (!includeSef) {
 
-             elem = elem[direction];
 
-         }
 
-         if (!elem) {
 
-             return null;
 
-         }
 
-         context = (context && DOM.get(context)) || null;
 
-         if (filter === undefined) {
 
-             // 默认取 1
 
-             filter = 1;
 
-         }
 
-         var ret = [],
 
-             isArray = S.isArray(filter),
 
-             fi,
 
-             flen;
 
-         if (S.isNumber(filter)) {
 
-             fi = 0;
 
-             flen = filter;
 
-             filter = function() {
 
-                 return ++fi === flen;
 
-             };
 
-         }
 
-         // 概念统一,都是 context 上下文,只过滤子孙节点,自己不管
 
-         while (elem && elem != context) {
 
-             if (isElementNode(elem)
 
-                 && testFilter(elem, filter)
 
-                 && (!extraFilter || extraFilter(elem))) {
 
-                 ret.push(elem);
 
-                 if (!isArray) {
 
-                     break;
 
-                 }
 
-             }
 
-             elem = elem[direction];
 
-         }
 
-         return isArray ? ret : ret[0] || null;
 
-     }
 
-     function testFilter(elem, filter) {
 
-         if (!filter) {
 
-             return true;
 
-         }
 
-         if (S.isArray(filter)) {
 
-             for (var i = 0; i < filter.length; i++) {
 
-                 if (DOM.test(elem, filter[i])) {
 
-                     return true;
 
-                 }
 
-             }
 
-         } else if (DOM.test(elem, filter)) {
 
-             return true;
 
-         }
 
-         return false;
 
-     }
 
-     // 获取元素 elem 的 siblings, 不包括自身
 
-     function getSiblings(selector, filter, parent) {
 
-         var ret = [],
 
-             elem = DOM.get(selector),
 
-             j,
 
-             parentNode = elem,
 
-             next;
 
-         if (elem && parent) {
 
-             parentNode = elem.parentNode;
 
-         }
 
-         if (parentNode) {
 
-             for (j = 0,next = parentNode.firstChild;
 
-                  next;
 
-                  next = next.nextSibling) {
 
-                 if (isElementNode(next)
 
-                     && next !== elem
 
-                     && (!filter || DOM.test(next, filter))) {
 
-                     ret[j++] = next;
 
-                 }
 
-             }
 
-         }
 
-         return ret;
 
-     }
 
-     return DOM;
 
- }, {
 
-     requires:["./base"]
 
- });
 
- /**
 
-  * 2011-08
 
-  * - 添加 closest , first ,last 完全摆脱原生属性
 
-  *
 
-  * NOTES:
 
-  * - jquery does not return null ,it only returns empty array , but kissy does.
 
-  *
 
-  *  - api 的设计上,没有跟随 jQuery. 一是为了和其他 api 一致,保持 first-all 原则。二是
 
-  *    遵循 8/2 原则,用尽可能少的代码满足用户最常用的功能。
 
-  *
 
-  */
 
- KISSY.add("dom", function(S,DOM) {
 
-     return DOM;
 
- }, {
 
-     requires:["dom/attr",
 
-         "dom/class",
 
-         "dom/create",
 
-         "dom/data",
 
-         "dom/insertion",
 
-         "dom/offset",
 
-         "dom/style",
 
-         "dom/selector",
 
-         "dom/style-ie",
 
-         "dom/traversal"]
 
- });
 
- /**
 
-  * @fileOverview some keycodes definition and utils from closure-library
 
-  * @author yiminghe@gmail.com
 
-  */
 
- KISSY.add("event/keycodes", function() {
 
-     var KeyCodes = {
 
-         MAC_ENTER: 3,
 
-         BACKSPACE: 8,
 
-         TAB: 9,
 
-         NUM_CENTER: 12,  // NUMLOCK on FF/Safari Mac
 
-         ENTER: 13,
 
-         SHIFT: 16,
 
-         CTRL: 17,
 
-         ALT: 18,
 
-         PAUSE: 19,
 
-         CAPS_LOCK: 20,
 
-         ESC: 27,
 
-         SPACE: 32,
 
-         PAGE_UP: 33,     // also NUM_NORTH_EAST
 
-         PAGE_DOWN: 34,   // also NUM_SOUTH_EAST
 
-         END: 35,         // also NUM_SOUTH_WEST
 
-         HOME: 36,        // also NUM_NORTH_WEST
 
-         LEFT: 37,        // also NUM_WEST
 
-         UP: 38,          // also NUM_NORTH
 
-         RIGHT: 39,       // also NUM_EAST
 
-         DOWN: 40,        // also NUM_SOUTH
 
-         PRINT_SCREEN: 44,
 
-         INSERT: 45,      // also NUM_INSERT
 
-         DELETE: 46,      // also NUM_DELETE
 
-         ZERO: 48,
 
-         ONE: 49,
 
-         TWO: 50,
 
-         THREE: 51,
 
-         FOUR: 52,
 
-         FIVE: 53,
 
-         SIX: 54,
 
-         SEVEN: 55,
 
-         EIGHT: 56,
 
-         NINE: 57,
 
-         QUESTION_MARK: 63, // needs localization
 
-         A: 65,
 
-         B: 66,
 
-         C: 67,
 
-         D: 68,
 
-         E: 69,
 
-         F: 70,
 
-         G: 71,
 
-         H: 72,
 
-         I: 73,
 
-         J: 74,
 
-         K: 75,
 
-         L: 76,
 
-         M: 77,
 
-         N: 78,
 
-         O: 79,
 
-         P: 80,
 
-         Q: 81,
 
-         R: 82,
 
-         S: 83,
 
-         T: 84,
 
-         U: 85,
 
-         V: 86,
 
-         W: 87,
 
-         X: 88,
 
-         Y: 89,
 
-         Z: 90,
 
-         META: 91, // WIN_KEY_LEFT
 
-         WIN_KEY_RIGHT: 92,
 
-         CONTEXT_MENU: 93,
 
-         NUM_ZERO: 96,
 
-         NUM_ONE: 97,
 
-         NUM_TWO: 98,
 
-         NUM_THREE: 99,
 
-         NUM_FOUR: 100,
 
-         NUM_FIVE: 101,
 
-         NUM_SIX: 102,
 
-         NUM_SEVEN: 103,
 
-         NUM_EIGHT: 104,
 
-         NUM_NINE: 105,
 
-         NUM_MULTIPLY: 106,
 
-         NUM_PLUS: 107,
 
-         NUM_MINUS: 109,
 
-         NUM_PERIOD: 110,
 
-         NUM_DIVISION: 111,
 
-         F1: 112,
 
-         F2: 113,
 
-         F3: 114,
 
-         F4: 115,
 
-         F5: 116,
 
-         F6: 117,
 
-         F7: 118,
 
-         F8: 119,
 
-         F9: 120,
 
-         F10: 121,
 
-         F11: 122,
 
-         F12: 123,
 
-         NUMLOCK: 144,
 
-         SEMICOLON: 186,            // needs localization
 
-         DASH: 189,                 // needs localization
 
-         EQUALS: 187,               // needs localization
 
-         COMMA: 188,                // needs localization
 
-         PERIOD: 190,               // needs localization
 
-         SLASH: 191,                // needs localization
 
-         APOSTROPHE: 192,           // needs localization
 
-         SINGLE_QUOTE: 222,         // needs localization
 
-         OPEN_SQUARE_BRACKET: 219,  // needs localization
 
-         BACKSLASH: 220,            // needs localization
 
-         CLOSE_SQUARE_BRACKET: 221, // needs localization
 
-         WIN_KEY: 224,
 
-         MAC_FF_META: 224, // Firefox (Gecko) fires this for the meta key instead of 91
 
-         WIN_IME: 229
 
-     };
 
-     KeyCodes.isTextModifyingKeyEvent = function(e) {
 
-         if (e.altKey && !e.ctrlKey ||
 
-             e.metaKey ||
 
-             // Function keys don't generate text
 
-             e.keyCode >= KeyCodes.F1 &&
 
-                 e.keyCode <= KeyCodes.F12) {
 
-             return false;
 
-         }
 
-         // The following keys are quite harmless, even in combination with
 
-         // CTRL, ALT or SHIFT.
 
-         switch (e.keyCode) {
 
-             case KeyCodes.ALT:
 
-             case KeyCodes.CAPS_LOCK:
 
-             case KeyCodes.CONTEXT_MENU:
 
-             case KeyCodes.CTRL:
 
-             case KeyCodes.DOWN:
 
-             case KeyCodes.END:
 
-             case KeyCodes.ESC:
 
-             case KeyCodes.HOME:
 
-             case KeyCodes.INSERT:
 
-             case KeyCodes.LEFT:
 
-             case KeyCodes.MAC_FF_META:
 
-             case KeyCodes.META:
 
-             case KeyCodes.NUMLOCK:
 
-             case KeyCodes.NUM_CENTER:
 
-             case KeyCodes.PAGE_DOWN:
 
-             case KeyCodes.PAGE_UP:
 
-             case KeyCodes.PAUSE:
 
-             case KeyCodes.PHANTOM:
 
-             case KeyCodes.PRINT_SCREEN:
 
-             case KeyCodes.RIGHT:
 
-             case KeyCodes.SHIFT:
 
-             case KeyCodes.UP:
 
-             case KeyCodes.WIN_KEY:
 
-             case KeyCodes.WIN_KEY_RIGHT:
 
-                 return false;
 
-             default:
 
-                 return true;
 
-         }
 
-     };
 
-     KeyCodes.isCharacterKey = function(keyCode) {
 
-         if (keyCode >= KeyCodes.ZERO &&
 
-             keyCode <= KeyCodes.NINE) {
 
-             return true;
 
-         }
 
-         if (keyCode >= KeyCodes.NUM_ZERO &&
 
-             keyCode <= KeyCodes.NUM_MULTIPLY) {
 
-             return true;
 
-         }
 
-         if (keyCode >= KeyCodes.A &&
 
-             keyCode <= KeyCodes.Z) {
 
-             return true;
 
-         }
 
-         // Safari sends zero key code for non-latin characters.
 
-         if (goog.userAgent.WEBKIT && keyCode == 0) {
 
-             return true;
 
-         }
 
-         switch (keyCode) {
 
-             case KeyCodes.SPACE:
 
-             case KeyCodes.QUESTION_MARK:
 
-             case KeyCodes.NUM_PLUS:
 
-             case KeyCodes.NUM_MINUS:
 
-             case KeyCodes.NUM_PERIOD:
 
-             case KeyCodes.NUM_DIVISION:
 
-             case KeyCodes.SEMICOLON:
 
-             case KeyCodes.DASH:
 
-             case KeyCodes.EQUALS:
 
-             case KeyCodes.COMMA:
 
-             case KeyCodes.PERIOD:
 
-             case KeyCodes.SLASH:
 
-             case KeyCodes.APOSTROPHE:
 
-             case KeyCodes.SINGLE_QUOTE:
 
-             case KeyCodes.OPEN_SQUARE_BRACKET:
 
-             case KeyCodes.BACKSLASH:
 
-             case KeyCodes.CLOSE_SQUARE_BRACKET:
 
-                 return true;
 
-             default:
 
-                 return false;
 
-         }
 
-     };
 
-     return KeyCodes;
 
- });
 
- /**
 
-  * @module  EventObject
 
-  * @author  lifesinger@gmail.com
 
-  */
 
- KISSY.add('event/object', function(S, undefined) {
 
-     var doc = document,
 
-         props = ('altKey attrChange attrName bubbles button cancelable ' +
 
-             'charCode clientX clientY ctrlKey currentTarget data detail ' +
 
-             'eventPhase fromElement handler keyCode metaKey ' +
 
-             'newValue offsetX offsetY originalTarget pageX pageY prevValue ' +
 
-             'relatedNode relatedTarget screenX screenY shiftKey srcElement ' +
 
-             'target toElement view wheelDelta which axis').split(' ');
 
-     /**
 
-      * KISSY's event system normalizes the event object according to
 
-      * W3C standards. The event object is guaranteed to be passed to
 
-      * the event handler. Most properties from the original event are
 
-      * copied over and normalized to the new event object.
 
-      */
 
-     function EventObject(currentTarget, domEvent, type) {
 
-         var self = this;
 
-         self.currentTarget = currentTarget;
 
-         self.originalEvent = domEvent || { };
 
-         if (domEvent) { // html element
 
-             self.type = domEvent.type;
 
-             self._fix();
 
-         }
 
-         else { // custom
 
-             self.type = type;
 
-             self.target = currentTarget;
 
-         }
 
-         // bug fix: in _fix() method, ie maybe reset currentTarget to undefined.
 
-         self.currentTarget = currentTarget;
 
-         self.fixed = true;
 
-     }
 
-     S.augment(EventObject, {
 
-         _fix: function() {
 
-             var self = this,
 
-                 originalEvent = self.originalEvent,
 
-                 l = props.length, prop,
 
-                 ct = self.currentTarget,
 
-                 ownerDoc = (ct.nodeType === 9) ? ct : (ct.ownerDocument || doc); // support iframe
 
-             // clone properties of the original event object
 
-             while (l) {
 
-                 prop = props[--l];
 
-                 self[prop] = originalEvent[prop];
 
-             }
 
-             // fix target property, if necessary
 
-             if (!self.target) {
 
-                 self.target = self.srcElement || doc; // srcElement might not be defined either
 
-             }
 
-             // check if target is a textnode (safari)
 
-             if (self.target.nodeType === 3) {
 
-                 self.target = self.target.parentNode;
 
-             }
 
-             // add relatedTarget, if necessary
 
-             if (!self.relatedTarget && self.fromElement) {
 
-                 self.relatedTarget = (self.fromElement === self.target) ? self.toElement : self.fromElement;
 
-             }
 
-             // calculate pageX/Y if missing and clientX/Y available
 
-             if (self.pageX === undefined && self.clientX !== undefined) {
 
-                 var docEl = ownerDoc.documentElement, bd = ownerDoc.body;
 
-                 self.pageX = self.clientX + (docEl && docEl.scrollLeft || bd && bd.scrollLeft || 0) - (docEl && docEl.clientLeft || bd && bd.clientLeft || 0);
 
-                 self.pageY = self.clientY + (docEl && docEl.scrollTop || bd && bd.scrollTop || 0) - (docEl && docEl.clientTop || bd && bd.clientTop || 0);
 
-             }
 
-             // add which for key events
 
-             if (self.which === undefined) {
 
-                 self.which = (self.charCode === undefined) ? self.keyCode : self.charCode;
 
-             }
 
-             // add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
 
-             if (self.metaKey === undefined) {
 
-                 self.metaKey = self.ctrlKey;
 
-             }
 
-             // add which for click: 1 === left; 2 === middle; 3 === right
 
-             // Note: button is not normalized, so don't use it
 
-             if (!self.which && self.button !== undefined) {
 
-                 self.which = (self.button & 1 ? 1 : (self.button & 2 ? 3 : ( self.button & 4 ? 2 : 0)));
 
-             }
 
-         },
 
-         /**
 
-          * Prevents the event's default behavior
 
-          */
 
-         preventDefault: function() {
 
-             var e = this.originalEvent;
 
-             // if preventDefault exists run it on the original event
 
-             if (e.preventDefault) {
 
-                 e.preventDefault();
 
-             }
 
-             // otherwise set the returnValue property of the original event to false (IE)
 
-             else {
 
-                 e.returnValue = false;
 
-             }
 
-             this.isDefaultPrevented = true;
 
-         },
 
-         /**
 
-          * Stops the propagation to the next bubble target
 
-          */
 
-         stopPropagation: function() {
 
-             var e = this.originalEvent;
 
-             // if stopPropagation exists run it on the original event
 
-             if (e.stopPropagation) {
 
-                 e.stopPropagation();
 
-             }
 
-             // otherwise set the cancelBubble property of the original event to true (IE)
 
-             else {
 
-                 e.cancelBubble = true;
 
-             }
 
-             this.isPropagationStopped = true;
 
-         },
 
-         /**
 
-          * Stops the propagation to the next bubble target and
 
-          * prevents any additional listeners from being exectued
 
-          * on the current target.
 
-          */
 
-         stopImmediatePropagation: function() {
 
-             var self = this;
 
-             self.isImmediatePropagationStopped = true;
 
-             // fixed 1.2
 
-             // call stopPropagation implicitly
 
-             self.stopPropagation();
 
-         },
 
-         /**
 
-          * Stops the event propagation and prevents the default
 
-          * event behavior.
 
-          * @param immediate {boolean} if true additional listeners
 
-          * on the current target will not be executed
 
-          */
 
-         halt: function(immediate) {
 
-             if (immediate) {
 
-                 this.stopImmediatePropagation();
 
-             } else {
 
-                 this.stopPropagation();
 
-             }
 
-             this.preventDefault();
 
-         }
 
-     });
 
-     if (1 > 2) {
 
-         alert(S.cancelBubble);
 
-     }
 
-     return EventObject;
 
- });
 
- /**
 
-  * NOTES:
 
-  *
 
-  *  2010.04
 
-  *   - http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
 
-  *
 
-  * TODO:
 
-  *   - pageX, clientX, scrollLeft, clientLeft 的详细测试
 
-  */
 
- /**
 
-  * utils for event
 
-  * @author yiminghe@gmail.com
 
-  */
 
- KISSY.add("event/utils", function(S, DOM) {
 
-     /**
 
-      * whether two event listens are the same
 
-      * @param h1 已有的 handler 描述
 
-      * @param h2 用户提供的 handler 描述
 
-      */
 
-     function isIdenticalHandler(h1, h2, el) {
 
-         var scope1 = h1.scope || el,
 
-             ret = 1,
 
-             d1,
 
-             d2,
 
-             scope2 = h2.scope || el;
 
-         if (h1.fn !== h2.fn
 
-             || scope1 !== scope2) {
 
-             ret = 0;
 
-         } else if ((d1 = h1.data) !== (d2 = h2.data)) {
 
-             // undelgate 不能 remove 普通 on 的 handler
 
-             // remove 不能 remove delegate 的 handler
 
-             if (!d1 && d2
 
-                 || d1 && !d2
 
-                 ) {
 
-                 ret = 0;
 
-             } else if (d1 && d2) {
 
-                 if (!d1.equals || !d2.equals) {
 
-                     S.error("no equals in data");
 
-                 } else if (!d1.equals(d2,el)) {
 
-                     ret = 0;
 
-                 }
 
-             }
 
-         }
 
-         return ret;
 
-     }
 
-     function isValidTarget(target) {
 
-         // 3 - is text node
 
-         // 8 - is comment node
 
-         return target &&
 
-             target.nodeType !== DOM.TEXT_NODE &&
 
-             target.nodeType !== DOM.COMMENT_NODE;
 
-     }
 
-     function batchForType(obj, methodName, targets, types) {
 
-         // on(target, 'click focus', fn)
 
-         if (types && types.indexOf(" ") > 0) {
 
-             var args = S.makeArray(arguments);
 
-             S.each(types.split(/\s+/), function(type) {
 
-                 var args2 = [].concat(args);
 
-                 args2.splice(0, 4, targets, type);
 
-                 obj[methodName].apply(obj, args2);
 
-             });
 
-             return true;
 
-         }
 
-         return 0;
 
-     }
 
-     function splitAndRun(type, fn) {
 
-         S.each(type.split(/\s+/), fn);
 
-     }
 
-     var doc = document,
 
-         simpleAdd = doc.addEventListener ?
 
-             function(el, type, fn, capture) {
 
-                 if (el.addEventListener) {
 
-                     el.addEventListener(type, fn, !!capture);
 
-                 }
 
-             } :
 
-             function(el, type, fn) {
 
-                 if (el.attachEvent) {
 
-                     el.attachEvent('on' + type, fn);
 
-                 }
 
-             },
 
-         simpleRemove = doc.removeEventListener ?
 
-             function(el, type, fn, capture) {
 
-                 if (el.removeEventListener) {
 
-                     el.removeEventListener(type, fn, !!capture);
 
-                 }
 
-             } :
 
-             function(el, type, fn) {
 
-                 if (el.detachEvent) {
 
-                     el.detachEvent('on' + type, fn);
 
-                 }
 
-             };
 
-     return {
 
-         splitAndRun:splitAndRun,
 
-         batchForType:batchForType,
 
-         isValidTarget:isValidTarget,
 
-         isIdenticalHandler:isIdenticalHandler,
 
-         simpleAdd:simpleAdd,
 
-         simpleRemove:simpleRemove
 
-     };
 
- }, {
 
-     requires:['dom']
 
- });
 
- /**
 
-  * scalable event framework for kissy (refer DOM3 Events)
 
-  * @author  yiminghe@gmail.com,lifesinger@gmail.com
 
-  */
 
- KISSY.add('event/base', function(S, DOM, EventObject, Utils, undefined) {
 
-     var isValidTarget = Utils.isValidTarget,
 
-         isIdenticalHandler = Utils.isIdenticalHandler,
 
-         batchForType = Utils.batchForType,
 
-         simpleRemove = Utils.simpleRemove,
 
-         simpleAdd = Utils.simpleAdd,
 
-         splitAndRun = Utils.splitAndRun,
 
-         nodeName = DOM._nodeName,
 
-         makeArray = S.makeArray,
 
-         each = S.each,
 
-         trim = S.trim,
 
-         // 记录手工 fire(domElement,type) 时的 type
 
-         // 再在浏览器通知的系统 eventHandler 中检查
 
-         // 如果相同,那么证明已经 fire 过了,不要再次触发了
 
-         Event_Triggered = "",
 
-         TRIGGERED_NONE = "trigger-none-" + S.now(),
 
-         EVENT_SPECIAL = {},
 
-         // 事件存储位置 key
 
-         // { handler: eventHandler, events:  {type:[{scope:scope,fn:fn}]}  } }
 
-         EVENT_GUID = 'ksEventTargetId' + S.now();
 
-     /**
 
-      * @name Event
 
-      * @namespace
 
-      */
 
-     var Event = {
 
-         _clone:function(src, dest) {
 
-             if (dest.nodeType !== DOM.ELEMENT_NODE ||
 
-                 !Event._hasData(src)) {
 
-                 return;
 
-             }
 
-             var eventDesc = Event._data(src),
 
-                 events = eventDesc.events;
 
-             each(events, function(handlers, type) {
 
-                 each(handlers, function(handler) {
 
-                     // scope undefined 时不能写死在 handlers 中,否则不能保证 clone 时的 this
 
-                     Event.on(dest, type, handler.fn, handler.scope, handler.data);
 
-                 });
 
-             });
 
-         },
 
-         _hasData:function(elem) {
 
-             return DOM.hasData(elem, EVENT_GUID);
 
-         },
 
-         _data:function(elem) {
 
-             var args = makeArray(arguments);
 
-             args.splice(1, 0, EVENT_GUID);
 
-             return DOM.data.apply(DOM, args);
 
-         },
 
-         _removeData:function(elem) {
 
-             var args = makeArray(arguments);
 
-             args.splice(1, 0, EVENT_GUID);
 
-             return DOM.removeData.apply(DOM, args);
 
-         },
 
-         // such as: { 'mouseenter' : { setup:fn ,tearDown:fn} }
 
-         special: EVENT_SPECIAL,
 
-         // single type , single target , fixed native
 
-         __add:function(isNativeTarget, target, type, fn, scope, data) {
 
-             var eventDesc;
 
-             // 不是有效的 target 或 参数不对
 
-             if (!target ||
 
-                 !S.isFunction(fn) ||
 
-                 (isNativeTarget && !isValidTarget(target))) {
 
-                 return;
 
-             }
 
-             // 获取事件描述
 
-             eventDesc = Event._data(target);
 
-             if (!eventDesc) {
 
-                 Event._data(target, eventDesc = {});
 
-             }
 
-             //事件 listeners , similar to eventListeners in DOM3 Events
 
-             var events = eventDesc.events = eventDesc.events || {},
 
-                 handlers = events[type] = events[type] || [],
 
-                 handleObj = {
 
-                     fn: fn,
 
-                     scope: scope,
 
-                     data:data
 
-                 },
 
-                 eventHandler = eventDesc.handler;
 
-             // 该元素没有 handler ,并且该元素是 dom 节点时才需要注册 dom 事件
 
-             if (!eventHandler) {
 
-                 eventHandler = eventDesc.handler = function(event, data) {
 
-                     // 是经过 fire 手动调用而浏览器同步触发导致的,就不要再次触发了,
 
-                     // 已经在 fire 中 bubble 过一次了
 
-                     if (event && event.type == Event_Triggered) {
 
-                         return;
 
-                     }
 
-                     var currentTarget = eventHandler.target;
 
-                     if (!event || !event.fixed) {
 
-                         event = new EventObject(currentTarget, event);
 
-                     }
 
-                     var type = event.type;
 
-                     if (S.isPlainObject(data)) {
 
-                         S.mix(event, data);
 
-                     }
 
-                     // protect type
 
-                     if (type) {
 
-                         event.type = type;
 
-                     }
 
-                     return _handle(currentTarget, event);
 
-                 };
 
-                 // as for native dom event , this represents currentTarget !
 
-                 eventHandler.target = target;
 
-             }
 
-             for (var i = handlers.length - 1; i >= 0; --i) {
 
-                 /**
 
-                  * If multiple identical EventListeners are registered on the same EventTarget
 
-                  * with the same parameters the duplicate instances are discarded.
 
-                  * They do not cause the EventListener to be called twice
 
-                  * and since they are discarded
 
-                  * they do not need to be removed with the removeEventListener method.
 
-                  */
 
-                 if (isIdenticalHandler(handlers[i], handleObj, target)) {
 
-                     return;
 
-                 }
 
-             }
 
-             if (isNativeTarget) {
 
-                 addDomEvent(target, type, eventHandler, handlers, handleObj);
 
-                 //nullify to prevent memory leak in ie ?
 
-                 target = null;
 
-             }
 
-             // 增加 listener
 
-             handlers.push(handleObj);
 
-         },
 
-         /**
 
-          * Adds an event listener.similar to addEventListener in DOM3 Events
 
-          * @param targets KISSY selector
 
-          * @param type {String} The type of event to append.
 
-          * @param fn {Function} The event handler/listener.
 
-          * @param scope {Object} (optional) The scope (this reference) in which the handler function is executed.
 
-          */
 
-         add: function(targets, type, fn, scope /* optional */, data/*internal usage*/) {
 
-             type = trim(type);
 
-             // data : 附加在回调后面的数据,delegate 检查使用
 
-             // remove 时 data 相等(指向同一对象或者定义了 equals 比较函数)
 
-             if (batchForType(Event, 'add', targets, type, fn, scope, data)) {
 
-                 return targets;
 
-             }
 
-             DOM.query(targets).each(function(target) {
 
-                 Event.__add(true, target, type, fn, scope, data);
 
-             });
 
-             return targets;
 
-         },
 
-         // single target, single type, fixed native
 
-         __remove:function(isNativeTarget, target, type, fn, scope, data) {
 
-             if (
 
-                 !target ||
 
-                     (isNativeTarget && !isValidTarget(target))
 
-                 ) {
 
-                 return;
 
-             }
 
-             var eventDesc = Event._data(target),
 
-                 events = eventDesc && eventDesc.events,
 
-                 handlers,
 
-                 len,
 
-                 i,
 
-                 j,
 
-                 t,
 
-                 special = (isNativeTarget && EVENT_SPECIAL[type]) || { };
 
-             if (!events) {
 
-                 return;
 
-             }
 
-             // remove all types of event
 
-             if (!type) {
 
-                 for (type in events) {
 
-                     Event.__remove(isNativeTarget, target, type);
 
-                 }
 
-                 return;
 
-             }
 
-             if ((handlers = events[type])) {
 
-                 len = handlers.length;
 
-                 // 移除 fn
 
-                 if (fn && len) {
 
-                     var currentHandler = {
 
-                         data:data,
 
-                         fn:fn,
 
-                         scope:scope
 
-                     },handler;
 
-                     for (i = 0,j = 0,t = []; i < len; ++i) {
 
-                         handler = handlers[i];
 
-                         // 注意顺序,用户提供的 handler 在第二个参数
 
-                         if (!isIdenticalHandler(handler, currentHandler, target)) {
 
-                             t[j++] = handler;
 
-                         } else if (special.remove) {
 
-                             special.remove.call(target, handler);
 
-                         }
 
-                     }
 
-                     events[type] = t;
 
-                     len = t.length;
 
-                 }
 
-                 // remove(el, type) or fn 已移除光
 
-                 if (fn === undefined || len === 0) {
 
-                     // dom node need to detach handler from dom node
 
-                     if (isNativeTarget &&
 
-                         (!special['tearDown'] ||
 
-                             special['tearDown'].call(target) === false)) {
 
-                         simpleRemove(target, type, eventDesc.handler);
 
-                     }
 
-                     // remove target's single event description
 
-                     delete events[type];
 
-                 }
 
-             }
 
-             // remove target's  all events description
 
-             if (S.isEmptyObject(events)) {
 
-                 eventDesc.handler.target = null;
 
-                 delete eventDesc.handler;
 
-                 delete eventDesc.events;
 
-                 Event._removeData(target);
 
-             }
 
-         },
 
-         /**
 
-          * Detach an event or set of events from an element. similar to removeEventListener in DOM3 Events
 
-          * @param targets KISSY selector
 
-          * @param type {String} The type of event to append.
 
-          * @param fn {Function} The event handler/listener.
 
-          * @param scope {Object} (optional) The scope (this reference) in which the handler function is executed.
 
-          */
 
-         remove: function(targets, type /* optional */, fn /* optional */, scope /* optional */, data/*internal usage*/) {
 
-             type = trim(type);
 
-             if (batchForType(Event, 'remove', targets, type, fn, scope)) {
 
-                 return targets;
 
-             }
 
-             DOM.query(targets).each(function(target) {
 
-                 Event.__remove(true, target, type, fn, scope, data);
 
-             });
 
-             return targets;
 
-         },
 
-         _handle:_handle,
 
-         /**
 
-          * fire event , simulate bubble in browser. similar to dispatchEvent in DOM3 Events
 
-          * @return boolean The return value of fire/dispatchEvent indicates
 
-          *                 whether any of the listeners which handled the event called preventDefault.
 
-          *                 If preventDefault was called the value is false, else the value is true.
 
-          */
 
-         fire: function(targets, eventType, eventData, onlyHandlers) {
 
-             var ret = true;
 
-             eventType = trim(eventType);
 
-             if (eventType.indexOf(" ") > -1) {
 
-                 splitAndRun(eventType, function(t) {
 
-                     ret = Event.fire(targets, t, eventData, onlyHandlers) && ret;
 
-                 });
 
-                 return ret;
 
-             }
 
-             // custom event firing moved to target.js
 
-             eventData = eventData || {};
 
-             // protect event type
 
-             eventData.type = eventType;
 
-             DOM.query(targets).each(function(target) {
 
-                 ret = fireDOMEvent(target, eventType, eventData, onlyHandlers) && ret;
 
-             });
 
-             return ret;
 
-         }
 
-     };
 
-     // for compatibility
 
-     Event['__getListeners'] = getListeners
 
-     // shorthand
 
-     Event.on = Event.add;
 
-     Event.detach = Event.remove;
 
-     function getListeners(target, type) {
 
-         var events = getEvents(target) || {};
 
-         return events[type] || [];
 
-     }
 
-     function _handle(target, event) {
 
-         /* As some listeners may remove themselves from the
 
-          event, the original array length is dynamic. So,
 
-          let's make a copy of all listeners, so we are
 
-          sure we'll call all of them.*/
 
-         /**
 
-          * DOM3 Events: EventListenerList objects in the DOM are live. ??
 
-          */
 
-         var listeners = getListeners(target, event.type).slice(0),
 
-             ret,
 
-             gRet,
 
-             i = 0,
 
-             len = listeners.length,
 
-             listener;
 
-         for (; i < len; ++i) {
 
-             listener = listeners[i];
 
-             // 传入附件参数data,目前用于委托
 
-             // scope undefined 时不能写死在 listener 中,否则不能保证 clone 时的 this
 
-             ret = listener.fn.call(listener.scope || target,
 
-                 event, listener.data);
 
-             // 和 jQuery 逻辑保持一致
 
-             if (ret !== undefined) {
 
-                 // 有一个 false,最终结果就是 false
 
-                 // 否则等于最后一个返回值
 
-                 if (gRet !== false) {
 
-                     gRet = ret;
 
-                 }
 
-                 // return false 等价 preventDefault + stopProgation
 
-                 if (ret === false) {
 
-                     event.halt();
 
-                 }
 
-             }
 
-             if (event.isImmediatePropagationStopped) {
 
-                 break;
 
-             }
 
-         }
 
-         // fire 时判断如果 preventDefault,则返回 false 否则返回 true
 
-         // 这里返回值意义不同
 
-         return gRet;
 
-     }
 
-     function getEvents(target) {
 
-         // 获取事件描述
 
-         var eventDesc = Event._data(target);
 
-         return eventDesc && eventDesc.events;
 
-     }
 
-     /**
 
-      * dom node need eventHandler attached to dom node
 
-      */
 
-     function addDomEvent(target, type, eventHandler, handlers, handleObj) {
 
-         var special = EVENT_SPECIAL[type] || {};
 
-         // 第一次注册该事件,dom 节点才需要注册 dom 事件
 
-         if (!handlers.length &&
 
-             (!special.setup || special.setup.call(target) === false)) {
 
-             simpleAdd(target, type, eventHandler)
 
-         }
 
-         if (special.add) {
 
-             special.add.call(target, handleObj);
 
-         }
 
-     }
 
-     /**
 
-      * fire dom event from bottom to up , emulate dispatchEvent in DOM3 Events
 
-      * @return boolean The return value of dispatchEvent indicates
 
-      *                 whether any of the listeners which handled the event called preventDefault.
 
-      *                 If preventDefault was called the value is false, else the value is true.
 
-      */
 
-     function fireDOMEvent(target, eventType, eventData, onlyHandlers) {
 
-         if (!isValidTarget(target)) {
 
-             return false;
 
-         }
 
-         var event,
 
-             ret = true;
 
-         if (eventData instanceof EventObject) {
 
-             event = eventData;
 
-         } else {
 
-             event = new EventObject(target, undefined, eventType);
 
-             S.mix(event, eventData);
 
-         }
 
-         /*
 
-          The target of the event is the EventTarget on which dispatchEvent is called.
 
-          */
 
-         // TODO: protect target , but incompatible
 
-         // event.target=target;
 
-         // protect type
 
-         event.type = eventType;
 
-         // 只运行自己的绑定函数,不冒泡也不触发默认行为
 
-         if (onlyHandlers) {
 
-             event.halt();
 
-         }
 
-         var cur = target,
 
-             ontype = "on" + eventType;
 
-         //bubble up dom tree
 
-         do{
 
-             event.currentTarget = cur;
 
-             _handle(cur, event);
 
-             // Trigger an inline bound script
 
-             if (cur[ ontype ] &&
 
-                 cur[ ontype ].call(cur) === false) {
 
-                 event.preventDefault();
 
-             }
 
-             // Bubble up to document, then to window
 
-             cur = cur.parentNode ||
 
-                 cur.ownerDocument ||
 
-                 cur === target.ownerDocument && window;
 
-         } while (cur && !event.isPropagationStopped);
 
-         if (!event.isDefaultPrevented) {
 
-             if (!(eventType === "click" &&
 
-                 nodeName(target, "a"))) {
 
-                 var old;
 
-                 try {
 
-                     if (ontype && target[ eventType ]) {
 
-                         // Don't re-trigger an onFOO event when we call its FOO() method
 
-                         old = target[ ontype ];
 
-                         if (old) {
 
-                             target[ ontype ] = null;
 
-                         }
 
-                         // 记录当前 trigger 触发
 
-                         Event_Triggered = eventType;
 
-                         // 只触发默认事件,而不要执行绑定的用户回调
 
-                         // 同步触发
 
-                         target[ eventType ]();
 
-                     }
 
-                 } catch (ieError) {
 
-                     S.log("trigger action error : ");
 
-                     S.log(ieError);
 
-                 }
 
-                 if (old) {
 
-                     target[ ontype ] = old;
 
-                 }
 
-                 Event_Triggered = TRIGGERED_NONE;
 
-             }
 
-         } else {
 
-             ret = false;
 
-         }
 
-         return ret;
 
-     }
 
-     return Event;
 
- }, {
 
-     requires:["dom","./object","./utils"]
 
- });
 
- /**
 
-  * 2011-11-24
 
-  *  - 自定义事件和 dom 事件操作彻底分离
 
-  *  - TODO: group event from DOM3 Event
 
-  *
 
-  * 2011-06-07
 
-  *  - refer : http://www.w3.org/TR/2001/WD-DOM-Level-3-Events-20010823/events.html
 
-  *  - 重构
 
-  *  - eventHandler 一个元素一个而不是一个元素一个事件一个,节省内存
 
-  *  - 减少闭包使用,prevent ie 内存泄露?
 
-  *  - 增加 fire ,模拟冒泡处理 dom 事件
 
-  */
 
- /**
 
-  * @module  EventTarget
 
-  * @author  yiminghe@gmail.com
 
-  */
 
- KISSY.add('event/target', function(S, Event, EventObject, Utils, undefined) {
 
-     var KS_PUBLISH = "__~ks_publish",
 
-         trim = S.trim,
 
-         splitAndRun = Utils.splitAndRun,
 
-         KS_BUBBLE_TARGETS = "__~ks_bubble_targets",
 
-         ALL_EVENT = "*";
 
-     function getCustomEvent(self, type, eventData) {
 
-         if (eventData instanceof EventObject) {
 
-             // set currentTarget in the process of bubbling
 
-             eventData.currentTarget = self;
 
-             return eventData;
 
-         }
 
-         var customEvent = new EventObject(self, undefined, type);
 
-         if (S.isPlainObject(eventData)) {
 
-             S.mix(customEvent, eventData);
 
-         }
 
-         // protect type
 
-         customEvent.type = type;
 
-         return customEvent
 
-     }
 
-     function getEventPublishObj(self) {
 
-         self[KS_PUBLISH] = self[KS_PUBLISH] || {};
 
-         return self[KS_PUBLISH];
 
-     }
 
-     function getBubbleTargetsObj(self) {
 
-         self[KS_BUBBLE_TARGETS] = self[KS_BUBBLE_TARGETS] || {};
 
-         return self[KS_BUBBLE_TARGETS];
 
-     }
 
-     function isBubblable(self, eventType) {
 
-         var publish = getEventPublishObj(self);
 
-         return publish[eventType] && publish[eventType].bubbles || publish[ALL_EVENT] && publish[ALL_EVENT].bubbles
 
-     }
 
-     function attach(method) {
 
-         return function(type, fn, scope) {
 
-             var self = this;
 
-             type = trim(type);
 
-             splitAndRun(type, function(t) {
 
-                 Event["__" + method](false, self, t, fn, scope);
 
-             });
 
-             return self; // chain
 
-         };
 
-     }
 
-     /**
 
-      * 提供事件发布和订阅机制
 
-      * @name Target
 
-      * @memberOf Event
 
-      */
 
-     var Target =
 
-     /**
 
-      * @lends Event.Target
 
-      */
 
-     {
 
-         /**
 
-          * 触发事件
 
-          * @param {String} type 事件名
 
-          * @param {Object} eventData 事件附加信息对象
 
-          * @returns 如果一个 listener 返回false,则返回 false ,否则返回最后一个 listener 的值.
 
-          */
 
-         fire: function(type, eventData) {
 
-             var self = this,
 
-                 ret,
 
-                 r2,
 
-                 customEvent;
 
-             type = trim(type);
 
-             if (type.indexOf(" ") > 0) {
 
-                 splitAndRun(type, function(t) {
 
-                     r2 = self.fire(t, eventData);
 
-                     if (r2 === false) {
 
-                         ret = false;
 
-                     }
 
-                 });
 
-                 return ret;
 
-             }
 
-             customEvent = getCustomEvent(self, type, eventData);
 
-             ret = Event._handle(self, customEvent);
 
-             if (!customEvent.isPropagationStopped &&
 
-                 isBubblable(self, type)) {
 
-                 r2 = self.bubble(type, customEvent);
 
-                 // false 优先返回
 
-                 if (ret !== false) {
 
-                     ret = r2;
 
-                 }
 
-             }
 
-             return ret
 
-         },
 
-         /**
 
-          * defined event config
 
-          * @param type
 
-          * @param cfg
 
-          *        example { bubbles: true}
 
-          *        default bubbles: false
 
-          */
 
-         publish: function(type, cfg) {
 
-             var self = this,
 
-                 publish = getEventPublishObj(self);
 
-             type = trim(type);
 
-             if (type) {
 
-                 publish[type] = cfg;
 
-             }
 
-         },
 
-         /**
 
-          * bubble event to its targets
 
-          * @param type
 
-          * @param eventData
 
-          */
 
-         bubble: function(type, eventData) {
 
-             var self = this,
 
-                 ret,
 
-                 targets = getBubbleTargetsObj(self);
 
-             S.each(targets, function(t) {
 
-                 var r2 = t.fire(type, eventData);
 
-                 if (ret !== false) {
 
-                     ret = r2;
 
-                 }
 
-             });
 
-             return ret;
 
-         },
 
-         /**
 
-          * add target which bubblable event bubbles towards
 
-          * @param target another EventTarget instance
 
-          */
 
-         addTarget: function(target) {
 
-             var self = this,
 
-                 targets = getBubbleTargetsObj(self);
 
-             targets[S.stamp(target)] = target;
 
-         },
 
-         removeTarget:function(target) {
 
-             var self = this,
 
-                 targets = getBubbleTargetsObj(self);
 
-             delete targets[S.stamp(target)];
 
-         },
 
-         /**
 
-          * 监听事件
 
-          * @param {String} type 事件名
 
-          * @param {Function} fn 事件处理器
 
-          * @param {Object} scope 事件处理器内的 this 值,默认当前实例
 
-          * @returns 当前实例
 
-          */
 
-         on: attach("add")
 
-     };
 
-     /**
 
-      * 取消监听事件
 
-      * @param {String} type 事件名
 
-      * @param {Function} fn 事件处理器
 
-      * @param {Object} scope 事件处理器内的 this 值,默认当前实例
 
-      * @returns 当前实例
 
-      */
 
-     Target.detach = attach("remove");
 
-     return Target;
 
- }, {
 
-     /*
 
-      实际上只需要 dom/data ,但是不要跨模块引用另一模块的子模块,
 
-      否则会导致build打包文件 dom 和 dom-data 重复载入
 
-      */
 
-     requires:["./base",'./object','./utils']
 
- });
 
- /**
 
-  *  yiminghe:2011-10-17
 
-  *   - implement bubble for custom event
 
-  **/
 
- /**
 
-  * @module  event-focusin
 
-  * @author  yiminghe@gmail.com
 
-  */
 
- KISSY.add('event/focusin', function(S, UA, Event) {
 
-     // 让非 IE 浏览器支持 focusin/focusout
 
-     if (!UA['ie']) {
 
-         S.each([
 
-             { name: 'focusin', fix: 'focus' },
 
-             { name: 'focusout', fix: 'blur' }
 
-         ], function(o) {
 
-             var attaches = 0;
 
-             Event.special[o.name] = {
 
-                 // 统一在 document 上 capture focus/blur 事件,然后模拟冒泡 fire 出来
 
-                 // 达到和 focusin 一样的效果 focusin -> focus
 
-                 // refer: http://yiminghe.iteye.com/blog/813255
 
-                 setup: function() {
 
-                     if (attaches++ === 0) {
 
-                         document.addEventListener(o.fix, handler, true);
 
-                     }
 
-                 },
 
-                 tearDown:function() {
 
-                     if (--attaches === 0) {
 
-                         document.removeEventListener(o.fix, handler, true);
 
-                     }
 
-                 }
 
-             };
 
-             function handler(event) {
 
-                 var target = event.target;
 
-                 return Event.fire(target, o.name);
 
-             }
 
-         });
 
-     }
 
-     return Event;
 
- }, {
 
-     requires:["ua","./base"]
 
- });
 
- /**
 
-  * 承玉:2011-06-07
 
-  * - refactor to jquery , 更加合理的模拟冒泡顺序,子元素先出触发,父元素后触发
 
-  *
 
-  * NOTES:
 
-  *  - webkit 和 opera 已支持 DOMFocusIn/DOMFocusOut 事件,但上面的写法已经能达到预期效果,暂时不考虑原生支持。
 
-  */
 
- /**
 
-  * @module  event-hashchange
 
-  * @author  yiminghe@gmail.com , xiaomacji@gmail.com
 
-  */
 
- KISSY.add('event/hashchange', function(S, Event, DOM, UA) {
 
-     var doc = document,
 
-         docMode = doc['documentMode'],
 
-         ie = docMode || UA['ie'],
 
-         HASH_CHANGE = 'hashchange';
 
-     // ie8 支持 hashchange
 
-     // 但IE8以上切换浏览器模式到IE7(兼容模式),会导致 'onhashchange' in window === true,但是不触发事件
 
-     // 1. 不支持 hashchange 事件,支持 hash 导航(opera??):定时器监控
 
-     // 2. 不支持 hashchange 事件,不支持 hash 导航(ie67) : iframe + 定时器
 
-     if ((!( 'on' + HASH_CHANGE in window)) || ie && ie < 8) {
 
-         function getIframeDoc(iframe) {
 
-             return iframe.contentWindow.document;
 
-         }
 
-         var POLL_INTERVAL = 50,
 
-             win = window,
 
-             IFRAME_TEMPLATE = "<html><head><title>" + (doc.title || "") +
 
-                 " - {hash}</title>{head}</head><body>{hash}</body></html>",
 
-             getHash = function() {
 
-                 // 不能 location.hash
 
-                 // http://xx.com/#yy?z=1
 
-                 // ie6 => location.hash = #yy
 
-                 // 其他浏览器 => location.hash = #yy?z=1
 
-                 var url = location.href;
 
-                 return '#' + url.replace(/^[^#]*#?(.*)$/, '$1');
 
-             },
 
-             timer,
 
-             // 用于定时器检测,上次定时器记录的 hash 值
 
-             lastHash,
 
-             poll = function () {
 
-                 var hash = getHash();
 
-                 if (hash !== lastHash) {
 
-                     // S.log("poll success :" + hash + " :" + lastHash);
 
-                     // 通知完调用者 hashchange 事件前设置 lastHash
 
-                     lastHash = hash;
 
-                     // ie<8 同步 : hashChange -> onIframeLoad
 
-                     hashChange(hash);
 
-                 }
 
-                 timer = setTimeout(poll, POLL_INTERVAL);
 
-             },
 
-             hashChange = ie && ie < 8 ? function(hash) {
 
-                 // S.log("set iframe html :" + hash);
 
-                 var html = S.substitute(IFRAME_TEMPLATE, {
 
-                     hash: hash,
 
-                     // 一定要加哦
 
-                     head:DOM._isCustomDomain() ? "<script>document.domain = '" +
 
-                         doc.domain
 
-                         + "';</script>" : ""
 
-                 }),
 
-                     iframeDoc = getIframeDoc(iframe);
 
-                 try {
 
-                     // 写入历史 hash
 
-                     iframeDoc.open();
 
-                     // 取时要用 innerText !!
 
-                     // 否则取 innerHtml 会因为 escapeHtml 导置 body.innerHTMl != hash
 
-                     iframeDoc.write(html);
 
-                     iframeDoc.close();
 
-                     // 立刻同步调用 onIframeLoad !!!!
 
-                 } catch (e) {
 
-                     // S.log('doc write error : ', 'error');
 
-                     // S.log(e, 'error');
 
-                 }
 
-             } : function () {
 
-                 notifyHashChange();
 
-             },
 
-             notifyHashChange = function () {
 
-                 // S.log("hash changed : " + getHash());
 
-                 Event.fire(win, HASH_CHANGE);
 
-             },
 
-             setup = function () {
 
-                 if (!timer) {
 
-                     poll();
 
-                 }
 
-             },
 
-             tearDown = function () {
 
-                 timer && clearTimeout(timer);
 
-                 timer = 0;
 
-             },
 
-             iframe;
 
-         // ie6, 7, 覆盖一些function
 
-         if (ie < 8) {
 
-             /**
 
-              * 前进后退 : start -> notifyHashChange
 
-              * 直接输入 : poll -> hashChange -> start
 
-              * iframe 内容和 url 同步
 
-              */
 
-             setup = function() {
 
-                 if (!iframe) {
 
-                     var iframeSrc = DOM._genEmptyIframeSrc();
 
-                     //http://www.paciellogroup.com/blog/?p=604
 
-                     iframe = DOM.create('<iframe ' +
 
-                         (iframeSrc ? 'src="' + iframeSrc + '"' : '') +
 
-                         ' style="display: none" ' +
 
-                         'height="0" ' +
 
-                         'width="0" ' +
 
-                         'tabindex="-1" ' +
 
-                         'title="empty"/>');
 
-                     // Append the iframe to the documentElement rather than the body.
 
-                     // Keeping it outside the body prevents scrolling on the initial
 
-                     // page load
 
-                     DOM.prepend(iframe, doc.documentElement);
 
-                     // init,第一次触发,以后都是 onIframeLoad
 
-                     Event.add(iframe, "load", function() {
 
-                         Event.remove(iframe, "load");
 
-                         // Update the iframe with the initial location hash, if any. This
 
-                         // will create an initial history entry that the user can return to
 
-                         // after the state has changed.
 
-                         hashChange(getHash());
 
-                         Event.add(iframe, "load", onIframeLoad);
 
-                         poll();
 
-                     });
 
-                     // Whenever `document.title` changes, update the Iframe's title to
 
-                     // prettify the back/next history menu entries. Since IE sometimes
 
-                     // errors with "Unspecified error" the very first time this is set
 
-                     // (yes, very useful) wrap this with a try/catch block.
 
-                     doc.onpropertychange = function() {
 
-                         try {
 
-                             if (event.propertyName === 'title') {
 
-                                 getIframeDoc(iframe).title =
 
-                                     doc.title + " - " + getHash();
 
-                             }
 
-                         } catch(e) {
 
-                         }
 
-                     };
 
-                     /**
 
-                      * 前进后退 : onIframeLoad -> 触发
 
-                      * 直接输入 : timer -> hashChange -> onIframeLoad -> 触发
 
-                      * 触发统一在 start(load)
 
-                      * iframe 内容和 url 同步
 
-                      */
 
-                     function onIframeLoad() {
 
-                         // S.log('iframe start load..');
 
-                        
 
-                         // 2011.11.02 note: 不能用 innerHtml 会自动转义!!
 
-                         // #/x?z=1&y=2 => #/x?z=1&y=2
 
-                         var c = S.trim(getIframeDoc(iframe).body.innerText),
 
-                             ch = getHash();
 
-                         // 后退时不等
 
-                         // 定时器调用 hashChange() 修改 iframe 同步调用过来的(手动改变 location)则相等
 
-                         if (c != ch) {
 
-                             S.log("set loc hash :" + c);
 
-                             location.hash = c;
 
-                             // 使lasthash为 iframe 历史, 不然重新写iframe,
 
-                             // 会导致最新状态(丢失前进状态)
 
-                             // 后退则立即触发 hashchange,
 
-                             // 并更新定时器记录的上个 hash 值
 
-                             lastHash = c;
 
-                         }
 
-                         notifyHashChange();
 
-                     }
 
-                 }
 
-             };
 
-             tearDown = function() {
 
-                 timer && clearTimeout(timer);
 
-                 timer = 0;
 
-                 Event.detach(iframe);
 
-                 DOM.remove(iframe);
 
-                 iframe = 0;
 
-             };
 
-         }
 
-         Event.special[HASH_CHANGE] = {
 
-             setup: function() {
 
-                 if (this !== win) {
 
-                     return;
 
-                 }
 
-                 // 第一次启动 hashchange 时取一下,不能类库载入后立即取
 
-                 // 防止类库嵌入后,手动修改过 hash,
 
-                 lastHash = getHash();
 
-                 // 不用注册 dom 事件
 
-                 setup();
 
-             },
 
-             tearDown: function() {
 
-                 if (this !== win) {
 
-                     return;
 
-                 }
 
-                 tearDown();
 
-             }
 
-         };
 
-     }
 
- }, {
 
-     requires:["./base","dom","ua"]
 
- });
 
- /**
 
-  * 已知 bug :
 
-  * - ie67 有时后退后取得的 location.hash 不和地址栏一致,导致必须后退两次才能触发 hashchange
 
-  *
 
-  * v1 : 2010-12-29
 
-  * v1.1: 支持非IE,但不支持onhashchange事件的浏览器(例如低版本的firefox、safari)
 
-  * refer : http://yiminghe.javaeye.com/blog/377867
 
-  *         https://github.com/cowboy/jquery-hashchange
 
-  */
 
- /**
 
-  * inspired by yui3 :
 
-  *
 
-  * Synthetic event that fires when the <code>value</code> property of an input
 
-  * field or textarea changes as a result of a keystroke, mouse operation, or
 
-  * input method editor (IME) input event.
 
-  *
 
-  * Unlike the <code>onchange</code> event, this event fires when the value
 
-  * actually changes and not when the element loses focus. This event also
 
-  * reports IME and multi-stroke input more reliably than <code>oninput</code> or
 
-  * the various key events across browsers.
 
-  *
 
-  * @author yiminghe@gmail.com
 
-  */
 
- KISSY.add('event/valuechange', function (S, Event, DOM) {
 
-     var VALUE_CHANGE = "valuechange",
 
-         nodeName = DOM._nodeName,
 
-         KEY = "event/valuechange",
 
-         HISTORY_KEY = KEY + "/history",
 
-         POLL_KEY = KEY + "/poll",
 
-         interval = 50;
 
-     function stopPoll(target) {
 
-         DOM.removeData(target, HISTORY_KEY);
 
-         if (DOM.hasData(target, POLL_KEY)) {
 
-             var poll = DOM.data(target, POLL_KEY);
 
-             clearTimeout(poll);
 
-             DOM.removeData(target, POLL_KEY);
 
-         }
 
-     }
 
-     function stopPollHandler(ev) {
 
-         var target = ev.target;
 
-         stopPoll(target);
 
-     }
 
-     function startPoll(target) {
 
-         if (DOM.hasData(target, POLL_KEY)) return;
 
-         DOM.data(target, POLL_KEY, setTimeout(function () {
 
-             var v = target.value, h = DOM.data(target, HISTORY_KEY);
 
-             if (v !== h) {
 
-                 // 只触发自己绑定的 handler
 
-                 Event.fire(target, VALUE_CHANGE, {
 
-                     prevVal:h,
 
-                     newVal:v
 
-                 }, true);
 
-                 DOM.data(target, HISTORY_KEY, v);
 
-             }
 
-             DOM.data(target, POLL_KEY, setTimeout(arguments.callee, interval));
 
-         }, interval));
 
-     }
 
-     function startPollHandler(ev) {
 
-         var target = ev.target;
 
-         // when focus ,record its current value immediately
 
-         if (ev.type == "focus") {
 
-             DOM.data(target, HISTORY_KEY, target.value);
 
-         }
 
-         startPoll(target);
 
-     }
 
-     function monitor(target) {
 
-         unmonitored(target);
 
-         Event.on(target, "blur", stopPollHandler);
 
-         Event.on(target, "mousedown keyup keydown focus", startPollHandler);
 
-     }
 
-     function unmonitored(target) {
 
-         stopPoll(target);
 
-         Event.remove(target, "blur", stopPollHandler);
 
-         Event.remove(target, "mousedown keyup keydown focus", startPollHandler);
 
-     }
 
-     Event.special[VALUE_CHANGE] = {
 
-         setup:function () {
 
-             var target = this;
 
-             if (nodeName(target, "input")
 
-                 || nodeName(target, "textarea")) {
 
-                 monitor(target);
 
-             }
 
-         },
 
-         tearDown:function () {
 
-             var target = this;
 
-             unmonitored(target);
 
-         }
 
-     };
 
-     return Event;
 
- }, {
 
-     requires:["./base", "dom"]
 
- });
 
- /**
 
-  * kissy delegate for event module
 
-  * @author yiminghe@gmail.com
 
-  */
 
- KISSY.add("event/delegate", function(S, DOM, Event, Utils) {
 
-     var batchForType = Utils.batchForType,
 
-         delegateMap = {
 
-             "focus":{
 
-                 type:"focusin"
 
-             },
 
-             "blur":{
 
-                 type:"focusout"
 
-             },
 
-             "mouseenter":{
 
-                 type:"mouseover",
 
-                 handler:mouseHandler
 
-             },
 
-             "mouseleave":{
 
-                 type:"mouseout",
 
-                 handler:mouseHandler
 
-             }
 
-         };
 
-     S.mix(Event, {
 
-         delegate:function(targets, type, selector, fn, scope) {
 
-             if (batchForType(Event, 'delegate', targets, type, selector, fn, scope)) {
 
-                 return targets;
 
-             }
 
-             DOM.query(targets).each(function(target) {
 
-                 var preType = type,handler = delegateHandler;
 
-                 if (delegateMap[type]) {
 
-                     type = delegateMap[preType].type;
 
-                     handler = delegateMap[preType].handler || handler;
 
-                 }
 
-                 Event.on(target, type, handler, target, {
 
-                     fn:fn,
 
-                     selector:selector,
 
-                     preType:preType,
 
-                     scope:scope,
 
-                     equals:equals
 
-                 });
 
-             });
 
-             return targets;
 
-         },
 
-         undelegate:function(targets, type, selector, fn, scope) {
 
-             if (batchForType(Event, 'undelegate', targets, type, selector, fn, scope)) {
 
-                 return targets;
 
-             }
 
-             DOM.query(targets).each(function(target) {
 
-                 var preType = type,
 
-                     handler = delegateHandler;
 
-                 if (delegateMap[type]) {
 
-                     type = delegateMap[preType].type;
 
-                     handler = delegateMap[preType].handler || handler;
 
-                 }
 
-                 Event.remove(target, type, handler, target, {
 
-                     fn:fn,
 
-                     selector:selector,
 
-                     preType:preType,
 
-                     scope:scope,
 
-                     equals:equals
 
-                 });
 
-             });
 
-             return targets;
 
-         }
 
-     });
 
-     // 比较函数,两个 delegate 描述对象比较
 
-     // 注意顺序: 已有data 和 用户提供的 data 比较
 
-     function equals(d, el) {
 
-         // 用户不提供 fn selector 那么肯定成功
 
-         if (d.fn === undefined && d.selector === undefined) {
 
-             return true;
 
-         }
 
-         // 用户不提供 fn 则只比较 selector
 
-         else if (d.fn === undefined) {
 
-             return this.selector == d.selector;
 
-         } else {
 
-             var scope = this.scope || el,
 
-                 dScope = d.scope || el;
 
-             return this.fn == d.fn && this.selector == d.selector && scope == dScope;
 
-         }
 
-     }
 
-     // 根据 selector ,从事件源得到对应节点
 
-     function delegateHandler(event, data) {
 
-         var delegateTarget = this,
 
-             target = event.target,
 
-             invokeds = DOM.closest(target, [data.selector], delegateTarget);
 
-         // 找到了符合 selector 的元素,可能并不是事件源
 
-         return invokes.call(delegateTarget, invokeds, event, data);
 
-     }
 
-     // mouseenter/leave 特殊处理
 
-     function mouseHandler(event, data) {
 
-         var delegateTarget = this,
 
-             ret,
 
-             target = event.target,
 
-             relatedTarget = event.relatedTarget;
 
-         // 恢复为用户想要的 mouseenter/leave 类型
 
-         event.type = data.preType;
 
-         // mouseenter/leave 不会冒泡,只选择最近一个
 
-         target = DOM.closest(target, data.selector, delegateTarget);
 
-         if (target) {
 
-             if (target !== relatedTarget &&
 
-                 (!relatedTarget || !DOM.contains(target, relatedTarget))
 
-                 ) {
 
-                 var currentTarget = event.currentTarget;
 
-                 event.currentTarget = target;
 
-                 ret = data.fn.call(data.scope || delegateTarget, event);
 
-                 event.currentTarget = currentTarget;
 
-             }
 
-         }
 
-         return ret;
 
-     }
 
-     function invokes(invokeds, event, data) {
 
-         var self = this;
 
-         if (invokeds) {
 
-             // 保护 currentTarget
 
-             // 否则 fire 影响 delegated listener 之后正常的 listener 事件
 
-             var currentTarget = event.currentTarget;
 
-             for (var i = 0; i < invokeds.length; i++) {
 
-                 event.currentTarget = invokeds[i];
 
-                 var ret = data.fn.call(data.scope || self, event);
 
-                 // delegate 的 handler 操作事件和根元素本身操作事件效果一致
 
-                 if (ret === false) {
 
-                     event.halt();
 
-                 }
 
-                 if (event.isPropagationStopped) {
 
-                     break;
 
-                 }
 
-             }
 
-             event.currentTarget = currentTarget;
 
-         }
 
-     }
 
-     return Event;
 
- }, {
 
-     requires:["dom","./base","./utils"]
 
- });
 
- /**
 
-  * focusin/out 的特殊之处 , delegate 只能在容器上注册 focusin/out ,
 
-  * 1.其实非 ie 都是注册 focus capture=true,然后注册到 focusin 对应 handlers
 
-  *   1.1 当 Event.fire("focus"),没有 focus 对应的 handlers 数组,然后调用元素 focus 方法,
 
-  *   focusin.js 调用 Event.fire("focusin") 进而执行 focusin 对应的 handlers 数组
 
-  *   1.2 当调用 Event.fire("focusin"),直接执行 focusin 对应的 handlers 数组,但不会真正聚焦
 
-  *
 
-  * 2.ie 直接注册 focusin , focusin handlers 也有对应用户回调
 
-  *   2.1 当 Event.fire("focus") , 同 1.1
 
-  *   2.2 当 Event.fire("focusin"),直接执行 focusin 对应的 handlers 数组,但不会真正聚焦
 
-  *
 
-  * mouseenter/leave delegate 特殊处理, mouseenter 没有冒泡的概念,只能替换为 mouseover/out
 
-  *
 
-  * form submit 事件 ie<9 不会冒泡
 
-  *
 
-  **/
 
- /**
 
-  * @module  event-mouseenter
 
-  * @author  lifesinger@gmail.com , yiminghe@gmail.com
 
-  */
 
- KISSY.add('event/mouseenter', function(S, Event, DOM, UA) {
 
-     if (!UA['ie']) {
 
-         S.each([
 
-             { name: 'mouseenter', fix: 'mouseover' },
 
-             { name: 'mouseleave', fix: 'mouseout' }
 
-         ], function(o) {
 
-             // 元素内触发的 mouseover/out 不能算 mouseenter/leave
 
-             function withinElement(event) {
 
-                 var self = this,
 
-                     parent = event.relatedTarget;
 
-                 // 设置用户实际注册的事件名,触发该事件所对应的 listener 数组
 
-                 event.type = o.name;
 
-                 // Firefox sometimes assigns relatedTarget a XUL element
 
-                 // which we cannot access the parentNode property of
 
-                 try {
 
-                     // Chrome does something similar, the parentNode property
 
-                     // can be accessed but is null.
 
-                     if (parent && parent !== document && !parent.parentNode) {
 
-                         return;
 
-                     }
 
-                     // 在自身外边就触发
 
-                     if (parent !== self &&
 
-                         // self==document , parent==null
 
-                         (!parent || !DOM.contains(self, parent))
 
-                         ) {
 
-                         // handle event if we actually just moused on to a non sub-element
 
-                         Event._handle(self, event);
 
-                     }
 
-                     // assuming we've left the element since we most likely mousedover a xul element
 
-                 } catch(e) {
 
-                     S.log("withinElement error : ", "error");
 
-                     S.log(e, "error");
 
-                 }
 
-             }
 
-             Event.special[o.name] = {
 
-                 // 第一次 mouseenter 时注册下
 
-                 // 以后都直接放到 listener 数组里, 由 mouseover 读取触发
 
-                 setup: function() {
 
-                     Event.add(this, o.fix, withinElement);
 
-                 },
 
-                 //当 listener 数组为空时,也清掉 mouseover 注册,不再读取
 
-                 tearDown:function() {
 
-                     Event.remove(this, o.fix, withinElement);
 
-                 }
 
-             }
 
-         });
 
-     }
 
-     return Event;
 
- }, {
 
-     requires:["./base","dom","ua"]
 
- });
 
- /**
 
-  * 承玉:2011-06-07
 
-  * - 根据新结构,调整 mouseenter 兼容处理
 
-  * - fire('mouseenter') 可以的,直接执行 mouseenter 的 handlers 用户回调数组
 
-  *
 
-  *
 
-  * TODO:
 
-  *  - ie6 下,原生的 mouseenter/leave 貌似也有 bug, 比如 <div><div /><div /><div /></div>
 
-  *    jQuery 也异常,需要进一步研究
 
-  */
 
- /**
 
-  * patch for ie<9 submit : does not bubble !
 
-  * @author yiminghe@gmail.com
 
-  */
 
- KISSY.add("event/submit", function(S, UA, Event, DOM) {
 
-     var mode = document['documentMode'];
 
-     if (UA['ie'] && (UA['ie'] < 9 || (mode && mode < 9))) {
 
-         var nodeName = DOM._nodeName;
 
-         Event.special['submit'] = {
 
-             setup: function() {
 
-                 var el = this;
 
-                 // form use native
 
-                 if (nodeName(el, "form")) {
 
-                     return false;
 
-                 }
 
-                 // lazy add submit for inside forms
 
-                 // note event order : click/keypress -> submit
 
-                 // keypoint : find the forms
 
-                 Event.on(el, "click keypress", detector);
 
-             },
 
-             tearDown:function() {
 
-                 var el = this;
 
-                 // form use native
 
-                 if (nodeName(el, "form")) {
 
-                     return false;
 
-                 }
 
-                 Event.remove(el, "click keypress", detector);
 
-                 DOM.query("form", el).each(function(form) {
 
-                     if (form.__submit__fix) {
 
-                         form.__submit__fix = 0;
 
-                         Event.remove(form, "submit", submitBubble);
 
-                     }
 
-                 });
 
-             }
 
-         };
 
-         function detector(e) {
 
-             var t = e.target,
 
-                 form = nodeName(t, "input") || nodeName(t, "button") ? t.form : null;
 
-             if (form && !form.__submit__fix) {
 
-                 form.__submit__fix = 1;
 
-                 Event.on(form, "submit", submitBubble);
 
-             }
 
-         }
 
-         function submitBubble(e) {
 
-             var form = this;
 
-             if (form.parentNode) {
 
-                 // simulated bubble for submit
 
-                 // fire from parentNode. if form.on("submit") , this logic is never run!
 
-                 Event.fire(form.parentNode, "submit", e);
 
-             }
 
-         }
 
-     }
 
- }, {
 
-     requires:["ua","./base","dom"]
 
- });
 
- /**
 
-  * modified from jq ,fix submit in ie<9
 
-  **/
 
- /**
 
-  * change bubble and checkbox/radio fix patch for ie<9
 
-  * @author yiminghe@gmail.com
 
-  */
 
- KISSY.add("event/change", function(S, UA, Event, DOM) {
 
-     var mode = document['documentMode'];
 
-     if (UA['ie'] && (UA['ie'] < 9 || (mode && mode < 9))) {
 
-         var rformElems = /^(?:textarea|input|select)$/i;
 
-         function isFormElement(n) {
 
-             return rformElems.test(n.nodeName);
 
-         }
 
-         function isCheckBoxOrRadio(el) {
 
-             var type = el.type;
 
-             return type == "checkbox" || type == "radio";
 
-         }
 
-         Event.special['change'] = {
 
-             setup: function() {
 
-                 var el = this;
 
-                 if (isFormElement(el)) {
 
-                     // checkbox/radio only fires change when blur in ie<9
 
-                     // so use another technique from jquery
 
-                     if (isCheckBoxOrRadio(el)) {
 
-                         // change in ie<9
 
-                         // change = propertychange -> click
 
-                         Event.on(el, "propertychange", propertyChange);
 
-                         Event.on(el, "click", onClick);
 
-                     } else {
 
-                         // other form elements use native , do not bubble
 
-                         return false;
 
-                     }
 
-                 } else {
 
-                     // if bind on parentNode ,lazy bind change event to its form elements
 
-                     // note event order : beforeactivate -> change
 
-                     // note 2: checkbox/radio is exceptional
 
-                     Event.on(el, "beforeactivate", beforeActivate);
 
-                 }
 
-             },
 
-             tearDown:function() {
 
-                 var el = this;
 
-                 if (isFormElement(el)) {
 
-                     if (isCheckBoxOrRadio(el)) {
 
-                         Event.remove(el, "propertychange", propertyChange);
 
-                         Event.remove(el, "click", onClick);
 
-                     } else {
 
-                         return false;
 
-                     }
 
-                 } else {
 
-                     Event.remove(el, "beforeactivate", beforeActivate);
 
-                     DOM.query("textarea,input,select", el).each(function(fel) {
 
-                         if (fel.__changeHandler) {
 
-                             fel.__changeHandler = 0;
 
-                             Event.remove(fel, "change", changeHandler);
 
-                         }
 
-                     });
 
-                 }
 
-             }
 
-         };
 
-         function propertyChange(e) {
 
-             if (e.originalEvent.propertyName == "checked") {
 
-                 this.__changed = 1;
 
-             }
 
-         }
 
-         function onClick(e) {
 
-             if (this.__changed) {
 
-                 this.__changed = 0;
 
-                 // fire from itself
 
-                 Event.fire(this, "change", e);
 
-             }
 
-         }
 
-         function beforeActivate(e) {
 
-             var t = e.target;
 
-             if (isFormElement(t) && !t.__changeHandler) {
 
-                 t.__changeHandler = 1;
 
-                 // lazy bind change
 
-                 Event.on(t, "change", changeHandler);
 
-             }
 
-         }
 
-         function changeHandler(e) {
 
-             var fel = this;
 
-             // checkbox/radio already bubble using another technique
 
-             if (isCheckBoxOrRadio(fel)) {
 
-                 return;
 
-             }
 
-             var p;
 
-             if (p = fel.parentNode) {
 
-                 // fire from parent , itself is handled natively
 
-                 Event.fire(p, "change", e);
 
-             }
 
-         }
 
-     }
 
- }, {
 
-     requires:["ua","./base","dom"]
 
- });
 
- /**
 
-  * normalize mousewheel in gecko
 
-  * @author yiminghe@gmail.com
 
-  */
 
- KISSY.add("event/mousewheel", function(S, Event, UA, Utils, EventObject) {
 
-     var MOUSE_WHEEL = UA.gecko ? 'DOMMouseScroll' : 'mousewheel',
 
-         simpleRemove = Utils.simpleRemove,
 
-         simpleAdd = Utils.simpleAdd,
 
-         mousewheelHandler = "mousewheelHandler";
 
-     function handler(e) {
 
-         var deltaX,
 
-             currentTarget = this,
 
-             deltaY,
 
-             delta,
 
-             detail = e.detail;
 
-         if (e.wheelDelta) {
 
-             delta = e.wheelDelta / 120;
 
-         }
 
-         if (e.detail) {
 
-             // press control e.detail == 1 else e.detail == 3
 
-             delta = -(detail % 3 == 0 ? detail / 3 : detail);
 
-         }
 
-         // Gecko
 
-         if (e.axis !== undefined) {
 
-             if (e.axis === e['HORIZONTAL_AXIS']) {
 
-                 deltaY = 0;
 
-                 deltaX = -1 * delta;
 
-             } else if (e.axis === e['VERTICAL_AXIS']) {
 
-                 deltaX = 0;
 
-                 deltaY = delta;
 
-             }
 
-         }
 
-         // Webkit
 
-         if (e['wheelDeltaY'] !== undefined) {
 
-             deltaY = e['wheelDeltaY'] / 120;
 
-         }
 
-         if (e['wheelDeltaX'] !== undefined) {
 
-             deltaX = -1 * e['wheelDeltaX'] / 120;
 
-         }
 
-         // 默认 deltaY ( ie )
 
-         if (!deltaX && !deltaY) {
 
-             deltaY = delta;
 
-         }
 
-         // can not invoke eventDesc.handler , it will protect type
 
-         // but here in firefox , we want to change type really
 
-         e = new EventObject(currentTarget, e);
 
-         S.mix(e, {
 
-             deltaY:deltaY,
 
-             delta:delta,
 
-             deltaX:deltaX,
 
-             type:'mousewheel'
 
-         });
 
-         return  Event._handle(currentTarget, e);
 
-     }
 
-     Event.special['mousewheel'] = {
 
-         setup: function() {
 
-             var el = this,
 
-                 mousewheelHandler,
 
-                 eventDesc = Event._data(el);
 
-             // solve this in ie
 
-             mousewheelHandler = eventDesc[mousewheelHandler] = S.bind(handler, el);
 
-             simpleAdd(this, MOUSE_WHEEL, mousewheelHandler);
 
-         },
 
-         tearDown:function() {
 
-             var el = this,
 
-                 mousewheelHandler,
 
-                 eventDesc = Event._data(el);
 
-             mousewheelHandler = eventDesc[mousewheelHandler];
 
-             simpleRemove(this, MOUSE_WHEEL, mousewheelHandler);
 
-             delete eventDesc[mousewheelHandler];
 
-         }
 
-     };
 
- }, {
 
-     requires:['./base','ua','./utils','./object']
 
- });
 
- /**
 
-  note:
 
-  not perfect in osx : accelerated scroll
 
-  refer:
 
-  https://github.com/brandonaaron/jquery-mousewheel/blob/master/jquery.mousewheel.js
 
-  http://www.planabc.net/2010/08/12/mousewheel_event_in_javascript/
 
-  http://www.switchonthecode.com/tutorials/javascript-tutorial-the-scroll-wheel
 
-  http://stackoverflow.com/questions/5527601/normalizing-mousewheel-speed-across-browsers/5542105#5542105
 
-  http://www.javascriptkit.com/javatutors/onmousewheel.shtml
 
-  http://www.adomas.org/javascript-mouse-wheel/
 
-  http://plugins.jquery.com/project/mousewheel
 
-  http://www.cnblogs.com/aiyuchen/archive/2011/04/19/2020843.html
 
-  http://www.w3.org/TR/DOM-Level-3-Events/#events-mousewheelevents
 
-  **/
 
- /**
 
-  * KISSY Scalable Event Framework
 
-  * @author yiminghe@gmail.com
 
-  */
 
- KISSY.add("event", function(S, KeyCodes, Event, Target, Object) {
 
-     Event.KeyCodes = KeyCodes;
 
-     Event.Target = Target;
 
-     Event.Object = Object;
 
-     return Event;
 
- }, {
 
-     requires:[
 
-         "event/keycodes",
 
-         "event/base",
 
-         "event/target",
 
-         "event/object",
 
-         "event/focusin",
 
-         "event/hashchange",
 
-         "event/valuechange",
 
-         "event/delegate",
 
-         "event/mouseenter",
 
-         "event/submit",
 
-         "event/change",
 
-         "event/mousewheel"
 
-     ]
 
- });
 
- /**
 
-  * definition for node and nodelist
 
-  * @author yiminghe@gmail.com,lifesinger@gmail.com
 
-  */
 
- KISSY.add("node/base", function(S, DOM, undefined) {
 
-     var AP = Array.prototype,
 
-         makeArray = S.makeArray,
 
-         isNodeList = DOM._isNodeList;
 
-     /**
 
-      * The NodeList class provides a wrapper for manipulating DOM Node.
 
-      * @constructor
 
-      */
 
-     function NodeList(html, props, ownerDocument) {
 
-         var self = this,
 
-             domNode;
 
-         if (!(self instanceof NodeList)) {
 
-             return new NodeList(html, props, ownerDocument);
 
-         }
 
-         // handle NodeList(''), NodeList(null), or NodeList(undefined)
 
-         if (!html) {
 
-             return undefined;
 
-         }
 
-         else if (S.isString(html)) {
 
-             // create from html
 
-             domNode = DOM.create(html, props, ownerDocument);
 
-             // ('<p>1</p><p>2</p>') 转换为 NodeList
 
-             if (domNode.nodeType === DOM.DOCUMENT_FRAGMENT_NODE) { // fragment
 
-                 AP.push.apply(this, makeArray(domNode.childNodes));
 
-                 return undefined;
 
-             }
 
-         }
 
-         else if (S.isArray(html) || isNodeList(html)) {
 
-             AP.push.apply(this, makeArray(html));
 
-             return undefined;
 
-         }
 
-         else {
 
-             // node, document, window
 
-             domNode = html;
 
-         }
 
-         self[0] = domNode;
 
-         self.length = 1;
 
-         return undefined;
 
-     }
 
-     S.augment(NodeList, {
 
-         /**
 
-          * 默认长度为 0
 
-          */
 
-         length: 0,
 
-         item: function(index) {
 
-             var self = this;
 
-             if (S.isNumber(index)) {
 
-                 if (index >= self.length) {
 
-                     return null;
 
-                 } else {
 
-                     return new NodeList(self[index]);
 
-                 }
 
-             } else {
 
-                 return new NodeList(index);
 
-             }
 
-         },
 
-         add:function(selector, context, index) {
 
-             if (S.isNumber(context)) {
 
-                 index = context;
 
-                 context = undefined;
 
-             }
 
-             var list = NodeList.all(selector, context).getDOMNodes(),
 
-                 ret = new NodeList(this);
 
-             if (index === undefined) {
 
-                 AP.push.apply(ret, list);
 
-             } else {
 
-                 var args = [index,0];
 
-                 args.push.apply(args, list);
 
-                 AP.splice.apply(ret, args);
 
-             }
 
-             return ret;
 
-         },
 
-         slice:function(start, end) {
 
-             return new NodeList(AP.slice.call(this, start, end));
 
-         },
 
-         /**
 
-          * Retrieves the DOMNodes.
 
-          */
 
-         getDOMNodes: function() {
 
-             return AP.slice.call(this);
 
-         },
 
-         /**
 
-          * Applies the given function to each Node in the NodeList.
 
-          * @param fn The function to apply. It receives 3 arguments: the current node instance, the node's index, and the NodeList instance
 
-          * @param context An optional context to apply the function with Default context is the current NodeList instance
 
-          */
 
-         each: function(fn, context) {
 
-             var self = this;
 
-             S.each(self, function(n, i) {
 
-                 n = new NodeList(n);
 
-                 return fn.call(context || n, n, i, self);
 
-             });
 
-             return self;
 
-         },
 
-         /**
 
-          * Retrieves the DOMNode.
 
-          */
 
-         getDOMNode: function() {
 
-             return this[0];
 
-         },
 
-         /**
 
-          * stack sub query
 
-          */
 
-         end:function() {
 
-             var self = this;
 
-             return self.__parent || self;
 
-         },
 
-         all:function(selector) {
 
-             var ret,self = this;
 
-             if (self.length > 0) {
 
-                 ret = NodeList.all(selector, self);
 
-             } else {
 
-                 ret = new NodeList();
 
-             }
 
-             ret.__parent = self;
 
-             return ret;
 
-         },
 
-         one:function(selector) {
 
-             var self = this,all = self.all(selector),
 
-                 ret = all.length ? all.slice(0, 1) : null;
 
-             if (ret) {
 
-                 ret.__parent = self;
 
-             }
 
-             return ret;
 
-         }
 
-     });
 
-     S.mix(NodeList, {
 
-         /**
 
-          * 查找位于上下文中并且符合选择器定义的节点列表或根据 html 生成新节点
 
-          * @param {String|HTMLElement[]|NodeList} selector html 字符串或<a href='http://docs.kissyui.com/docs/html/api/core/dom/selector.html'>选择器</a>或节点列表
 
-          * @param {String|Array<HTMLElement>|NodeList|HTMLElement|Document} [context] 上下文定义
 
-          * @returns {NodeList} 节点列表对象
 
-          */
 
-         all:function(selector, context) {
 
-             // are we dealing with html string ?
 
-             // TextNode 仍需要自己 new Node
 
-             if (S.isString(selector)
 
-                 && (selector = S.trim(selector))
 
-                 && selector.length >= 3
 
-                 && S.startsWith(selector, "<")
 
-                 && S.endsWith(selector, ">")
 
-                 ) {
 
-                 if (context) {
 
-                     if (context.getDOMNode) {
 
-                         context = context.getDOMNode();
 
-                     }
 
-                     if (context.ownerDocument) {
 
-                         context = context.ownerDocument;
 
-                     }
 
-                 }
 
-                 return new NodeList(selector, undefined, context);
 
-             }
 
-             return new NodeList(DOM.query(selector, context));
 
-         },
 
-         one:function(selector, context) {
 
-             var all = NodeList.all(selector, context);
 
-             return all.length ? all.slice(0, 1) : null;
 
-         }
 
-     });
 
-     S.mix(NodeList, DOM._NODE_TYPE);
 
-     return NodeList;
 
- }, {
 
-     requires:["dom"]
 
- });
 
- /**
 
-  * Notes:
 
-  * 2011-05-25
 
-  *  - 承玉:参考 jquery,只有一个 NodeList 对象,Node 就是 NodeList 的别名
 
-  *
 
-  *  2010.04
 
-  *   - each 方法传给 fn 的 this, 在 jQuery 里指向原生对象,这样可以避免性能问题。
 
-  *     但从用户角度讲,this 的第一直觉是 $(this), kissy 和 yui3 保持一致,牺牲
 
-  *     性能,以易用为首。
 
-  *   - 有了 each 方法,似乎不再需要 import 所有 dom 方法,意义不大。
 
-  *   - dom 是低级 api, node 是中级 api, 这是分层的一个原因。还有一个原因是,如果
 
-  *     直接在 node 里实现 dom 方法,则不大好将 dom 的方法耦合到 nodelist 里。可
 
-  *     以说,技术成本会制约 api 设计。
 
-  */
 
- /**
 
-  * import methods from DOM to NodeList.prototype
 
-  * @author  yiminghe@gmail.com
 
-  */
 
- KISSY.add('node/attach', function(S, DOM, Event, NodeList, undefined) {
 
-     var NLP = NodeList.prototype,
 
-         makeArray = S.makeArray,
 
-         // DOM 添加到 NP 上的方法
 
-         // if DOM methods return undefined , Node methods need to transform result to itself
 
-         DOM_INCLUDES_NORM = [
 
-             "equals",
 
-             "contains",
 
-             "scrollTop",
 
-             "scrollLeft",
 
-             "height",
 
-             "width",
 
-             "innerHeight",
 
-             "innerWidth",
 
-             "outerHeight",
 
-             "outerWidth",
 
-             "addStyleSheet",
 
-             // "append" will be overridden
 
-             "appendTo",
 
-             // "prepend" will be overridden
 
-             "prependTo",
 
-             "insertBefore",
 
-             "before",
 
-             "after",
 
-             "insertAfter",
 
-             "test",
 
-             "hasClass",
 
-             "addClass",
 
-             "removeClass",
 
-             "replaceClass",
 
-             "toggleClass",
 
-             "removeAttr",
 
-             "hasAttr",
 
-             "hasProp",
 
-             // anim override
 
- //            "show",
 
- //            "hide",
 
- //            "toggle",
 
-             "scrollIntoView",
 
-             "remove",
 
-             "empty",
 
-             "removeData",
 
-             "hasData",
 
-             "unselectable"
 
-         ],
 
-         // if return array ,need transform to nodelist
 
-         DOM_INCLUDES_NORM_NODE_LIST = [
 
-             "filter",
 
-             "first",
 
-             "last",
 
-             "parent",
 
-             "closest",
 
-             "next",
 
-             "prev",
 
-             "clone",
 
-             "siblings",
 
-             "children"
 
-         ],
 
-         // if set return this else if get return true value ,no nodelist transform
 
-         DOM_INCLUDES_NORM_IF = {
 
-             // dom method : set parameter index
 
-             "attr":1,
 
-             "text":0,
 
-             "css":1,
 
-             "style":1,
 
-             "val":0,
 
-             "prop":1,
 
-             "offset":0,
 
-             "html":0,
 
-             "data":1
 
-         },
 
-         // Event 添加到 NP 上的方法
 
-         EVENT_INCLUDES = ["on","detach","fire","delegate","undelegate"];
 
-     function accessNorm(fn, self, args) {
 
-         args.unshift(self);
 
-         var ret = DOM[fn].apply(DOM, args);
 
-         if (ret === undefined) {
 
-             return self;
 
-         }
 
-         return ret;
 
-     }
 
-     function accessNormList(fn, self, args) {
 
-         args.unshift(self);
 
-         var ret = DOM[fn].apply(DOM, args);
 
-         if (ret === undefined) {
 
-             return self;
 
-         }
 
-         else if (ret === null) {
 
-             return null;
 
-         }
 
-         return new NodeList(ret);
 
-     }
 
-     function accessNormIf(fn, self, index, args) {
 
-         // get
 
-         if (args[index] === undefined
 
-             // 并且第一个参数不是对象,否则可能是批量设置写
 
-             && !S.isObject(args[0])) {
 
-             args.unshift(self);
 
-             return DOM[fn].apply(DOM, args);
 
-         }
 
-         // set
 
-         return accessNorm(fn, self, args);
 
-     }
 
-     S.each(DOM_INCLUDES_NORM, function(k) {
 
-         NLP[k] = function() {
 
-             var args = makeArray(arguments);
 
-             return accessNorm(k, this, args);
 
-         };
 
-     });
 
-     S.each(DOM_INCLUDES_NORM_NODE_LIST, function(k) {
 
-         NLP[k] = function() {
 
-             var args = makeArray(arguments);
 
-             return accessNormList(k, this, args);
 
-         };
 
-     });
 
-     S.each(DOM_INCLUDES_NORM_IF, function(index, k) {
 
-         NLP[k] = function() {
 
-             var args = makeArray(arguments);
 
-             return accessNormIf(k, this, index, args);
 
-         };
 
-     });
 
-     S.each(EVENT_INCLUDES, function(k) {
 
-         NLP[k] = function() {
 
-             var self=this,
 
-                 args = makeArray(arguments);
 
-             args.unshift(self);
 
-             Event[k].apply(Event, args);
 
-             return self;
 
-         }
 
-     });
 
- }, {
 
-     requires:["dom","event","./base"]
 
- });
 
- /**
 
-  * 2011-05-24
 
-  *  - 承玉:
 
-  *  - 将 DOM 中的方法包装成 NodeList 方法
 
-  *  - Node 方法调用参数中的 KISSY NodeList 要转换成第一个 HTML Node
 
-  *  - 要注意链式调用,如果 DOM 方法返回 undefined (无返回值),则 NodeList 对应方法返回 this
 
-  *  - 实际上可以完全使用 NodeList 来代替 DOM,不和节点关联的方法如:viewportHeight 等,在 window,document 上调用
 
-  *  - 存在 window/document 虚节点,通过 S.one(window)/new Node(window) ,S.one(document)/new NodeList(document) 获得
 
-  */
 
- /**
 
-  * overrides methods in NodeList.prototype
 
-  * @author yiminghe@gmail.com
 
-  */
 
- KISSY.add("node/override", function(S, DOM, Event, NodeList) {
 
-     /**
 
-      * append(node ,parent) : 参数顺序反过来了
 
-      * appendTo(parent,node) : 才是正常
 
-      *
 
-      */
 
-     S.each(['append', 'prepend','before','after'], function(insertType) {
 
-         NodeList.prototype[insertType] = function(html) {
 
-             var newNode = html,self = this;
 
-             // 创建
 
-             if (S.isString(newNode)) {
 
-                 newNode = DOM.create(newNode);
 
-             }
 
-             if (newNode) {
 
-                 DOM[insertType](newNode, self);
 
-             }
 
-             return self;
 
-         };
 
-     });
 
- }, {
 
-     requires:["dom","event","./base","./attach"]
 
- });
 
- /**
 
-  * 2011-05-24
 
-  * - 承玉:
 
-  * - 重写 NodeList 的某些方法
 
-  * - 添加 one ,all ,从当前 NodeList 往下开始选择节点
 
-  * - 处理 append ,prepend 和 DOM 的参数实际上是反过来的
 
-  * - append/prepend 参数是节点时,如果当前 NodeList 数量 > 1 需要经过 clone,因为同一节点不可能被添加到多个节点中去(NodeList)
 
-  */
 
- /**
 
-  * @module anim-easing
 
-  */
 
- KISSY.add('anim/easing', function() {
 
-     // Based on Easing Equations (c) 2003 Robert Penner, all rights reserved.
 
-     // This work is subject to the terms in http://www.robertpenner.com/easing_terms_of_use.html
 
-     // Preview: http://www.robertpenner.com/easing/easing_demo.html
 
-     /**
 
-      * 和 YUI 的 Easing 相比,S.Easing 进行了归一化处理,参数调整为:
 
-      * @param {Number} t Time value used to compute current value  保留 0 =< t <= 1
 
-      * @param {Number} b Starting value  b = 0
 
-      * @param {Number} c Delta between start and end values  c = 1
 
-      * @param {Number} d Total length of animation d = 1
 
-      */
 
-     var PI = Math.PI,
 
-         pow = Math.pow,
 
-         sin = Math.sin,
 
-         BACK_CONST = 1.70158,
 
-         Easing = {
 
-             swing:function(t) {
 
-                 return ( -Math.cos(t * PI) / 2 ) + 0.5;
 
-             },
 
-             /**
 
-              * Uniform speed between points.
 
-              */
 
-             easeNone: function (t) {
 
-                 return t;
 
-             },
 
-             /**
 
-              * Begins slowly and accelerates towards end. (quadratic)
 
-              */
 
-             easeIn: function (t) {
 
-                 return t * t;
 
-             },
 
-             /**
 
-              * Begins quickly and decelerates towards end.  (quadratic)
 
-              */
 
-             easeOut: function (t) {
 
-                 return ( 2 - t) * t;
 
-             },
 
-             /**
 
-              * Begins slowly and decelerates towards end. (quadratic)
 
-              */
 
-             easeBoth: function (t) {
 
-                 return (t *= 2) < 1 ?
 
-                     .5 * t * t :
 
-                     .5 * (1 - (--t) * (t - 2));
 
-             },
 
-             /**
 
-              * Begins slowly and accelerates towards end. (quartic)
 
-              */
 
-             easeInStrong: function (t) {
 
-                 return t * t * t * t;
 
-             },
 
-             /**
 
-              * Begins quickly and decelerates towards end.  (quartic)
 
-              */
 
-             easeOutStrong: function (t) {
 
-                 return 1 - (--t) * t * t * t;
 
-             },
 
-             /**
 
-              * Begins slowly and decelerates towards end. (quartic)
 
-              */
 
-             easeBothStrong: function (t) {
 
-                 return (t *= 2) < 1 ?
 
-                     .5 * t * t * t * t :
 
-                     .5 * (2 - (t -= 2) * t * t * t);
 
-             },
 
-             /**
 
-              * Snap in elastic effect.
 
-              */
 
-             elasticIn: function (t) {
 
-                 var p = .3, s = p / 4;
 
-                 if (t === 0 || t === 1) return t;
 
-                 return -(pow(2, 10 * (t -= 1)) * sin((t - s) * (2 * PI) / p));
 
-             },
 
-             /**
 
-              * Snap out elastic effect.
 
-              */
 
-             elasticOut: function (t) {
 
-                 var p = .3, s = p / 4;
 
-                 if (t === 0 || t === 1) return t;
 
-                 return pow(2, -10 * t) * sin((t - s) * (2 * PI) / p) + 1;
 
-             },
 
-             /**
 
-              * Snap both elastic effect.
 
-              */
 
-             elasticBoth: function (t) {
 
-                 var p = .45, s = p / 4;
 
-                 if (t === 0 || (t *= 2) === 2) return t;
 
-                 if (t < 1) {
 
-                     return -.5 * (pow(2, 10 * (t -= 1)) *
 
-                         sin((t - s) * (2 * PI) / p));
 
-                 }
 
-                 return pow(2, -10 * (t -= 1)) *
 
-                     sin((t - s) * (2 * PI) / p) * .5 + 1;
 
-             },
 
-             /**
 
-              * Backtracks slightly, then reverses direction and moves to end.
 
-              */
 
-             backIn: function (t) {
 
-                 if (t === 1) t -= .001;
 
-                 return t * t * ((BACK_CONST + 1) * t - BACK_CONST);
 
-             },
 
-             /**
 
-              * Overshoots end, then reverses and comes back to end.
 
-              */
 
-             backOut: function (t) {
 
-                 return (t -= 1) * t * ((BACK_CONST + 1) * t + BACK_CONST) + 1;
 
-             },
 
-             /**
 
-              * Backtracks slightly, then reverses direction, overshoots end,
 
-              * then reverses and comes back to end.
 
-              */
 
-             backBoth: function (t) {
 
-                 if ((t *= 2 ) < 1) {
 
-                     return .5 * (t * t * (((BACK_CONST *= (1.525)) + 1) * t - BACK_CONST));
 
-                 }
 
-                 return .5 * ((t -= 2) * t * (((BACK_CONST *= (1.525)) + 1) * t + BACK_CONST) + 2);
 
-             },
 
-             /**
 
-              * Bounce off of start.
 
-              */
 
-             bounceIn: function (t) {
 
-                 return 1 - Easing.bounceOut(1 - t);
 
-             },
 
-             /**
 
-              * Bounces off end.
 
-              */
 
-             bounceOut: function (t) {
 
-                 var s = 7.5625, r;
 
-                 if (t < (1 / 2.75)) {
 
-                     r = s * t * t;
 
-                 }
 
-                 else if (t < (2 / 2.75)) {
 
-                     r = s * (t -= (1.5 / 2.75)) * t + .75;
 
-                 }
 
-                 else if (t < (2.5 / 2.75)) {
 
-                     r = s * (t -= (2.25 / 2.75)) * t + .9375;
 
-                 }
 
-                 else {
 
-                     r = s * (t -= (2.625 / 2.75)) * t + .984375;
 
-                 }
 
-                 return r;
 
-             },
 
-             /**
 
-              * Bounces off start and end.
 
-              */
 
-             bounceBoth: function (t) {
 
-                 if (t < .5) {
 
-                     return Easing.bounceIn(t * 2) * .5;
 
-                 }
 
-                 return Easing.bounceOut(t * 2 - 1) * .5 + .5;
 
-             }
 
-         };
 
-     Easing.NativeTimeFunction = {
 
-         easeNone: 'linear',
 
-         ease: 'ease',
 
-         easeIn: 'ease-in',
 
-         easeOut: 'ease-out',
 
-         easeBoth: 'ease-in-out',
 
-         // Ref:
 
-         //  1. http://www.w3.org/TR/css3-transitions/#transition-timing-function_tag
 
-         //  2. http://www.robertpenner.com/easing/easing_demo.html
 
-         //  3. assets/cubic-bezier-timing-function.html
 
-         // 注:是模拟值,非精确推导值
 
-         easeInStrong: 'cubic-bezier(0.9, 0.0, 0.9, 0.5)',
 
-         easeOutStrong: 'cubic-bezier(0.1, 0.5, 0.1, 1.0)',
 
-         easeBothStrong: 'cubic-bezier(0.9, 0.0, 0.1, 1.0)'
 
-     };
 
-     return Easing;
 
- });
 
- /**
 
-  * TODO:
 
-  *  - test-easing.html 详细的测试 + 曲线可视化
 
-  *
 
-  * NOTES:
 
-  *  - 综合比较 jQuery UI/scripty2/YUI 的 easing 命名,还是觉得 YUI 的对用户
 
-  *    最友好。因此这次完全照搬 YUI 的 Easing, 只是代码上做了点压缩优化。
 
-  *
 
-  */
 
- /**
 
-  * single timer for the whole anim module
 
-  * @author  yiminghe@gmail.com
 
-  */
 
- KISSY.add("anim/manager", function(S) {
 
-     var stamp = S.stamp;
 
-     return {
 
-         interval:15,
 
-         runnings:{},
 
-         timer:null,
 
-         start:function(anim) {
 
-             var self = this,
 
-                 kv = stamp(anim);
 
-             if (self.runnings[kv]) {
 
-                 return;
 
-             }
 
-             self.runnings[kv] = anim;
 
-             self.startTimer();
 
-         },
 
-         stop:function(anim) {
 
-             this.notRun(anim);
 
-         },
 
-         notRun:function(anim) {
 
-             var self = this,
 
-                 kv = stamp(anim);
 
-             delete self.runnings[kv];
 
-             if (S.isEmptyObject(self.runnings)) {
 
-                 self.stopTimer();
 
-             }
 
-         },
 
-         pause:function(anim) {
 
-             this.notRun(anim);
 
-         },
 
-         resume:function(anim) {
 
-             this.start(anim);
 
-         },
 
-         startTimer:function() {
 
-             var self = this;
 
-             if (!self.timer) {
 
-                 self.timer = setTimeout(function() {
 
-                     if (!self.runFrames()) {
 
-                         self.timer = 0;
 
-                         self.startTimer();
 
-                     } else {
 
-                         self.stopTimer();
 
-                     }
 
-                 }, self.interval);
 
-             }
 
-         },
 
-         stopTimer:function() {
 
-             var self = this,
 
-                 t = self.timer;
 
-             if (t) {
 
-                 clearTimeout(t);
 
-                 self.timer = 0;
 
-             }
 
-         },
 
-         runFrames:function() {
 
-             var self = this,
 
-                 done = 1,
 
-                 runnings = self.runnings;
 
-             for (var r in runnings) {
 
-                 if (runnings.hasOwnProperty(r)) {
 
-                     done = 0;
 
-                     runnings[r]._frame();
 
-                 }
 
-             }
 
-             return done;
 
-         }
 
-     };
 
- });
 
- /**
 
-  * animate on single property
 
-  * @author yiminghe@gmail.com
 
-  */
 
- KISSY.add("anim/fx", function(S, DOM, undefined) {
 
-     /**
 
-      * basic animation about single css property or element attribute
 
-      * @param cfg
 
-      */
 
-     function Fx(cfg) {
 
-         this.load(cfg);
 
-     }
 
-     S.augment(Fx, {
 
-         load:function(cfg) {
 
-             var self = this;
 
-             S.mix(self, cfg);
 
-             self.startTime = S.now();
 
-             self.pos = 0;
 
-             self.unit = self.unit || "";
 
-         },
 
-         frame:function(end) {
 
-             var self = this,
 
-                 endFlag = 0,
 
-                 elapsedTime,
 
-                 t = S.now();
 
-             if (end || t >= self.duration + self.startTime) {
 
-                 self.pos = 1;
 
-                 endFlag = 1;
 
-             } else {
 
-                 elapsedTime = t - self.startTime;
 
-                 self.pos = self.easing(elapsedTime / self.duration);
 
-             }
 
-             self.update();
 
-             return endFlag;
 
-         },
 
-         /**
 
-          * 数值插值函数
 
-          * @param {Number} from 源值
 
-          * @param {Number} to 目的值
 
-          * @param {Number} pos 当前位置,从 easing 得到 0~1
 
-          * @return {Number} 当前值
 
-          */
 
-         interpolate:function (from, to, pos) {
 
-             // 默认只对数字进行 easing
 
-             if (S.isNumber(from) &&
 
-                 S.isNumber(to)) {
 
-                 return (from + (to - from) * pos).toFixed(3);
 
-             } else {
 
-                 return undefined;
 
-             }
 
-         },
 
-         update:function() {
 
-             var self = this,
 
-                 prop = self.prop,
 
-                 elem = self.elem,
 
-                 from = self.from,
 
-                 to = self.to,
 
-                 val = self.interpolate(from, to, self.pos);
 
-             if (val === undefined) {
 
-                 // 插值出错,直接设置为最终值
 
-                 if (!self.finished) {
 
-                     self.finished = 1;
 
-                     DOM.css(elem, prop, to);
 
-                     S.log(self.prop + " update directly ! : " + val + " : " + from + " : " + to);
 
-                 }
 
-             } else {
 
-                 val += self.unit;
 
-                 if (isAttr(elem, prop)) {
 
-                     DOM.attr(elem, prop, val, 1);
 
-                 } else {
 
-                     DOM.css(elem, prop, val);
 
-                 }
 
-             }
 
-         },
 
-         /**
 
-          * current value
 
-          */
 
-         cur:function() {
 
-             var self = this,
 
-                 prop = self.prop,
 
-                 elem = self.elem;
 
-             if (isAttr(elem, prop)) {
 
-                 return DOM.attr(elem, prop, undefined, 1);
 
-             }
 
-             var parsed,
 
-                 r = DOM.css(elem, prop);
 
-             // Empty strings, null, undefined and "auto" are converted to 0,
 
-             // complex values such as "rotate(1rad)" are returned as is,
 
-             // simple values such as "10px" are parsed to Float.
 
-             return isNaN(parsed = parseFloat(r)) ?
 
-                 !r || r === "auto" ? 0 : r
 
-                 : parsed;
 
-         }
 
-     });
 
-     function isAttr(elem, prop) {
 
-         // support scrollTop/Left now!
 
-         if ((!elem.style || elem.style[ prop ] == null) &&
 
-             DOM.attr(elem, prop, undefined, 1) != null) {
 
-             return 1;
 
-         }
 
-         return 0;
 
-     }
 
-     Fx.Factories = {};
 
-     Fx.getFx = function(cfg) {
 
-         var Constructor = Fx.Factories[cfg.prop] || Fx;
 
-         return new Constructor(cfg);
 
-     };
 
-     return Fx;
 
- }, {
 
-     requires:['dom']
 
- });
 
- /**
 
-  * TODO
 
-  * 支持 transform ,ie 使用 matrix
 
-  *  - http://shawphy.com/2011/01/transformation-matrix-in-front-end.html
 
-  *  - http://www.cnblogs.com/winter-cn/archive/2010/12/29/1919266.html
 
-  *  - 标准:http://www.zenelements.com/blog/css3-transform/
 
-  *  - ie: http://www.useragentman.com/IETransformsTranslator/
 
-  *  - wiki: http://en.wikipedia.org/wiki/Transformation_matrix
 
-  *  - jq 插件: http://plugins.jquery.com/project/2d-transform
 
-  **/
 
- /**
 
-  * queue of anim objects
 
-  * @author yiminghe@gmail.com
 
-  */
 
- KISSY.add("anim/queue", function(S, DOM) {
 
-     var /*队列集合容器*/
 
-         queueCollectionKey = S.guid("ks-queue-" + S.now() + "-"),
 
-         /*默认队列*/
 
-         queueKey = S.guid("ks-queue-" + S.now() + "-"),
 
-         // 当前队列是否有动画正在执行
 
-         processing = "...";
 
-     function getQueue(elem, name, readOnly) {
 
-         name = name || queueKey;
 
-         var qu,
 
-             quCollection = DOM.data(elem, queueCollectionKey);
 
-         if (!quCollection && !readOnly) {
 
-             DOM.data(elem, queueCollectionKey, quCollection = {});
 
-         }
 
-         if (quCollection) {
 
-             qu = quCollection[name];
 
-             if (!qu && !readOnly) {
 
-                 qu = quCollection[name] = [];
 
-             }
 
-         }
 
-         return qu;
 
-     }
 
-     function removeQueue(elem, name) {
 
-         name = name || queueKey;
 
-         var quCollection = DOM.data(elem, queueCollectionKey);
 
-         if (quCollection) {
 
-             delete quCollection[name];
 
-         }
 
-         if (S.isEmptyObject(quCollection)) {
 
-             DOM.removeData(elem, queueCollectionKey);
 
-         }
 
-     }
 
-     var q = {
 
-         queueCollectionKey:queueCollectionKey,
 
-         queue:function(anim) {
 
-             var elem = anim.elem,
 
-                 name = anim.config.queue,
 
-                 qu = getQueue(elem, name);
 
-             qu.push(anim);
 
-             if (qu[0] !== processing) {
 
-                 q.dequeue(anim);
 
-             }
 
-             return qu;
 
-         },
 
-         remove:function(anim) {
 
-             var elem = anim.elem,
 
-                 name = anim.config.queue,
 
-                 qu = getQueue(elem, name, 1),index;
 
-             if (qu) {
 
-                 index = S.indexOf(anim, qu);
 
-                 if (index > -1) {
 
-                     qu.splice(index, 1);
 
-                 }
 
-             }
 
-         },
 
-         removeQueues:function(elem) {
 
-             DOM.removeData(elem, queueCollectionKey);
 
-         },
 
-         removeQueue:removeQueue,
 
-         dequeue:function(anim) {
 
-             var elem = anim.elem,
 
-                 name = anim.config.queue,
 
-                 qu = getQueue(elem, name, 1),
 
-                 nextAnim = qu && qu.shift();
 
-             if (nextAnim == processing) {
 
-                 nextAnim = qu.shift();
 
-             }
 
-             if (nextAnim) {
 
-                 qu.unshift(processing);
 
-                 nextAnim._runInternal();
 
-             } else {
 
-                 // remove queue data
 
-                 removeQueue(elem, name);
 
-             }
 
-         }
 
-     };
 
-     return q;
 
- }, {
 
-     requires:['dom']
 
- });
 
- /**
 
-  * animation framework for KISSY
 
-  * @author   yiminghe@gmail.com,lifesinger@gmail.com
 
-  */
 
- KISSY.add('anim/base', function(S, DOM, Event, Easing, UA, AM, Fx, Q) {
 
-     var camelCase = DOM._camelCase,
 
-         _isElementNode = DOM._isElementNode,
 
-         specialVals = ["hide","show","toggle"],
 
-         // shorthand css properties
 
-         SHORT_HANDS = {
 
-             border:[
 
-                 "borderBottomWidth",
 
-                 "borderLeftWidth",
 
-                 'borderRightWidth',
 
-                 // 'borderSpacing', 组合属性?
 
-                 'borderTopWidth'
 
-             ],
 
-             "borderBottom":["borderBottomWidth"],
 
-             "borderLeft":["borderLeftWidth"],
 
-             borderTop:["borderTopWidth"],
 
-             borderRight:["borderRightWidth"],
 
-             font:[
 
-                 'fontSize',
 
-                 'fontWeight'
 
-             ],
 
-             margin:[
 
-                 'marginBottom',
 
-                 'marginLeft',
 
-                 'marginRight',
 
-                 'marginTop'
 
-             ],
 
-             padding:[
 
-                 'paddingBottom',
 
-                 'paddingLeft',
 
-                 'paddingRight',
 
-                 'paddingTop'
 
-             ]
 
-         },
 
-         defaultConfig = {
 
-             duration: 1,
 
-             easing: 'easeNone'
 
-         },
 
-         rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i;
 
-     Anim.SHORT_HANDS = SHORT_HANDS;
 
-     /**
 
-      * get a anim instance associate
 
-      * @param elem 元素或者 window ( window 时只能动画 scrollTop/scrollLeft )
 
-      * @param props
 
-      * @param duration
 
-      * @param easing
 
-      * @param callback
 
-      */
 
-     function Anim(elem, props, duration, easing, callback) {
 
-         var self = this,config;
 
-         // ignore non-exist element
 
-         if (!(elem = DOM.get(elem))) {
 
-             return;
 
-         }
 
-         // factory or constructor
 
-         if (!(self instanceof Anim)) {
 
-             return new Anim(elem, props, duration, easing, callback);
 
-         }
 
-         /**
 
-          * the transition properties
 
-          */
 
-         if (S.isString(props)) {
 
-             props = S.unparam(props, ";", ":");
 
-         } else {
 
-             // clone to prevent collision within multiple instance
 
-             props = S.clone(props);
 
-         }
 
-         /**
 
-          * 驼峰属性名
 
-          */
 
-         for (var prop in props) {
 
-             var camelProp = camelCase(S.trim(prop));
 
-             if (prop != camelProp) {
 
-                 props[camelProp] = props[prop];
 
-                 delete props[prop];
 
-             }
 
-         }
 
-         /**
 
-          * animation config
 
-          */
 
-         if (S.isPlainObject(duration)) {
 
-             config = S.clone(duration);
 
-         } else {
 
-             config = {
 
-                 duration:parseFloat(duration) || undefined,
 
-                 easing:easing,
 
-                 complete:callback
 
-             };
 
-         }
 
-         config = S.merge(defaultConfig, config);
 
-         self.config = config;
 
-         config.duration *= 1000;
 
-         // domEl deprecated!
 
-         self.elem = self['domEl'] = elem;
 
-         self.props = props;
 
-         // 实例属性
 
-         self._backupProps = {};
 
-         self._fxs = {};
 
-         // register callback
 
-         self.on("complete", onComplete);
 
-     }
 
-     function onComplete(e) {
 
-         var self = this,
 
-             _backupProps = self._backupProps,
 
-             config = self.config;
 
-         // only recover after complete anim
 
-         if (!S.isEmptyObject(_backupProps = self._backupProps)) {
 
-             DOM.css(self.elem, _backupProps);
 
-         }
 
-         if (config.complete) {
 
-             config.complete.call(self, e);
 
-         }
 
-     }
 
-     function runInternal() {
 
-         var self = this,
 
-             config = self.config,
 
-             _backupProps = self._backupProps,
 
-             elem = self.elem,
 
-             hidden,
 
-             val,
 
-             prop,
 
-             specialEasing = (config['specialEasing'] || {}),
 
-             fxs = self._fxs,
 
-             props = self.props;
 
-         // 进入该函数即代表执行(q[0] 已经是 ...)
 
-         saveRunning(self);
 
-         if (self.fire("start") === false) {
 
-             // no need to invoke complete
 
-             self.stop(0);
 
-             return;
 
-         }
 
-         if (_isElementNode(elem)) {
 
-             hidden = DOM.css(elem, "display") == "none";
 
-             for (prop in props) {
 
-                 val = props[prop];
 
-                 // 直接结束
 
-                 if (val == "hide" && hidden || val == 'show' && !hidden) {
 
-                     // need to invoke complete
 
-                     self.stop(1);
 
-                     return;
 
-                 }
 
-             }
 
-         }
 
-         // 分离 easing
 
-         S.each(props, function(val, prop) {
 
-             if (!props.hasOwnProperty(prop)) {
 
-                 return;
 
-             }
 
-             var easing;
 
-             if (S.isArray(val)) {
 
-                 easing = specialEasing[prop] = val[1];
 
-                 props[prop] = val[0];
 
-             } else {
 
-                 easing = specialEasing[prop] = (specialEasing[prop] || config.easing);
 
-             }
 
-             if (S.isString(easing)) {
 
-                 easing = specialEasing[prop] = Easing[easing];
 
-             }
 
-             specialEasing[prop] = easing || Easing.easeNone;
 
-         });
 
-         // 扩展分属性
 
-         S.each(SHORT_HANDS, function(shortHands, p) {
 
-             var sh,
 
-                 origin,
 
-                 val;
 
-             if (val = props[p]) {
 
-                 origin = {};
 
-                 S.each(shortHands, function(sh) {
 
-                     // 得到原始分属性之前值
 
-                     origin[sh] = DOM.css(elem, sh);
 
-                     specialEasing[sh] = specialEasing[p];
 
-                 });
 
-                 DOM.css(elem, p, val);
 
-                 for (sh in origin) {
 
-                     // 得到期待的分属性最后值
 
-                     props[sh] = DOM.css(elem, sh);
 
-                     // 还原
 
-                     DOM.css(elem, sh, origin[sh]);
 
-                 }
 
-                 // 删除复合属性
 
-                 delete props[p];
 
-             }
 
-         });
 
-         // 取得单位,并对单个属性构建 Fx 对象
 
-         for (prop in props) {
 
-             if (!props.hasOwnProperty(prop)) {
 
-                 continue;
 
-             }
 
-             val = S.trim(props[prop]);
 
-             var to,
 
-                 from,
 
-                 propCfg = {
 
-                     elem:elem,
 
-                     prop:prop,
 
-                     duration:config.duration,
 
-                     easing:specialEasing[prop]
 
-                 },
 
-                 fx = Fx.getFx(propCfg);
 
-             // hide/show/toggle : special treat!
 
-             if (S.inArray(val, specialVals)) {
 
-                 // backup original value
 
-                 _backupProps[prop] = DOM.style(elem, prop);
 
-                 if (val == "toggle") {
 
-                     val = hidden ? "show" : "hide";
 
-                 }
 
-                 if (val == "hide") {
 
-                     to = 0;
 
-                     from = fx.cur();
 
-                     // 执行完后隐藏
 
-                     _backupProps.display = 'none';
 
-                 } else {
 
-                     from = 0;
 
-                     to = fx.cur();
 
-                     // prevent flash of content
 
-                     DOM.css(elem, prop, from);
 
-                     DOM.show(elem);
 
-                 }
 
-                 val = to;
 
-             } else {
 
-                 to = val;
 
-                 from = fx.cur();
 
-             }
 
-             val += "";
 
-             var unit = "",
 
-                 parts = val.match(rfxnum);
 
-             if (parts) {
 
-                 to = parseFloat(parts[2]);
 
-                 unit = parts[3];
 
-                 // 有单位但单位不是 px
 
-                 if (unit && unit !== "px") {
 
-                     DOM.css(elem, prop, val);
 
-                     from = (to / fx.cur()) * from;
 
-                     DOM.css(elem, prop, from + unit);
 
-                 }
 
-                 // 相对
 
-                 if (parts[1]) {
 
-                     to = ( (parts[ 1 ] === "-=" ? -1 : 1) * to ) + from;
 
-                 }
 
-             }
 
-             propCfg.from = from;
 
-             propCfg.to = to;
 
-             propCfg.unit = unit;
 
-             fx.load(propCfg);
 
-             fxs[prop] = fx;
 
-         }
 
-         if (_isElementNode(elem) &&
 
-             (props.width || props.height)) {
 
-             // Make sure that nothing sneaks out
 
-             // Record all 3 overflow attributes because IE does not
 
-             // change the overflow attribute when overflowX and
 
-             // overflowY are set to the same value
 
-             S.mix(_backupProps, {
 
-                 overflow:DOM.style(elem, "overflow"),
 
-                 "overflow-x":DOM.style(elem, "overflowX"),
 
-                 "overflow-y":DOM.style(elem, "overflowY")
 
-             });
 
-             DOM.css(elem, "overflow", "hidden");
 
-             // inline element should has layout/inline-block
 
-             if (DOM.css(elem, "display") === "inline" &&
 
-                 DOM.css(elem, "float") === "none") {
 
-                 if (UA['ie']) {
 
-                     DOM.css(elem, "zoom", 1);
 
-                 } else {
 
-                     DOM.css(elem, "display", "inline-block");
 
-                 }
 
-             }
 
-         }
 
-         AM.start(self);
 
-     }
 
-     S.augment(Anim, Event.Target, {
 
-         /**
 
-          * @type {boolean} 是否在运行
 
-          */
 
-         isRunning:function() {
 
-             return isRunning(this);
 
-         },
 
-         _runInternal:runInternal,
 
-         /**
 
-          * 开始动画
 
-          */
 
-         run: function() {
 
-             var self = this,
 
-                 queueName = self.config.queue;
 
-             if (queueName === false) {
 
-                 runInternal.call(self);
 
-             } else {
 
-                 // 当前动画对象加入队列
 
-                 Q.queue(self);
 
-             }
 
-             return self;
 
-         },
 
-         _frame:function() {
 
-             var self = this,
 
-                 prop,
 
-                 end = 1,
 
-                 fxs = self._fxs;
 
-             for (prop in fxs) {
 
-                 if (fxs.hasOwnProperty(prop)) {
 
-                     end &= fxs[prop].frame();
 
-                 }
 
-             }
 
-             if ((self.fire("step") === false) ||
 
-                 end) {
 
-                 // complete 事件只在动画到达最后一帧时才触发
 
-                 self.stop(end);
 
-             }
 
-         },
 
-         stop: function(finish) {
 
-             var self = this,
 
-                 config = self.config,
 
-                 queueName = config.queue,
 
-                 prop,
 
-                 fxs = self._fxs;
 
-             // already stopped
 
-             if (!self.isRunning()) {
 
-                 // 从自己的队列中移除
 
-                 if (queueName !== false) {
 
-                     Q.remove(self);
 
-                 }
 
-                 return;
 
-             }
 
-             if (finish) {
 
-                 for (prop in fxs) {
 
-                     if (fxs.hasOwnProperty(prop)) {
 
-                         fxs[prop].frame(1);
 
-                     }
 
-                 }
 
-                 self.fire("complete");
 
-             }
 
-             AM.stop(self);
 
-             removeRunning(self);
 
-             if (queueName !== false) {
 
-                 // notify next anim to run in the same queue
 
-                 Q.dequeue(self);
 
-             }
 
-             return self;
 
-         }
 
-     });
 
-     var runningKey = S.guid("ks-anim-unqueued-" + S.now() + "-");
 
-     function saveRunning(anim) {
 
-         var elem = anim.elem,
 
-             allRunning = DOM.data(elem, runningKey);
 
-         if (!allRunning) {
 
-             DOM.data(elem, runningKey, allRunning = {});
 
-         }
 
-         allRunning[S.stamp(anim)] = anim;
 
-     }
 
-     function removeRunning(anim) {
 
-         var elem = anim.elem,
 
-             allRunning = DOM.data(elem, runningKey);
 
-         if (allRunning) {
 
-             delete allRunning[S.stamp(anim)];
 
-             if (S.isEmptyObject(allRunning)) {
 
-                 DOM.removeData(elem, runningKey);
 
-             }
 
-         }
 
-     }
 
-     function isRunning(anim) {
 
-         var elem = anim.elem,
 
-             allRunning = DOM.data(elem, runningKey);
 
-         if (allRunning) {
 
-             return !!allRunning[S.stamp(anim)];
 
-         }
 
-         return 0;
 
-     }
 
-     /**
 
-      * stop all the anims currently running
 
-      * @param elem element which anim belongs to
 
-      * @param end
 
-      * @param clearQueue
 
-      */
 
-     Anim.stop = function(elem, end, clearQueue, queueName) {
 
-         if (
 
-         // default queue
 
-             queueName === null ||
 
-                 // name of specified queue
 
-                 S.isString(queueName) ||
 
-                 // anims not belong to any queue
 
-                 queueName === false
 
-             ) {
 
-             return stopQueue.apply(undefined, arguments);
 
-         }
 
-         // first stop first anim in queues
 
-         if (clearQueue) {
 
-             Q.removeQueues(elem);
 
-         }
 
-         var allRunning = DOM.data(elem, runningKey),
 
-             // can not stop in for/in , stop will modified allRunning too
 
-             anims = S.merge(allRunning);
 
-         for (var k in anims) {
 
-             anims[k].stop(end);
 
-         }
 
-     };
 
-     /**
 
-      *
 
-      * @param elem element which anim belongs to
 
-      * @param queueName queue'name if set to false only remove
 
-      * @param end
 
-      * @param clearQueue
 
-      */
 
-     function stopQueue(elem, end, clearQueue, queueName) {
 
-         if (clearQueue && queueName !== false) {
 
-             Q.removeQueue(elem, queueName);
 
-         }
 
-         var allRunning = DOM.data(elem, runningKey),
 
-             anims = S.merge(allRunning);
 
-         for (var k in anims) {
 
-             var anim = anims[k];
 
-             if (anim.config.queue == queueName) {
 
-                 anim.stop(end);
 
-             }
 
-         }
 
-     }
 
-     /**
 
-      * whether elem is running anim
 
-      * @param elem
 
-      */
 
-     Anim['isRunning'] = function(elem) {
 
-         var allRunning = DOM.data(elem, runningKey);
 
-         return allRunning && !S.isEmptyObject(allRunning);
 
-     };
 
-     Anim.Q = Q;
 
-     if (SHORT_HANDS) {
 
-     }
 
-     return Anim;
 
- }, {
 
-     requires:["dom","event","./easing","ua","./manager","./fx","./queue"]
 
- });
 
- /**
 
-  * 2011-11
 
-  * - 重构,抛弃 emile,优化性能,只对需要的属性进行动画
 
-  * - 添加 stop/stopQueue/isRunning,支持队列管理
 
-  *
 
-  * 2011-04
 
-  * - 借鉴 yui3 ,中央定时器,否则 ie6 内存泄露?
 
-  * - 支持配置 scrollTop/scrollLeft
 
-  *
 
-  *
 
-  * TODO:
 
-  *  - 效率需要提升,当使用 nativeSupport 时仍做了过多动作
 
-  *  - opera nativeSupport 存在 bug ,浏览器自身 bug ?
 
-  *  - 实现 jQuery Effects 的 queue / specialEasing / += / 等特性
 
-  *
 
-  * NOTES:
 
-  *  - 与 emile 相比,增加了 borderStyle, 使得 border: 5px solid #ccc 能从无到有,正确显示
 
-  *  - api 借鉴了 YUI, jQuery 以及 http://www.w3.org/TR/css3-transitions/
 
-  *  - 代码实现了借鉴了 Emile.js: http://github.com/madrobby/emile *
 
-  */
 
- /**
 
-  * special patch for making color gradual change
 
-  * @author  yiminghe@gmail.com
 
-  */
 
- KISSY.add("anim/color", function(S, DOM, Anim, Fx) {
 
-     var HEX_BASE = 16,
 
-         floor = Math.floor,
 
-         KEYWORDS = {
 
-             "black":[0,0,0],
 
-             "silver":[192,192,192],
 
-             "gray":[128,128,128],
 
-             "white":[255,255,255],
 
-             "maroon":[128,0,0],
 
-             "red":[255,0,0],
 
-             "purple":[128,0,128],
 
-             "fuchsia":[255,0,255],
 
-             "green":[0,128,0],
 
-             "lime":[0,255,0],
 
-             "olive":[128,128,0],
 
-             "yellow":[255,255,0],
 
-             "navy":[0,0,128],
 
-             "blue":[0,0,255],
 
-             "teal":[0,128,128],
 
-             "aqua":[0,255,255]
 
-         },
 
-         re_RGB = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,
 
-         re_RGBA = /^rgba\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+),\s*([0-9]+)\)$/i,
 
-         re_hex = /^#?([0-9A-F]{1,2})([0-9A-F]{1,2})([0-9A-F]{1,2})$/i,
 
-         SHORT_HANDS = Anim.SHORT_HANDS,
 
-         COLORS = [
 
-             'backgroundColor' ,
 
-             'borderBottomColor' ,
 
-             'borderLeftColor' ,
 
-             'borderRightColor' ,
 
-             'borderTopColor' ,
 
-             'color' ,
 
-             'outlineColor'
 
-         ];
 
-     SHORT_HANDS['background'] = ['backgroundColor'];
 
-     SHORT_HANDS['borderColor'] = [
 
-         'borderBottomColor',
 
-         'borderLeftColor',
 
-         'borderRightColor',
 
-         'borderTopColor'
 
-     ];
 
-     SHORT_HANDS['border'].push(
 
-         'borderBottomColor',
 
-         'borderLeftColor',
 
-         'borderRightColor',
 
-         'borderTopColor'
 
-     );
 
-     SHORT_HANDS['borderBottom'].push(
 
-         'borderBottomColor'
 
-     );
 
-     SHORT_HANDS['borderLeft'].push(
 
-         'borderLeftColor'
 
-     );
 
-     SHORT_HANDS['borderRight'].push(
 
-         'borderRightColor'
 
-     );
 
-     SHORT_HANDS['borderTop'].push(
 
-         'borderTopColor'
 
-     );
 
-     //得到颜色的数值表示,红绿蓝数字数组
 
-     function numericColor(val) {
 
-         val = (val + "");
 
-         var match;
 
-         if (match = val.match(re_RGB)) {
 
-             return [
 
-                 parseInt(match[1]),
 
-                 parseInt(match[2]),
 
-                 parseInt(match[3])
 
-             ];
 
-         }
 
-         else if (match = val.match(re_RGBA)) {
 
-             return [
 
-                 parseInt(match[1]),
 
-                 parseInt(match[2]),
 
-                 parseInt(match[3]),
 
-                 parseInt(match[4])
 
-             ];
 
-         }
 
-         else if (match = val.match(re_hex)) {
 
-             for (var i = 1; i < match.length; i++) {
 
-                 if (match[i].length < 2) {
 
-                     match[i] += match[i];
 
-                 }
 
-             }
 
-             return [
 
-                 parseInt(match[1], HEX_BASE),
 
-                 parseInt(match[2], HEX_BASE),
 
-                 parseInt(match[3], HEX_BASE)
 
-             ];
 
-         }
 
-         if (KEYWORDS[val = val.toLowerCase()]) {
 
-             return KEYWORDS[val];
 
-         }
 
-         //transparent 或者 颜色字符串返回
 
-         S.log("only allow rgb or hex color string : " + val, "warn");
 
-         return [255,255,255];
 
-     }
 
-     function ColorFx() {
 
-         ColorFx.superclass.constructor.apply(this, arguments);
 
-     }
 
-     S.extend(ColorFx, Fx, {
 
-         load:function() {
 
-             var self = this;
 
-             ColorFx.superclass.load.apply(self, arguments);
 
-             if (self.from) {
 
-                 self.from = numericColor(self.from);
 
-             }
 
-             if (self.to) {
 
-                 self.to = numericColor(self.to);
 
-             }
 
-         },
 
-         interpolate:function (from, to, pos) {
 
-             var interpolate = ColorFx.superclass.interpolate;
 
-             if (from.length == 3 && to.length == 3) {
 
-                 return 'rgb(' + [
 
-                     floor(interpolate(from[0], to[0], pos)),
 
-                     floor(interpolate(from[1], to[1], pos)),
 
-                     floor(interpolate(from[2], to[2], pos))
 
-                 ].join(', ') + ')';
 
-             } else if (from.length == 4 || to.length == 4) {
 
-                 return 'rgba(' + [
 
-                     floor(interpolate(from[0], to[0], pos)),
 
-                     floor(interpolate(from[1], to[1], pos)),
 
-                     floor(interpolate(from[2], to[2], pos)),
 
-                     // 透明度默认 1
 
-                     floor(interpolate(from[3] || 1, to[3] || 1, pos))
 
-                 ].join(', ') + ')';
 
-             } else {
 
-                 S.log("anim/color unknown value : " + from);
 
-             }
 
-         }
 
-     });
 
-     S.each(COLORS, function(color) {
 
-         Fx.Factories[color] = ColorFx;
 
-     });
 
-     return ColorFx;
 
- }, {
 
-     requires:["dom","./base","./fx"]
 
- });
 
- /**
 
-  * TODO
 
-  * 支持 hsla
 
-  *  - https://github.com/jquery/jquery-color/blob/master/jquery.color.js
 
-  **/
 
- KISSY.add("anim", function(S, Anim,Easing) {
 
-     Anim.Easing=Easing;
 
-     return Anim;
 
- }, {
 
-     requires:["anim/base","anim/easing","anim/color"]
 
- });
 
- /**
 
-  * @module  anim-node-plugin
 
-  * @author  yiminghe@gmail.com,
 
-  *          lifesinger@gmail.com,
 
-  *          qiaohua@taobao.com,
 
-  *
 
-  */
 
- KISSY.add('node/anim', function(S, DOM, Anim, Node, undefined) {
 
-     var FX = [
 
-         // height animations
 
-         [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
 
-         // width animations
 
-         [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
 
-         // opacity animations
 
-         [ "opacity" ]
 
-     ];
 
-     function getFxs(type, num, from) {
 
-         var ret = [],
 
-             obj = {};
 
-         for (var i = from || 0; i < num; i++) {
 
-             ret.push.apply(ret, FX[i]);
 
-         }
 
-         for (i = 0; i < ret.length; i++) {
 
-             obj[ret[i]] = type;
 
-         }
 
-         return obj;
 
-     }
 
-     S.augment(Node, {
 
-         animate:function() {
 
-             var self = this,
 
-                 args = S.makeArray(arguments);
 
-             S.each(self, function(elem) {
 
-                 Anim.apply(undefined, [elem].concat(args)).run();
 
-             });
 
-             return self;
 
-         },
 
-         stop:function(end, clearQueue, queue) {
 
-             var self = this;
 
-             S.each(self, function(elem) {
 
-                 Anim.stop(elem, end, clearQueue, queue);
 
-             });
 
-             return self;
 
-         },
 
-         isRunning:function() {
 
-             var self = this;
 
-             for (var i = 0; i < self.length; i++) {
 
-                 if (Anim.isRunning(self[i])) {
 
-                     return 1;
 
-                 }
 
-             }
 
-             return 0;
 
-         }
 
-     });
 
-     S.each({
 
-             show: getFxs("show", 3),
 
-             hide: getFxs("hide", 3),
 
-             toggle:getFxs("toggle", 3),
 
-             fadeIn: getFxs("show", 3, 2),
 
-             fadeOut: getFxs("hide", 3, 2),
 
-             fadeToggle:getFxs("toggle", 3, 2),
 
-             slideDown: getFxs("show", 1),
 
-             slideUp: getFxs("hide", 1),
 
-             slideToggle:getFxs("toggle", 1)
 
-         },
 
-         function(v, k) {
 
-             Node.prototype[k] = function(speed, callback, easing) {
 
-                 var self = this;
 
-                 // 没有参数时,调用 DOM 中的对应方法
 
-                 if (DOM[k] && !speed) {
 
-                     DOM[k](self);
 
-                 } else {
 
-                     S.each(self, function(elem) {
 
-                         Anim(elem, v, speed, easing || 'easeOut', callback).run();
 
-                     });
 
-                 }
 
-                 return self;
 
-             };
 
-         });
 
- }, {
 
-     requires:["dom","anim","./base"]
 
- });
 
- /**
 
-  * 2011-11-10
 
-  *  - 重写,逻辑放到 Anim 模块,这边只进行转发
 
-  *
 
-  * 2011-05-17
 
-  *  - 承玉:添加 stop ,随时停止动画
 
-  *
 
-  *  TODO
 
-  *  - anim needs queue mechanism ?
 
-  */
 
- KISSY.add("node", function(S, Event, Node) {
 
-     Node.KeyCodes = Event.KeyCodes;
 
-     return Node;
 
- }, {
 
-     requires:[
 
-         "event",
 
-         "node/base",
 
-         "node/attach",
 
-         "node/override",
 
-         "node/anim"]
 
- });
 
- /*
 
-  http://www.JSON.org/json2.js
 
-  2010-08-25
 
-  Public Domain.
 
-  NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 
-  See http://www.JSON.org/js.html
 
-  This code should be minified before deployment.
 
-  See http://javascript.crockford.com/jsmin.html
 
-  USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
 
-  NOT CONTROL.
 
-  This file creates a global JSON object containing two methods: stringify
 
-  and parse.
 
-  JSON.stringify(value, replacer, space)
 
-  value       any JavaScript value, usually an object or array.
 
-  replacer    an optional parameter that determines how object
 
-  values are stringified for objects. It can be a
 
-  function or an array of strings.
 
-  space       an optional parameter that specifies the indentation
 
-  of nested structures. If it is omitted, the text will
 
-  be packed without extra whitespace. If it is a number,
 
-  it will specify the number of spaces to indent at each
 
-  level. If it is a string (such as '\t' or ' '),
 
-  it contains the characters used to indent at each level.
 
-  This method produces a JSON text from a JavaScript value.
 
-  When an object value is found, if the object contains a toJSON
 
-  method, its toJSON method will be called and the result will be
 
-  stringified. A toJSON method does not serialize: it returns the
 
-  value represented by the name/value pair that should be serialized,
 
-  or undefined if nothing should be serialized. The toJSON method
 
-  will be passed the key associated with the value, and this will be
 
-  bound to the value
 
-  For example, this would serialize Dates as ISO strings.
 
-  Date.prototype.toJSON = function (key) {
 
-  function f(n) {
 
-  // Format integers to have at least two digits.
 
-  return n < 10 ? '0' + n : n;
 
-  }
 
-  return this.getUTCFullYear()   + '-' +
 
-  f(this.getUTCMonth() + 1) + '-' +
 
-  f(this.getUTCDate())      + 'T' +
 
-  f(this.getUTCHours())     + ':' +
 
-  f(this.getUTCMinutes())   + ':' +
 
-  f(this.getUTCSeconds())   + 'Z';
 
-  };
 
-  You can provide an optional replacer method. It will be passed the
 
-  key and value of each member, with this bound to the containing
 
-  object. The value that is returned from your method will be
 
-  serialized. If your method returns undefined, then the member will
 
-  be excluded from the serialization.
 
-  If the replacer parameter is an array of strings, then it will be
 
-  used to select the members to be serialized. It filters the results
 
-  such that only members with keys listed in the replacer array are
 
-  stringified.
 
-  Values that do not have JSON representations, such as undefined or
 
-  functions, will not be serialized. Such values in objects will be
 
-  dropped; in arrays they will be replaced with null. You can use
 
-  a replacer function to replace those with JSON values.
 
-  JSON.stringify(undefined) returns undefined.
 
-  The optional space parameter produces a stringification of the
 
-  value that is filled with line breaks and indentation to make it
 
-  easier to read.
 
-  If the space parameter is a non-empty string, then that string will
 
-  be used for indentation. If the space parameter is a number, then
 
-  the indentation will be that many spaces.
 
-  Example:
 
-  text = JSON.stringify(['e', {pluribus: 'unum'}]);
 
-  // text is '["e",{"pluribus":"unum"}]'
 
-  text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
 
-  // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
 
-  text = JSON.stringify([new Date()], function (key, value) {
 
-  return this[key] instanceof Date ?
 
-  'Date(' + this[key] + ')' : value;
 
-  });
 
-  // text is '["Date(---current time---)"]'
 
-  JSON.parse(text, reviver)
 
-  This method parses a JSON text to produce an object or array.
 
-  It can throw a SyntaxError exception.
 
-  The optional reviver parameter is a function that can filter and
 
-  transform the results. It receives each of the keys and values,
 
-  and its return value is used instead of the original value.
 
-  If it returns what it received, then the structure is not modified.
 
-  If it returns undefined then the member is deleted.
 
-  Example:
 
-  // Parse the text. Values that look like ISO date strings will
 
-  // be converted to Date objects.
 
-  myData = JSON.parse(text, function (key, value) {
 
-  var a;
 
-  if (typeof value === 'string') {
 
-  a =
 
-  /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
 
-  if (a) {
 
-  return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
 
-  +a[5], +a[6]));
 
-  }
 
-  }
 
-  return value;
 
-  });
 
-  myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
 
-  var d;
 
-  if (typeof value === 'string' &&
 
-  value.slice(0, 5) === 'Date(' &&
 
-  value.slice(-1) === ')') {
 
-  d = new Date(value.slice(5, -1));
 
-  if (d) {
 
-  return d;
 
-  }
 
-  }
 
-  return value;
 
-  });
 
-  This is a reference implementation. You are free to copy, modify, or
 
-  redistribute.
 
-  */
 
- /*jslint evil: true, strict: false */
 
- /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
 
-  call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
 
-  getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
 
-  lastIndex, length, parse, prototype, push, replace, slice, stringify,
 
-  test, toJSON, toString, valueOf
 
-  */
 
- // Create a JSON object only if one does not already exist. We create the
 
- // methods in a closure to avoid creating global variables.
 
- KISSY.add("json/json2", function(S, UA) {
 
-     var win = window,JSON = win.JSON;
 
-     // ie 8.0.7600.16315@win7 json 有问题
 
-     if (!JSON || UA['ie'] < 9) {
 
-         JSON = win.JSON = {};
 
-     }
 
-     function f(n) {
 
-         // Format integers to have at least two digits.
 
-         return n < 10 ? '0' + n : n;
 
-     }
 
-     if (typeof Date.prototype.toJSON !== 'function') {
 
-         Date.prototype.toJSON = function (key) {
 
-             return isFinite(this.valueOf()) ?
 
-                 this.getUTCFullYear() + '-' +
 
-                     f(this.getUTCMonth() + 1) + '-' +
 
-                     f(this.getUTCDate()) + 'T' +
 
-                     f(this.getUTCHours()) + ':' +
 
-                     f(this.getUTCMinutes()) + ':' +
 
-                     f(this.getUTCSeconds()) + 'Z' : null;
 
-         };
 
-         String.prototype.toJSON =
 
-             Number.prototype.toJSON =
 
-                 Boolean.prototype.toJSON = function (key) {
 
-                     return this.valueOf();
 
-                 };
 
-     }
 
-     var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
 
-         escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
 
-         gap,
 
-         indent,
 
-         meta = {    // table of character substitutions
 
-             '\b': '\\b',
 
-             '\t': '\\t',
 
-             '\n': '\\n',
 
-             '\f': '\\f',
 
-             '\r': '\\r',
 
-             '"' : '\\"',
 
-             '\\': '\\\\'
 
-         },
 
-         rep;
 
-     function quote(string) {
 
- // If the string contains no control characters, no quote characters, and no
 
- // backslash characters, then we can safely slap some quotes around it.
 
- // Otherwise we must also replace the offending characters with safe escape
 
- // sequences.
 
-         escapable['lastIndex'] = 0;
 
-         return escapable.test(string) ?
 
-             '"' + string.replace(escapable, function (a) {
 
-                 var c = meta[a];
 
-                 return typeof c === 'string' ? c :
 
-                     '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
 
-             }) + '"' :
 
-             '"' + string + '"';
 
-     }
 
-     function str(key, holder) {
 
- // Produce a string from holder[key].
 
-         var i,          // The loop counter.
 
-             k,          // The member key.
 
-             v,          // The member value.
 
-             length,
 
-             mind = gap,
 
-             partial,
 
-             value = holder[key];
 
- // If the value has a toJSON method, call it to obtain a replacement value.
 
-         if (value && typeof value === 'object' &&
 
-             typeof value.toJSON === 'function') {
 
-             value = value.toJSON(key);
 
-         }
 
- // If we were called with a replacer function, then call the replacer to
 
- // obtain a replacement value.
 
-         if (typeof rep === 'function') {
 
-             value = rep.call(holder, key, value);
 
-         }
 
- // What happens next depends on the value's type.
 
-         switch (typeof value) {
 
-             case 'string':
 
-                 return quote(value);
 
-             case 'number':
 
- // JSON numbers must be finite. Encode non-finite numbers as null.
 
-                 return isFinite(value) ? String(value) : 'null';
 
-             case 'boolean':
 
-             case 'null':
 
- // If the value is a boolean or null, convert it to a string. Note:
 
- // typeof null does not produce 'null'. The case is included here in
 
- // the remote chance that this gets fixed someday.
 
-                 return String(value);
 
- // If the type is 'object', we might be dealing with an object or an array or
 
- // null.
 
-             case 'object':
 
- // Due to a specification blunder in ECMAScript, typeof null is 'object',
 
- // so watch out for that case.
 
-                 if (!value) {
 
-                     return 'null';
 
-                 }
 
- // Make an array to hold the partial results of stringifying this object value.
 
-                 gap += indent;
 
-                 partial = [];
 
- // Is the value an array?
 
-                 if (Object.prototype.toString.apply(value) === '[object Array]') {
 
- // The value is an array. Stringify every element. Use null as a placeholder
 
- // for non-JSON values.
 
-                     length = value.length;
 
-                     for (i = 0; i < length; i += 1) {
 
-                         partial[i] = str(i, value) || 'null';
 
-                     }
 
- // Join all of the elements together, separated with commas, and wrap them in
 
- // brackets.
 
-                     v = partial.length === 0 ? '[]' :
 
-                         gap ? '[\n' + gap +
 
-                             partial.join(',\n' + gap) + '\n' +
 
-                             mind + ']' :
 
-                             '[' + partial.join(',') + ']';
 
-                     gap = mind;
 
-                     return v;
 
-                 }
 
- // If the replacer is an array, use it to select the members to be stringified.
 
-                 if (rep && typeof rep === 'object') {
 
-                     length = rep.length;
 
-                     for (i = 0; i < length; i += 1) {
 
-                         k = rep[i];
 
-                         if (typeof k === 'string') {
 
-                             v = str(k, value);
 
-                             if (v) {
 
-                                 partial.push(quote(k) + (gap ? ': ' : ':') + v);
 
-                             }
 
-                         }
 
-                     }
 
-                 } else {
 
- // Otherwise, iterate through all of the keys in the object.
 
-                     for (k in value) {
 
-                         if (Object.hasOwnProperty.call(value, k)) {
 
-                             v = str(k, value);
 
-                             if (v) {
 
-                                 partial.push(quote(k) + (gap ? ': ' : ':') + v);
 
-                             }
 
-                         }
 
-                     }
 
-                 }
 
- // Join all of the member texts together, separated with commas,
 
- // and wrap them in braces.
 
-                 v = partial.length === 0 ? '{}' :
 
-                     gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
 
-                         mind + '}' : '{' + partial.join(',') + '}';
 
-                 gap = mind;
 
-                 return v;
 
-         }
 
-     }
 
- // If the JSON object does not yet have a stringify method, give it one.
 
-     if (typeof JSON.stringify !== 'function') {
 
-         JSON.stringify = function (value, replacer, space) {
 
- // The stringify method takes a value and an optional replacer, and an optional
 
- // space parameter, and returns a JSON text. The replacer can be a function
 
- // that can replace values, or an array of strings that will select the keys.
 
- // A default replacer method can be provided. Use of the space parameter can
 
- // produce text that is more easily readable.
 
-             var i;
 
-             gap = '';
 
-             indent = '';
 
- // If the space parameter is a number, make an indent string containing that
 
- // many spaces.
 
-             if (typeof space === 'number') {
 
-                 for (i = 0; i < space; i += 1) {
 
-                     indent += ' ';
 
-                 }
 
- // If the space parameter is a string, it will be used as the indent string.
 
-             } else if (typeof space === 'string') {
 
-                 indent = space;
 
-             }
 
- // If there is a replacer, it must be a function or an array.
 
- // Otherwise, throw an error.
 
-             rep = replacer;
 
-             if (replacer && typeof replacer !== 'function' &&
 
-                 (typeof replacer !== 'object' ||
 
-                     typeof replacer.length !== 'number')) {
 
-                 throw new Error('JSON.stringify');
 
-             }
 
- // Make a fake root object containing our value under the key of ''.
 
- // Return the result of stringifying the value.
 
-             return str('', {'': value});
 
-         };
 
-     }
 
- // If the JSON object does not yet have a parse method, give it one.
 
-     if (typeof JSON.parse !== 'function') {
 
-         JSON.parse = function (text, reviver) {
 
- // The parse method takes a text and an optional reviver function, and returns
 
- // a JavaScript value if the text is a valid JSON text.
 
-             var j;
 
-             function walk(holder, key) {
 
- // The walk method is used to recursively walk the resulting structure so
 
- // that modifications can be made.
 
-                 var k, v, value = holder[key];
 
-                 if (value && typeof value === 'object') {
 
-                     for (k in value) {
 
-                         if (Object.hasOwnProperty.call(value, k)) {
 
-                             v = walk(value, k);
 
-                             if (v !== undefined) {
 
-                                 value[k] = v;
 
-                             } else {
 
-                                 delete value[k];
 
-                             }
 
-                         }
 
-                     }
 
-                 }
 
-                 return reviver.call(holder, key, value);
 
-             }
 
- // Parsing happens in four stages. In the first stage, we replace certain
 
- // Unicode characters with escape sequences. JavaScript handles many characters
 
- // incorrectly, either silently deleting them, or treating them as line endings.
 
-             text = String(text);
 
-             cx['lastIndex'] = 0;
 
-             if (cx.test(text)) {
 
-                 text = text.replace(cx, function (a) {
 
-                     return '\\u' +
 
-                         ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
 
-                 });
 
-             }
 
- // In the second stage, we run the text against regular expressions that look
 
- // for non-JSON patterns. We are especially concerned with '()' and 'new'
 
- // because they can cause invocation, and '=' because it can cause mutation.
 
- // But just to be safe, we want to reject all unexpected forms.
 
- // We split the second stage into 4 regexp operations in order to work around
 
- // crippling inefficiencies in IE's and Safari's regexp engines. First we
 
- // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
 
- // replace all simple value tokens with ']' characters. Third, we delete all
 
- // open brackets that follow a colon or comma or that begin the text. Finally,
 
- // we look to see that the remaining characters are only whitespace or ']' or
 
- // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
 
-             if (/^[\],:{}\s]*$/
 
-                 .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
 
-                 .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
 
-                 .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
 
- // In the third stage we use the eval function to compile the text into a
 
- // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
 
- // in JavaScript: it can begin a block or an object literal. We wrap the text
 
- // in parens to eliminate the ambiguity.
 
-                 j = eval('(' + text + ')');
 
- // In the optional fourth stage, we recursively walk the new structure, passing
 
- // each name/value pair to a reviver function for possible transformation.
 
-                 return typeof reviver === 'function' ?
 
-                     walk({'': j}, '') : j;
 
-             }
 
- // If the text is not JSON parseable, then a SyntaxError is thrown.
 
-             throw new SyntaxError('JSON.parse');
 
-         };
 
-     }
 
-     return JSON;
 
- }, {requires:['ua']});
 
- /**
 
-  * adapt json2 to kissy
 
-  * @author lifesinger@gmail.com
 
-  */
 
- KISSY.add('json', function (S, JSON) {
 
-     return {
 
-         parse: function(text) {
 
-             // 当输入为 undefined / null / '' 时,返回 null
 
-             if (S.isNullOrUndefined(text) || text === '') {
 
-                 return null;
 
-             }
 
-             return JSON.parse(text);
 
-         },
 
-         stringify: JSON.stringify
 
-     };
 
- }, {
 
-     requires:["json/json2"]
 
- });
 
- /**
 
-  * form data  serialization util
 
-  * @author  yiminghe@gmail.com
 
-  */
 
- KISSY.add("ajax/form-serializer", function(S, DOM) {
 
-     var rselectTextarea = /^(?:select|textarea)/i,
 
-         rCRLF = /\r?\n/g,
 
-         rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i;
 
-     return {
 
-         /**
 
-          * 序列化表单元素
 
-          * @param {String|HTMLElement[]|HTMLElement|Node} forms
 
-          */
 
-         serialize:function(forms) {
 
-             var elements = [],data = {};
 
-             DOM.query(forms).each(function(el) {
 
-                 // form 取其表单元素集合
 
-                 // 其他直接取自身
 
-                 var subs = el.elements ? S.makeArray(el.elements) : [el];
 
-                 elements.push.apply(elements, subs);
 
-             });
 
-             // 对表单元素进行过滤,具备有效值的才保留
 
-             elements = S.filter(elements, function(el) {
 
-                 // 有名字
 
-                 return el.name &&
 
-                     // 不被禁用
 
-                     !el.disabled &&
 
-                     (
 
-                         // radio,checkbox 被选择了
 
-                         el.checked ||
 
-                             // select 或者 textarea
 
-                             rselectTextarea.test(el.nodeName) ||
 
-                             // input 类型
 
-                             rinput.test(el.type)
 
-                         );
 
-                 // 这样子才取值
 
-             });
 
-             S.each(elements, function(el) {
 
-                 var val = DOM.val(el),vs;
 
-                 // 字符串换行平台归一化
 
-                 val = S.map(S.makeArray(val), function(v) {
 
-                     return v.replace(rCRLF, "\r\n");
 
-                 });
 
-                 // 全部搞成数组,防止同名
 
-                 vs = data[el.name] = data[el.name] || [];
 
-                 vs.push.apply(vs, val);
 
-             });
 
-             // 名值键值对序列化,数组元素名字前不加 []
 
-             return S.param(data, undefined, undefined, false);
 
-         }
 
-     };
 
- }, {
 
-     requires:['dom']
 
- });
 
- /**
 
-  * encapsulation of io object . as transaction object in yui3
 
-  * @author yiminghe@gmail.com
 
-  */
 
- KISSY.add("ajax/xhrobject", function(S, Event) {
 
-     var OK_CODE = 200,
 
-         MULTIPLE_CHOICES = 300,
 
-         NOT_MODIFIED = 304,
 
-         // get individual response header from responseheader str
 
-         rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg;
 
-     function handleResponseData(xhr) {
 
-         // text xml 是否原生转化支持
 
-         var text = xhr.responseText,
 
-             xml = xhr.responseXML,
 
-             c = xhr.config,
 
-             cConverts = c.converters,
 
-             xConverts = xhr.converters || {},
 
-             type,
 
-             responseData,
 
-             contents = c.contents,
 
-             dataType = c.dataType;
 
-         // 例如 script 直接是js引擎执行,没有返回值,不需要自己处理初始返回值
 
-         // jsonp 时还需要把 script 转换成 json,后面还得自己来
 
-         if (text || xml) {
 
-             var contentType = xhr.mimeType || xhr.getResponseHeader("Content-Type");
 
-             // 去除无用的通用格式
 
-             while (dataType[0] == "*") {
 
-                 dataType.shift();
 
-             }
 
-             if (!dataType.length) {
 
-                 // 获取源数据格式,放在第一个
 
-                 for (type in contents) {
 
-                     if (contents[type].test(contentType)) {
 
-                         if (dataType[0] != type) {
 
-                             dataType.unshift(type);
 
-                         }
 
-                         break;
 
-                     }
 
-                 }
 
-             }
 
-             // 服务器端没有告知(并且客户端没有mimetype)默认 text 类型
 
-             dataType[0] = dataType[0] || "text";
 
-             //获得合适的初始数据
 
-             if (dataType[0] == "text" && text !== undefined) {
 
-                 responseData = text;
 
-             }
 
-             // 有 xml 值才直接取,否则可能还要从 xml 转
 
-             else if (dataType[0] == "xml" && xml !== undefined) {
 
-                 responseData = xml;
 
-             } else {
 
-                 // 看能否从 text xml 转换到合适数据
 
-                 S.each(["text","xml"], function(prevType) {
 
-                     var type = dataType[0],
 
-                         converter = xConverts[prevType] && xConverts[prevType][type] ||
 
-                             cConverts[prevType] && cConverts[prevType][type];
 
-                     if (converter) {
 
-                         dataType.unshift(prevType);
 
-                         responseData = prevType == "text" ? text : xml;
 
-                         return false;
 
-                     }
 
-                 });
 
-             }
 
-         }
 
-         var prevType = dataType[0];
 
-         // 按照转化链把初始数据转换成我们想要的数据类型
 
-         for (var i = 1; i < dataType.length; i++) {
 
-             type = dataType[i];
 
-             var converter = xConverts[prevType] && xConverts[prevType][type] ||
 
-                 cConverts[prevType] && cConverts[prevType][type];
 
-             if (!converter) {
 
-                 throw "no covert for " + prevType + " => " + type;
 
-             }
 
-             responseData = converter(responseData);
 
-             prevType = type;
 
-         }
 
-         xhr.responseData = responseData;
 
-     }
 
-     function XhrObject(c) {
 
-         S.mix(this, {
 
-             // 结构化数据,如 json
 
-             responseData:null,
 
-             config:c || {},
 
-             timeoutTimer:null,
 
-             responseText:null,
 
-             responseXML:null,
 
-             responseHeadersString:"",
 
-             responseHeaders:null,
 
-             requestHeaders:{},
 
-             readyState:0,
 
-             //internal state
 
-             state:0,
 
-             statusText:null,
 
-             status:0,
 
-             transport:null
 
-         });
 
-     }
 
-     S.augment(XhrObject, Event.Target, {
 
-             // Caches the header
 
-             setRequestHeader: function(name, value) {
 
-                 this.requestHeaders[ name ] = value;
 
-                 return this;
 
-             },
 
-             // Raw string
 
-             getAllResponseHeaders: function() {
 
-                 return this.state === 2 ? this.responseHeadersString : null;
 
-             },
 
-             // Builds headers hashtable if needed
 
-             getResponseHeader: function(key) {
 
-                 var match;
 
-                 if (this.state === 2) {
 
-                     if (!this.responseHeaders) {
 
-                         this.responseHeaders = {};
 
-                         while (( match = rheaders.exec(this.responseHeadersString) )) {
 
-                             this.responseHeaders[ match[1] ] = match[ 2 ];
 
-                         }
 
-                     }
 
-                     match = this.responseHeaders[ key];
 
-                 }
 
-                 return match === undefined ? null : match;
 
-             },
 
-             // Overrides response content-type header
 
-             overrideMimeType: function(type) {
 
-                 if (!this.state) {
 
-                     this.mimeType = type;
 
-                 }
 
-                 return this;
 
-             },
 
-             // Cancel the request
 
-             abort: function(statusText) {
 
-                 statusText = statusText || "abort";
 
-                 if (this.transport) {
 
-                     this.transport.abort(statusText);
 
-                 }
 
-                 this.callback(0, statusText);
 
-                 return this;
 
-             },
 
-             callback:function(status, statusText) {
 
-                 //debugger
 
-                 var xhr = this;
 
-                 // 只能执行一次,防止重复执行
 
-                 // 例如完成后,调用 abort
 
-                 // 到这要么成功,调用success
 
-                 // 要么失败,调用 error
 
-                 // 最终都会调用 complete
 
-                 if (xhr.state == 2) {
 
-                     return;
 
-                 }
 
-                 xhr.state = 2;
 
-                 xhr.readyState = 4;
 
-                 var isSuccess;
 
-                 if (status >= OK_CODE && status < MULTIPLE_CHOICES || status == NOT_MODIFIED) {
 
-                     if (status == NOT_MODIFIED) {
 
-                         statusText = "notmodified";
 
-                         isSuccess = true;
 
-                     } else {
 
-                         try {
 
-                             handleResponseData(xhr);
 
-                             statusText = "success";
 
-                             isSuccess = true;
 
-                         } catch(e) {
 
-                             statusText = "parsererror : " + e;
 
-                         }
 
-                     }
 
-                 } else {
 
-                     if (status < 0) {
 
-                         status = 0;
 
-                     }
 
-                 }
 
-                 xhr.status = status;
 
-                 xhr.statusText = statusText;
 
-                 if (isSuccess) {
 
-                     xhr.fire("success");
 
-                 } else {
 
-                     xhr.fire("error");
 
-                 }
 
-                 xhr.fire("complete");
 
-                 xhr.transport = undefined;
 
-             }
 
-         }
 
-     );
 
-     return XhrObject;
 
- }, {
 
-     requires:["event"]
 
- });
 
- /**
 
-  * a scalable client io framework
 
-  * @author  yiminghe@gmail.com , lijing00333@163.com
 
-  */
 
- KISSY.add("ajax/base", function(S, JSON, Event, XhrObject) {
 
-         var rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/,
 
-             rspace = /\s+/,
 
-             rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
 
-             mirror = function(s) {
 
-                 return s;
 
-             },
 
-             HTTP_PORT = 80,
 
-             HTTPS_PORT = 443,
 
-             rnoContent = /^(?:GET|HEAD)$/,
 
-             curLocation,
 
-             curLocationParts;
 
-         try {
 
-             curLocation = location.href;
 
-         } catch(e) {
 
-             S.log("ajax/base get curLocation error : ");
 
-             S.log(e);
 
-             // Use the href attribute of an A element
 
-             // since IE will modify it given document.location
 
-             curLocation = document.createElement("a");
 
-             curLocation.href = "";
 
-             curLocation = curLocation.href;
 
-         }
 
-         curLocationParts = rurl.exec(curLocation);
 
-         var isLocal = rlocalProtocol.test(curLocationParts[1]),
 
-             transports = {},
 
-             defaultConfig = {
 
-                 // isLocal:isLocal,
 
-                 type:"GET",
 
-                 // only support utf-8 when post, encoding can not be changed actually
 
-                 contentType: "application/x-www-form-urlencoded; charset=UTF-8",
 
-                 async:true,
 
-                 // whether add []
 
-                 serializeArray:true,
 
-                 // whether param data
 
-                 processData:true,
 
-                 /*
 
-                  url:"",
 
-                  context:null,
 
-                  // 单位秒!!
 
-                  timeout: 0,
 
-                  data: null,
 
-                  // 可取json | jsonp | script | xml | html | text | null | undefined
 
-                  dataType: null,
 
-                  username: null,
 
-                  password: null,
 
-                  cache: null,
 
-                  mimeType:null,
 
-                  xdr:{
 
-                      subDomain:{
 
-                         proxy:'http://xx.t.com/proxy.html'
 
-                      },
 
-                      src:''
 
-                  },
 
-                  headers: {},
 
-                  xhrFields:{},
 
-                  // jsonp script charset
 
-                  scriptCharset:null,
 
-                  crossdomain:false,
 
-                  forceScript:false,
 
-                  */
 
-                 accepts: {
 
-                     xml: "application/xml, text/xml",
 
-                     html: "text/html",
 
-                     text: "text/plain",
 
-                     json: "application/json, text/javascript",
 
-                     "*": "*/*"
 
-                 },
 
-                 converters:{
 
-                     text:{
 
-                         json:JSON.parse,
 
-                         html:mirror,
 
-                         text:mirror,
 
-                         xml:S.parseXML
 
-                     }
 
-                 },
 
-                 contents:{
 
-                     xml:/xml/,
 
-                     html:/html/,
 
-                     json:/json/
 
-                 }
 
-             };
 
-         defaultConfig.converters.html = defaultConfig.converters.text;
 
-         function setUpConfig(c) {
 
-             // deep mix
 
-             c = S.mix(S.clone(defaultConfig), c || {}, undefined, undefined, true);
 
-             if (!S.isBoolean(c.crossDomain)) {
 
-                 var parts = rurl.exec(c.url.toLowerCase());
 
-                 c.crossDomain = !!( parts &&
 
-                     ( parts[ 1 ] != curLocationParts[ 1 ] || parts[ 2 ] != curLocationParts[ 2 ] ||
 
-                         ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? HTTP_PORT : HTTPS_PORT ) )
 
-                             !=
 
-                             ( curLocationParts[ 3 ] || ( curLocationParts[ 1 ] === "http:" ? HTTP_PORT : HTTPS_PORT ) ) )
 
-                     );
 
-             }
 
-             if (c.processData && c.data && !S.isString(c.data)) {
 
-                 // 必须 encodeURIComponent 编码 utf-8
 
-                 c.data = S.param(c.data, undefined, undefined, c.serializeArray);
 
-             }
 
-             c.type = c.type.toUpperCase();
 
-             c.hasContent = !rnoContent.test(c.type);
 
-             if (!c.hasContent) {
 
-                 if (c.data) {
 
-                     c.url += ( /\?/.test(c.url) ? "&" : "?" ) + c.data;
 
-                 }
 
-                 if (c.cache === false) {
 
-                     c.url += ( /\?/.test(c.url) ? "&" : "?" ) + "_ksTS=" + (S.now() + "_" + S.guid());
 
-                 }
 
-             }
 
-             // 数据类型处理链,一步步将前面的数据类型转化成最后一个
 
-             c.dataType = S.trim(c.dataType || "*").split(rspace);
 
-             c.context = c.context || c;
 
-             return c;
 
-         }
 
-         function fire(eventType, xhr) {
 
-             io.fire(eventType, { ajaxConfig: xhr.config ,xhr:xhr});
 
-         }
 
-         function handleXhrEvent(e) {
 
-             var xhr = this,
 
-                 c = xhr.config,
 
-                 type = e.type;
 
-             if (this.timeoutTimer) {
 
-                 clearTimeout(this.timeoutTimer);
 
-             }
 
-             if (c[type]) {
 
-                 c[type].call(c.context, xhr.responseData, xhr.statusText, xhr);
 
-             }
 
-             fire(type, xhr);
 
-         }
 
-         function io(c) {
 
-             if (!c.url) {
 
-                 return undefined;
 
-             }
 
-             c = setUpConfig(c);
 
-             var xhr = new XhrObject(c);
 
-             fire("start", xhr);
 
-             var transportContructor = transports[c.dataType[0]] || transports["*"],
 
-                 transport = new transportContructor(xhr);
 
-             xhr.transport = transport;
 
-             if (c.contentType) {
 
-                 xhr.setRequestHeader("Content-Type", c.contentType);
 
-             }
 
-             var dataType = c.dataType[0],
 
-                 accepts = c.accepts;
 
-             // Set the Accepts header for the server, depending on the dataType
 
-             xhr.setRequestHeader(
 
-                 "Accept",
 
-                 dataType && accepts[dataType] ?
 
-                     accepts[ dataType ] + (dataType === "*" ? "" : ", */*; q=0.01"  ) :
 
-                     accepts[ "*" ]
 
-             );
 
-             // Check for headers option
 
-             for (var i in c.headers) {
 
-                 xhr.setRequestHeader(i, c.headers[ i ]);
 
-             }
 
-             xhr.on("complete success error", handleXhrEvent);
 
-             xhr.readyState = 1;
 
-             fire("send", xhr);
 
-             // Timeout
 
-             if (c.async && c.timeout > 0) {
 
-                 xhr.timeoutTimer = setTimeout(function() {
 
-                     xhr.abort("timeout");
 
-                 }, c.timeout * 1000);
 
-             }
 
-             try {
 
-                 // flag as sending
 
-                 xhr.state = 1;
 
-                 transport.send();
 
-             } catch (e) {
 
-                 // Propagate exception as error if not done
 
-                 if (xhr.status < 2) {
 
-                     xhr.callback(-1, e);
 
-                     // Simply rethrow otherwise
 
-                 } else {
 
-                     S.error(e);
 
-                 }
 
-             }
 
-             return xhr;
 
-         }
 
-         S.mix(io, Event.Target);
 
-         S.mix(io, {
 
-             isLocal:isLocal,
 
-             setupConfig:function(setting) {
 
-                 S.mix(defaultConfig, setting, undefined, undefined, true);
 
-             },
 
-             setupTransport:function(name, fn) {
 
-                 transports[name] = fn;
 
-             },
 
-             getTransport:function(name) {
 
-                 return transports[name];
 
-             },
 
-             getConfig:function() {
 
-                 return defaultConfig;
 
-             }
 
-         });
 
-         return io;
 
-     },
 
-     {
 
-         requires:["json","event","./xhrobject"]
 
-     });
 
- /**
 
-  * 借鉴 jquery,优化减少闭包使用
 
-  *
 
-  * TODO:
 
-  *  ifModified mode 是否需要?
 
-  *  优点:
 
-  *      不依赖浏览器处理,ajax 请求浏览不会自动加 If-Modified-Since If-None-Match ??
 
-  *  缺点:
 
-  *      内存占用
 
-  **/
 
- /**
 
-  * base for xhr and subdomain
 
-  * @author yiminghe@gmail.com
 
-  */
 
- KISSY.add("ajax/xhrbase", function(S, io) {
 
-     var OK_CODE = 200,
 
-         win = window,
 
-         // http://msdn.microsoft.com/en-us/library/cc288060(v=vs.85).aspx
 
-         _XDomainRequest = win['XDomainRequest'],
 
-         NO_CONTENT_CODE = 204,
 
-         NOT_FOUND_CODE = 404,
 
-         NO_CONTENT_CODE2 = 1223,
 
-         XhrBase = {
 
-             proto:{}
 
-         };
 
-     function createStandardXHR(_, refWin) {
 
-         try {
 
-             return new (refWin || win)['XMLHttpRequest']();
 
-         } catch(e) {
 
-             //S.log("createStandardXHR error");
 
-         }
 
-         return undefined;
 
-     }
 
-     function createActiveXHR(_, refWin) {
 
-         try {
 
-             return new (refWin || win)['ActiveXObject']("Microsoft.XMLHTTP");
 
-         } catch(e) {
 
-             S.log("createActiveXHR error");
 
-         }
 
-         return undefined;
 
-     }
 
-     XhrBase.xhr = win.ActiveXObject ? function(crossDomain, refWin) {
 
-         if (crossDomain && _XDomainRequest) {
 
-             return new _XDomainRequest();
 
-         }
 
-         // ie7 XMLHttpRequest 不能访问本地文件
 
-         return !io.isLocal && createStandardXHR(crossDomain, refWin) || createActiveXHR(crossDomain, refWin);
 
-     } : createStandardXHR;
 
-     function isInstanceOfXDomainRequest(xhr) {
 
-         return _XDomainRequest && (xhr instanceof _XDomainRequest);
 
-     }
 
-     S.mix(XhrBase.proto, {
 
-         sendInternal:function() {
 
-             var self = this,
 
-                 xhrObj = self.xhrObj,
 
-                 c = xhrObj.config;
 
-             var xhr = self.xhr,
 
-                 xhrFields,
 
-                 i;
 
-             if (c['username']) {
 
-                 xhr.open(c.type, c.url, c.async, c['username'], c.password)
 
-             } else {
 
-                 xhr.open(c.type, c.url, c.async);
 
-             }
 
-             if (xhrFields = c['xhrFields']) {
 
-                 for (i in xhrFields) {
 
-                     xhr[ i ] = xhrFields[ i ];
 
-                 }
 
-             }
 
-             // Override mime type if supported
 
-             if (xhrObj.mimeType && xhr.overrideMimeType) {
 
-                 xhr.overrideMimeType(xhrObj.mimeType);
 
-             }
 
-             // yui3 and jquery both have
 
-             if (!c.crossDomain && !xhrObj.requestHeaders["X-Requested-With"]) {
 
-                 xhrObj.requestHeaders[ "X-Requested-With" ] = "XMLHttpRequest";
 
-             }
 
-             try {
 
-                 // 跨域时,不能设,否则请求变成
 
-                 // OPTIONS /xhr/r.php HTTP/1.1
 
-                 if (!c.crossDomain) {
 
-                     for (i in xhrObj.requestHeaders) {
 
-                         xhr.setRequestHeader(i, xhrObj.requestHeaders[ i ]);
 
-                     }
 
-                 }
 
-             } catch(e) {
 
-                 S.log("setRequestHeader in xhr error : ");
 
-                 S.log(e);
 
-             }
 
-             xhr.send(c.hasContent && c.data || null);
 
-             if (!c.async || xhr.readyState == 4) {
 
-                 self._callback();
 
-             } else {
 
-                 // _XDomainRequest 单独的回调机制
 
-                 if (isInstanceOfXDomainRequest(xhr)) {
 
-                     xhr.onload = function() {
 
-                         xhr.readyState = 4;
 
-                         xhr.status = 200;
 
-                         self._callback();
 
-                     };
 
-                     xhr.onerror = function() {
 
-                         xhr.readyState = 4;
 
-                         xhr.status = 500;
 
-                         self._callback();
 
-                     };
 
-                 } else {
 
-                     xhr.onreadystatechange = function() {
 
-                         self._callback();
 
-                     };
 
-                 }
 
-             }
 
-         },
 
-         // 由 xhrObj.abort 调用,自己不可以调用 xhrObj.abort
 
-         abort:function() {
 
-             this._callback(0, 1);
 
-         },
 
-         _callback:function(event, abort) {
 
-             // Firefox throws exceptions when accessing properties
 
-             // of an xhr when a network error occured
 
-             // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
 
-             try {
 
-                 var self = this,
 
-                     xhr = self.xhr,
 
-                     xhrObj = self.xhrObj,
 
-                     c = xhrObj.config;
 
-                 //abort or complete
 
-                 if (abort || xhr.readyState == 4) {
 
-                     // ie6 ActiveObject 设置不恰当属性导致出错
 
-                     if (isInstanceOfXDomainRequest(xhr)) {
 
-                         xhr.onerror = S.noop;
 
-                         xhr.onload = S.noop;
 
-                     } else {
 
-                         // ie6 ActiveObject 只能设置,不能读取这个属性,否则出错!
 
-                         xhr.onreadystatechange = S.noop;
 
-                     }
 
-                     if (abort) {
 
-                         // 完成以后 abort 不要调用
 
-                         if (xhr.readyState !== 4) {
 
-                             xhr.abort();
 
-                         }
 
-                     } else {
 
-                         var status = xhr.status;
 
-                         // _XDomainRequest 不能获取响应头
 
-                         if (!isInstanceOfXDomainRequest(xhr)) {
 
-                             xhrObj.responseHeadersString = xhr.getAllResponseHeaders();
 
-                         }
 
-                         var xml = xhr.responseXML;
 
-                         // Construct response list
 
-                         if (xml && xml.documentElement /* #4958 */) {
 
-                             xhrObj.responseXML = xml;
 
-                         }
 
-                         xhrObj.responseText = xhr.responseText;
 
-                         // Firefox throws an exception when accessing
 
-                         // statusText for faulty cross-domain requests
 
-                         try {
 
-                             var statusText = xhr.statusText;
 
-                         } catch(e) {
 
-                             S.log("xhr statustext error : ");
 
-                             S.log(e);
 
-                             // We normalize with Webkit giving an empty statusText
 
-                             statusText = "";
 
-                         }
 
-                         // Filter status for non standard behaviors
 
-                         // If the request is local and we have data: assume a success
 
-                         // (success with no data won't get notified, that's the best we
 
-                         // can do given current implementations)
 
-                         if (!status && io.isLocal && !c.crossDomain) {
 
-                             status = xhrObj.responseText ? OK_CODE : NOT_FOUND_CODE;
 
-                             // IE - #1450: sometimes returns 1223 when it should be 204
 
-                         } else if (status === NO_CONTENT_CODE2) {
 
-                             status = NO_CONTENT_CODE;
 
-                         }
 
-                         xhrObj.callback(status, statusText);
 
-                     }
 
-                 }
 
-             } catch (firefoxAccessException) {
 
-                 xhr.onreadystatechange = S.noop;
 
-                 if (!abort) {
 
-                     xhrObj.callback(-1, firefoxAccessException);
 
-                 }
 
-             }
 
-         }
 
-     });
 
-     return XhrBase;
 
- }, {
 
-     requires:['./base']
 
- });
 
- /**
 
-  * solve io between sub domains using proxy page
 
-  * @author yiminghe@gmail.com
 
-  */
 
- KISSY.add("ajax/subdomain", function(S, XhrBase, Event, DOM) {
 
-     var rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
 
-         PROXY_PAGE = "/sub_domain_proxy.html",
 
-         doc = document,
 
-         iframeMap = {
 
-             // hostname:{iframe: , ready:}
 
-         };
 
-     function SubDomain(xhrObj) {
 
-         var self = this,
 
-             c = xhrObj.config;
 
-         self.xhrObj = xhrObj;
 
-         var m = c.url.match(rurl);
 
-         self.__hostname = m[2];
 
-         self.__protocol = m[1];
 
-         c.crossDomain = false;
 
-     }
 
-     S.augment(SubDomain, XhrBase.proto, {
 
-         send:function() {
 
-             var self = this,
 
-                 c = self.xhrObj.config,
 
-                 hostname = self.__hostname,
 
-                 iframe,
 
-                 iframeDesc = iframeMap[hostname];
 
-             var proxy = PROXY_PAGE;
 
-             if (c['xdr'] && c['xdr']['subDomain'] && c['xdr']['subDomain'].proxy) {
 
-                 proxy = c['xdr']['subDomain'].proxy;
 
-             }
 
-             if (iframeDesc && iframeDesc.ready) {
 
-                 self.xhr = XhrBase.xhr(0, iframeDesc.iframe.contentWindow);
 
-                 if (self.xhr) {
 
-                     self.sendInternal();
 
-                 } else {
 
-                     S.error("document.domain not set correctly!");
 
-                 }
 
-                 return;
 
-             }
 
-             if (!iframeDesc) {
 
-                 iframeDesc = iframeMap[hostname] = {};
 
-                 iframe = iframeDesc.iframe = document.createElement("iframe");
 
-                 DOM.css(iframe, {
 
-                     position:'absolute',
 
-                     left:'-9999px',
 
-                     top:'-9999px'
 
-                 });
 
-                 DOM.prepend(iframe, doc.body || doc.documentElement);
 
-                 iframe.src = self.__protocol + "//" + hostname + proxy;
 
-             } else {
 
-                 iframe = iframeDesc.iframe;
 
-             }
 
-             Event.on(iframe, "load", _onLoad, self);
 
-         }
 
-     });
 
-     function _onLoad() {
 
-         var self = this,
 
-             hostname = self.__hostname,
 
-             iframeDesc = iframeMap[hostname];
 
-         iframeDesc.ready = 1;
 
-         Event.detach(iframeDesc.iframe, "load", _onLoad, self);
 
-         self.send();
 
-     }
 
-     return SubDomain;
 
- }, {
 
-     requires:['./xhrbase','event','dom']
 
- });
 
- /**
 
-  * use flash to accomplish cross domain request , usage scenario ? why not jsonp ?
 
-  * @author yiminghe@gmail.com
 
-  */
 
- KISSY.add("ajax/xdr", function(S, io, DOM) {
 
-     var // current running request instances
 
-         maps = {},
 
-         ID = "io_swf",
 
-         // flash transporter
 
-         flash,
 
-         doc = document,
 
-         // whether create the flash transporter
 
-         init = false;
 
-     // create the flash transporter
 
-     function _swf(uri, _, uid) {
 
-         if (init) {
 
-             return;
 
-         }
 
-         init = true;
 
-         var o = '<object id="' + ID +
 
-             '" type="application/x-shockwave-flash" data="' +
 
-             uri + '" width="0" height="0">' +
 
-             '<param name="movie" value="' +
 
-             uri + '" />' +
 
-             '<param name="FlashVars" value="yid=' +
 
-             _ + '&uid=' +
 
-             uid +
 
-             '&host=KISSY.io" />' +
 
-             '<param name="allowScriptAccess" value="always" />' +
 
-             '</object>',
 
-             c = doc.createElement('div');
 
-         DOM.prepend(c, doc.body || doc.documentElement);
 
-         c.innerHTML = o;
 
-     }
 
-     function XdrTransport(xhrObj) {
 
-         S.log("use flash xdr");
 
-         this.xhrObj = xhrObj;
 
-     }
 
-     S.augment(XdrTransport, {
 
-         // rewrite send to support flash xdr
 
-         send:function() {
 
-             var self = this,
 
-                 xhrObj = self.xhrObj,
 
-                 c = xhrObj.config;
 
-             var xdr = c['xdr'] || {};
 
-             // 不提供则使用 cdn 默认的 flash
 
-             _swf(xdr.src || (S.Config.base + "ajax/io.swf"), 1, 1);
 
-             // 简便起见,用轮训
 
-             if (!flash) {
 
-                 // S.log("detect xdr flash");
 
-                 setTimeout(function() {
 
-                     self.send();
 
-                 }, 200);
 
-                 return;
 
-             }
 
-             self._uid = S.guid();
 
-             maps[self._uid] = self;
 
-             // ie67 send 出错?
 
-             flash.send(c.url, {
 
-                 id:self._uid,
 
-                 uid:self._uid,
 
-                 method:c.type,
 
-                 data:c.hasContent && c.data || {}
 
-             });
 
-         },
 
-         abort:function() {
 
-             flash.abort(this._uid);
 
-         },
 
-         _xdrResponse:function(e, o) {
 
-             // S.log(e);
 
-             var self = this,
 
-                 ret,
 
-                 xhrObj = self.xhrObj;
 
-             // need decodeURI to get real value from flash returned value
 
-             xhrObj.responseText = decodeURI(o.c.responseText);
 
-             switch (e) {
 
-                 case 'success':
 
-                     ret = { status: 200, statusText: "success" };
 
-                     delete maps[o.id];
 
-                     break;
 
-                 case 'abort':
 
-                     delete maps[o.id];
 
-                     break;
 
-                 case 'timeout':
 
-                 case 'transport error':
 
-                 case 'failure':
 
-                     delete maps[o.id];
 
-                     ret = { status: 500, statusText: e };
 
-                     break;
 
-             }
 
-             if (ret) {
 
-                 xhrObj.callback(ret.status, ret.statusText);
 
-             }
 
-         }
 
-     });
 
-     /*called by flash*/
 
-     io['applyTo'] = function(_, cmd, args) {
 
-         // S.log(cmd + " execute");
 
-         var cmds = cmd.split("."),
 
-             func = S;
 
-         S.each(cmds, function(c) {
 
-             func = func[c];
 
-         });
 
-         func.apply(null, args);
 
-     };
 
-     // when flash is loaded
 
-     io['xdrReady'] = function() {
 
-         flash = doc.getElementById(ID);
 
-     };
 
-     /**
 
-      * when response is returned from server
 
-      * @param e response status
 
-      * @param o internal data
 
-      * @param c internal data
 
-      */
 
-     io['xdrResponse'] = function(e, o, c) {
 
-         var xhr = maps[o.uid];
 
-         xhr && xhr._xdrResponse(e, o, c);
 
-     };
 
-     // export io for flash to call
 
-     S.io = io;
 
-     return XdrTransport;
 
- }, {
 
-     requires:["./base",'dom']
 
- });
 
- /**
 
-  * ajax xhr transport class , route subdomain , xdr
 
-  * @author yiminghe@gmail.com
 
-  */
 
- KISSY.add("ajax/xhr", function(S, io, XhrBase, SubDomain, XdrTransport) {
 
-     var rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/;
 
-     var _XDomainRequest = window['XDomainRequest'];
 
-     var detectXhr = XhrBase.xhr();
 
-     if (detectXhr) {
 
-         // slice last two pars
 
-         // xx.taobao.com => taobao.com
 
-         function getMainDomain(host) {
 
-             var t = host.split('.');
 
-             if (t.length < 2) {
 
-                 return t.join(".");
 
-             } else {
 
-                 return t.reverse().slice(0, 2).reverse().join('.');
 
-             }
 
-         }
 
-         function XhrTransport(xhrObj) {
 
-             var c = xhrObj.config,
 
-                 xdrCfg = c['xdr'] || {};
 
-             if (c.crossDomain) {
 
-                 var parts = c.url.match(rurl);
 
-                 // 跨子域
 
-                 if (getMainDomain(location.hostname) == getMainDomain(parts[2])) {
 
-                     return new SubDomain(xhrObj);
 
-                 }
 
-                 /**
 
-                  * ie>7 强制使用 flash xdr
 
-                  */
 
-                 if (!("withCredentials" in detectXhr) &&
 
-                     (String(xdrCfg.use) === "flash" || !_XDomainRequest)) {
 
-                     return new XdrTransport(xhrObj);
 
-                 }
 
-             }
 
-             this.xhrObj = xhrObj;
 
-             return undefined;
 
-         }
 
-         S.augment(XhrTransport, XhrBase.proto, {
 
-             send:function() {
 
-                 var self = this,
 
-                     xhrObj = self.xhrObj,
 
-                     c = xhrObj.config;
 
-                 self.xhr = XhrBase.xhr(c.crossDomain);
 
-                 self.sendInternal();
 
-             }
 
-         });
 
-         io.setupTransport("*", XhrTransport);
 
-     }
 
-     return io;
 
- }, {
 
-     requires:["./base",'./xhrbase','./subdomain',"./xdr"]
 
- });
 
- /**
 
-  * 借鉴 jquery,优化使用原型替代闭包
 
-  **/
 
- /**
 
-  * script transport for kissy io
 
-  * @description: modified version of S.getScript , add abort ability
 
-  * @author  yiminghe@gmail.com
 
-  */
 
- KISSY.add("ajax/script", function(S, io) {
 
-     var doc = document;
 
-     var OK_CODE = 200,ERROR_CODE = 500;
 
-     io.setupConfig({
 
-         accepts:{
 
-             script:"text/javascript, " +
 
-                 "application/javascript, " +
 
-                 "application/ecmascript, " +
 
-                 "application/x-ecmascript"
 
-         },
 
-         contents:{
 
-             script:/javascript|ecmascript/
 
-         },
 
-         converters:{
 
-             text:{
 
-                 // 如果以 xhr+eval 需要下面的,
 
-                 // 否则直接 script node 不需要,引擎自己执行了,
 
-                 // 不需要手动 eval
 
-                 script:function(text) {
 
-                     S.globalEval(text);
 
-                     return text;
 
-                 }
 
-             }
 
-         }
 
-     });
 
-     function ScriptTransport(xhrObj) {
 
-         // 优先使用 xhr+eval 来执行脚本, ie 下可以探测到(更多)失败状态
 
-         if (!xhrObj.config.crossDomain &&
 
-             !xhrObj.config['forceScript']) {
 
-             return new (io.getTransport("*"))(xhrObj);
 
-         }
 
-         this.xhrObj = xhrObj;
 
-         return 0;
 
-     }
 
-     S.augment(ScriptTransport, {
 
-         send:function() {
 
-             var self = this,
 
-                 script,
 
-                 xhrObj = this.xhrObj,
 
-                 c = xhrObj.config,
 
-                 head = doc['head'] ||
 
-                     doc.getElementsByTagName("head")[0] ||
 
-                     doc.documentElement;
 
-             self.head = head;
 
-             script = doc.createElement("script");
 
-             self.script = script;
 
-             script.async = "async";
 
-             if (c['scriptCharset']) {
 
-                 script.charset = c['scriptCharset'];
 
-             }
 
-             script.src = c.url;
 
-             script.onerror =
 
-                 script.onload =
 
-                     script.onreadystatechange = function(e) {
 
-                         e = e || window.event;
 
-                         // firefox onerror 没有 type ?!
 
-                         self._callback((e.type || "error").toLowerCase());
 
-                     };
 
-             head.insertBefore(script, head.firstChild);
 
-         },
 
-         _callback:function(event, abort) {
 
-             var script = this.script,
 
-                 xhrObj = this.xhrObj,
 
-                 head = this.head;
 
-             // 防止重复调用,成功后 abort
 
-             if (!script) {
 
-                 return;
 
-             }
 
-             if (abort ||
 
-                 !script.readyState ||
 
-                 /loaded|complete/.test(script.readyState)
 
-                 || event == "error"
 
-                 ) {
 
-                 script['onerror'] = script.onload = script.onreadystatechange = null;
 
-                 // Remove the script
 
-                 if (head && script.parentNode) {
 
-                     // ie 报错载入无效 js
 
-                     // 怎么 abort ??
 
-                     // script.src = "#";
 
-                     head.removeChild(script);
 
-                 }
 
-                 this.script = undefined;
 
-                 this.head = undefined;
 
-                 // Callback if not abort
 
-                 if (!abort && event != "error") {
 
-                     xhrObj.callback(OK_CODE, "success");
 
-                 }
 
-                 // 非 ie<9 可以判断出来
 
-                 else if (event == "error") {
 
-                     xhrObj.callback(ERROR_CODE, "scripterror");
 
-                 }
 
-             }
 
-         },
 
-         abort:function() {
 
-             this._callback(0, 1);
 
-         }
 
-     });
 
-     io.setupTransport("script", ScriptTransport);
 
-     return io;
 
- }, {
 
-     requires:['./base','./xhr']
 
- });
 
- /**
 
-  * jsonp transport based on script transport
 
-  * @author  yiminghe@gmail.com
 
-  */
 
- KISSY.add("ajax/jsonp", function(S, io) {
 
-     io.setupConfig({
 
-         jsonp:"callback",
 
-         jsonpCallback:function() {
 
-             //不使用 now() ,极端情况下可能重复
 
-             return S.guid("jsonp");
 
-         }
 
-     });
 
-     io.on("start", function(e) {
 
-         var xhr = e.xhr,c = xhr.config;
 
-         if (c.dataType[0] == "jsonp") {
 
-             var response,
 
-                 cJsonpCallback = c.jsonpCallback,
 
-                 jsonpCallback = S.isFunction(cJsonpCallback) ?
 
-                     cJsonpCallback() :
 
-                     cJsonpCallback,
 
-                 previous = window[ jsonpCallback ];
 
-             c.url += ( /\?/.test(c.url) ? "&" : "?" ) + c.jsonp + "=" + jsonpCallback;
 
-             // build temporary JSONP function
 
-             window[jsonpCallback] = function(r) {
 
-                 // 使用数组,区别:故意调用了 jsonpCallback(undefined) 与 根本没有调用
 
-                 // jsonp 返回了数组
 
-                 if (arguments.length > 1) {
 
-                     r = S.makeArray(arguments);
 
-                 }
 
-                 response = [r];
 
-             };
 
-             // cleanup whether success or failure
 
-             xhr.on("complete", function() {
 
-                 window[ jsonpCallback ] = previous;
 
-                 if (previous === undefined) {
 
-                     try {
 
-                         delete window[ jsonpCallback ];
 
-                     } catch(e) {
 
-                         //S.log("delete window variable error : ");
 
-                         //S.log(e);
 
-                     }
 
-                 } else if (response) {
 
-                     // after io success handler called
 
-                     // then call original existed jsonpcallback
 
-                     previous(response[0]);
 
-                 }
 
-             });
 
-             xhr.converters = xhr.converters || {};
 
-             xhr.converters.script = xhr.converters.script || {};
 
-             // script -> jsonp ,jsonp need to see json not as script
 
-             xhr.converters.script.json = function() {
 
-                 if (!response) {
 
-                     S.error(" not call jsonpCallback : " + jsonpCallback)
 
-                 }
 
-                 return response[0];
 
-             };
 
-             c.dataType.length = 2;
 
-             // 利用 script transport 发送 script 请求
 
-             c.dataType[0] = 'script';
 
-             c.dataType[1] = 'json';
 
-         }
 
-     });
 
-     return io;
 
- }, {
 
-     requires:['./base']
 
- });
 
- KISSY.add("ajax/form", function(S, io, DOM, FormSerializer) {
 
-     io.on("start", function(e) {
 
-         var xhr = e.xhr,
 
-             c = xhr.config;
 
-         // serialize form if needed
 
-         if (c.form) {
 
-             var form = DOM.get(c.form),
 
-                 enctype = form['encoding'] || form.enctype;
 
-             // 上传有其他方法
 
-             if (enctype.toLowerCase() != "multipart/form-data") {
 
-                 // when get need encode
 
-                 var formParam = FormSerializer.serialize(form);
 
-                 if (formParam) {
 
-                     if (c.hasContent) {
 
-                         // post 加到 data 中
 
-                         c.data = c.data || "";
 
-                         if (c.data) {
 
-                             c.data += "&";
 
-                         }
 
-                         c.data += formParam;
 
-                     } else {
 
-                         // get 直接加到 url
 
-                         c.url += ( /\?/.test(c.url) ? "&" : "?" ) + formParam;
 
-                     }
 
-                 }
 
-             } else {
 
-                 var d = c.dataType[0];
 
-                 if (d == "*") {
 
-                     d = "text";
 
-                 }
 
-                 c.dataType.length = 2;
 
-                 c.dataType[0] = "iframe";
 
-                 c.dataType[1] = d;
 
-             }
 
-         }
 
-     });
 
-     return io;
 
- }, {
 
-         requires:['./base',"dom","./form-serializer"]
 
-     });
 
- /**
 
-  * non-refresh upload file with form by iframe
 
-  * @author  yiminghe@gmail.com
 
-  */
 
- KISSY.add("ajax/iframe-upload", function(S, DOM, Event, io) {
 
-     var doc = document;
 
-     var OK_CODE = 200,ERROR_CODE = 500,BREATH_INTERVAL = 30;
 
-     // iframe 内的内容就是 body.innerText
 
-     io.setupConfig({
 
-         converters:{
 
-             // iframe 到其他类型的转化和 text 一样
 
-             iframe:io.getConfig().converters.text,
 
-             text:{
 
-                 iframe:function(text) {
 
-                     return text;
 
-                 }
 
-             }}});
 
-     function createIframe(xhr) {
 
-         var id = S.guid("ajax-iframe");
 
-         xhr.iframe = DOM.create("<iframe " +
 
-             " id='" + id + "'" +
 
-             // need name for target of form
 
-             " name='" + id + "'" +
 
-             " style='position:absolute;left:-9999px;top:-9999px;'/>");
 
-         xhr.iframeId = id;
 
-         DOM.prepend(xhr.iframe, doc.body || doc.documentElement);
 
-     }
 
-     function addDataToForm(data, form, serializeArray) {
 
-         data = S.unparam(data);
 
-         var ret = [];
 
-         for (var d in data) {
 
-             var isArray = S.isArray(data[d]),
 
-                 vs = S.makeArray(data[d]);
 
-             // 数组和原生一样对待,创建多个同名输入域
 
-             for (var i = 0; i < vs.length; i++) {
 
-                 var e = doc.createElement("input");
 
-                 e.type = 'hidden';
 
-                 e.name = d + (isArray && serializeArray ? "[]" : "");
 
-                 e.value = vs[i];
 
-                 DOM.append(e, form);
 
-                 ret.push(e);
 
-             }
 
-         }
 
-         return ret;
 
-     }
 
-     function removeFieldsFromData(fields) {
 
-         DOM.remove(fields);
 
-     }
 
-     function IframeTransport(xhr) {
 
-         this.xhr = xhr;
 
-     }
 
-     S.augment(IframeTransport, {
 
-         send:function() {
 
-             //debugger
 
-             var xhr = this.xhr,
 
-                 c = xhr.config,
 
-                 fields,
 
-                 form = DOM.get(c.form);
 
-             this.attrs = {
 
-                 target:DOM.attr(form, "target") || "",
 
-                 action:DOM.attr(form, "action") || ""
 
-             };
 
-             this.form = form;
 
-             createIframe(xhr);
 
-             // set target to iframe to avoid main page refresh
 
-             DOM.attr(form, {"target": xhr.iframeId,"action": c.url});
 
-             if (c.data) {
 
-                 fields = addDataToForm(c.data, form, c.serializeArray);
 
-             }
 
-             this.fields = fields;
 
-             var iframe = xhr.iframe;
 
-             Event.on(iframe, "load error", this._callback, this);
 
-             form.submit();
 
-         },
 
-         _callback:function(event
 
-                            //, abort
 
-             ) {
 
-             //debugger
 
-             var form = this.form,
 
-                 xhr = this.xhr,
 
-                 eventType = event.type,
 
-                 iframe = xhr.iframe;
 
-             // 防止重复调用 , 成功后 abort
 
-             if (!iframe) {
 
-                 return;
 
-             }
 
-             DOM.attr(form, this.attrs);
 
-             if (eventType == "load") {
 
-                 var iframeDoc = iframe.contentWindow.document;
 
-                 xhr.responseXML = iframeDoc;
 
-                 xhr.responseText = DOM.text(iframeDoc.body);
 
-                 xhr.callback(OK_CODE, "success");
 
-             } else if (eventType == 'error') {
 
-                 xhr.callback(ERROR_CODE, "error");
 
-             }
 
-             removeFieldsFromData(this.fields);
 
-             Event.detach(iframe);
 
-             setTimeout(function() {
 
-                 // firefox will keep loading if not settimeout
 
-                 DOM.remove(iframe);
 
-             }, BREATH_INTERVAL);
 
-             // nullify to prevent memory leak?
 
-             xhr.iframe = null;
 
-         },
 
-         abort:function() {
 
-             this._callback(0, 1);
 
-         }
 
-     });
 
-     io.setupTransport("iframe", IframeTransport);
 
-     return io;
 
- }, {
 
-     requires:["dom","event","./base"]
 
- });
 
- KISSY.add("ajax", function(S, serializer, io) {
 
-     var undef = undefined;
 
-     // some shortcut
 
-     S.mix(io, {
 
-         /**
 
-          * form 序列化
 
-          * @param formElement {HTMLFormElement} 将要序列化的 form 元素
 
-          */
 
-         serialize:serializer.serialize,
 
-         get: function(url, data, callback, dataType, _t) {
 
-             // data 参数可省略
 
-             if (S.isFunction(data)) {
 
-                 dataType = callback;
 
-                 callback = data;
 
-                 data = undef;
 
-             }
 
-             return io({
 
-                 type: _t || "get",
 
-                 url: url,
 
-                 data: data,
 
-                 success: callback,
 
-                 dataType: dataType
 
-             });
 
-         },
 
-         post: function(url, data, callback, dataType) {
 
-             if (S.isFunction(data)) {
 
-                 dataType = callback;
 
-                 callback = data;
 
-                 data = undef;
 
-             }
 
-             return io.get(url, data, callback, dataType, "post");
 
-         },
 
-         jsonp: function(url, data, callback) {
 
-             if (S.isFunction(data)) {
 
-                 callback = data;
 
-                 data = undef;
 
-             }
 
-             return io.get(url, data, callback, "jsonp");
 
-         },
 
-         // 和 S.getScript 保持一致
 
-         // 更好的 getScript 可以用
 
-         /*
 
-          io({
 
-          dataType:'script'
 
-          });
 
-          */
 
-         getScript:S.getScript,
 
-         getJSON: function(url, data, callback) {
 
-             if (S.isFunction(data)) {
 
-                 callback = data;
 
-                 data = undef;
 
-             }
 
-             return io.get(url, data, callback, "json");
 
-         },
 
-         upload:function(url, form, data, callback, dataType) {
 
-             if (S.isFunction(data)) {
 
-                 dataType = callback;
 
-                 callback = data;
 
-                 data = undef;
 
-             }
 
-             return io({
 
-                 url:url,
 
-                 type:'post',
 
-                 dataType:dataType,
 
-                 form:form,
 
-                 data:data,
 
-                 success:callback
 
-             });
 
-         }
 
-     });
 
-     return io;
 
- }, {
 
-     requires:[
 
-         "ajax/form-serializer",
 
-         "ajax/base",
 
-         "ajax/xhrobject",
 
-         "ajax/xhr",
 
-         "ajax/script",
 
-         "ajax/jsonp",
 
-         "ajax/form",
 
-         "ajax/iframe-upload"]
 
- });
 
- /**
 
-  * @module  Attribute
 
-  * @author  yiminghe@gmail.com, lifesinger@gmail.com
 
-  */
 
- KISSY.add('base/attribute', function(S, undef) {
 
-     // atomic flag
 
-     Attribute.INVALID = {};
 
-     var INVALID = Attribute.INVALID;
 
-     /**
 
-      *
 
-      * @param host
 
-      * @param method
 
-      * @return method if fn or host[method]
 
-      */
 
-     function normalFn(host, method) {
 
-         if (S.isString(method)) {
 
-             return host[method];
 
-         }
 
-         return method;
 
-     }
 
-     /**
 
-      * fire attribute value change
 
-      */
 
-     function __fireAttrChange(self, when, name, prevVal, newVal, subAttrName, attrName) {
 
-         attrName = attrName || name;
 
-         return self.fire(when + capitalFirst(name) + 'Change', {
 
-             attrName: attrName,
 
-             subAttrName:subAttrName,
 
-             prevVal: prevVal,
 
-             newVal: newVal
 
-         });
 
-     }
 
-     /**
 
-      *
 
-      * @param obj
 
-      * @param name
 
-      * @param create
 
-      * @return non-empty property value of obj
 
-      */
 
-     function ensureNonEmpty(obj, name, create) {
 
-         var ret = obj[name] || {};
 
-         if (create) {
 
-             obj[name] = ret;
 
-         }
 
-         return ret;
 
-     }
 
-     /**
 
-      *
 
-      * @param self
 
-      * @return non-empty attr config holder
 
-      */
 
-     function getAttrs(self) {
 
-         /**
 
-          * attribute meta information
 
-          {
 
-          attrName: {
 
-          getter: function,
 
-          setter: function,
 
-          // 注意:只能是普通对象以及系统内置类型,而不能是 new Xx(),否则用 valueFn 替代
 
-          value: v, // default value
 
-          valueFn: function
 
-          }
 
-          }
 
-          */
 
-         return ensureNonEmpty(self, "__attrs", true);
 
-     }
 
-     /**
 
-      *
 
-      * @param self
 
-      * @return non-empty attr value holder
 
-      */
 
-     function getAttrVals(self) {
 
-         /**
 
-          * attribute value
 
-          {
 
-          attrName: attrVal
 
-          }
 
-          */
 
-         return ensureNonEmpty(self, "__attrVals", true);
 
-     }
 
-     /**
 
-      * o, [x,y,z] => o[x][y][z]
 
-      * @param o
 
-      * @param path
 
-      */
 
-     function getValueByPath(o, path) {
 
-         for (var i = 0,len = path.length;
 
-              o != undef && i < len;
 
-              i++) {
 
-             o = o[path[i]];
 
-         }
 
-         return o;
 
-     }
 
-     /**
 
-      * o, [x,y,z], val => o[x][y][z]=val
 
-      * @param o
 
-      * @param path
 
-      * @param val
 
-      */
 
-     function setValueByPath(o, path, val) {
 
-         var rlen = path.length - 1,
 
-             s = o;
 
-         if (rlen >= 0) {
 
-             for (var i = 0; i < rlen; i++) {
 
-                 o = o[path[i]];
 
-             }
 
-             if (o != undef) {
 
-                 o[path[i]] = val;
 
-             } else {
 
-                 s = undef;
 
-             }
 
-         }
 
-         return s;
 
-     }
 
-     function setInternal(self, name, value, opts, attrs) {
 
-         var ret;
 
-         opts = opts || {};
 
-         var dot = ".",
 
-             path,
 
-             subVal,
 
-             prevVal,
 
-             fullName = name;
 
-         if (name.indexOf(dot) !== -1) {
 
-             path = name.split(dot);
 
-             name = path.shift();
 
-         }
 
-         prevVal = self.get(name);
 
-         if (path) {
 
-             subVal = getValueByPath(prevVal, path);
 
-         }
 
-         // if no change, just return
 
-         if (!path && prevVal === value) {
 
-             return undefined;
 
-         } else if (path && subVal === value) {
 
-             return undefined;
 
-         }
 
-         if (path) {
 
-             var tmp = S.clone(prevVal);
 
-             setValueByPath(tmp, path, value);
 
-             value = tmp;
 
-         }
 
-         // check before event
 
-         if (!opts['silent']) {
 
-             if (false === __fireAttrChange(self, 'before', name, prevVal, value, fullName)) {
 
-                 return false;
 
-             }
 
-         }
 
-         // set it
 
-         ret = self.__set(name, value);
 
-         if (ret === false) {
 
-             return ret;
 
-         }
 
-         // fire after event
 
-         if (!opts['silent']) {
 
-             value = getAttrVals(self)[name];
 
-             __fireAttrChange(self, 'after', name, prevVal, value, fullName);
 
-             if (!attrs) {
 
-                 __fireAttrChange(self,
 
-                     '', '*',
 
-                     [prevVal], [value],
 
-                     [fullName], [name]);
 
-             } else {
 
-                 attrs.push({
 
-                     prevVal:prevVal,
 
-                     newVal:value,
 
-                     attrName:name,
 
-                     subAttrName:fullName
 
-                 });
 
-             }
 
-         }
 
-         return self;
 
-     }
 
-     /**
 
-      * 提供属性管理机制
 
-      * @name Attribute
 
-      * @class
 
-      */
 
-     function Attribute() {
 
-     }
 
-     S.augment(Attribute, {
 
-         /**
 
-          * @return un-cloned attr config collections
 
-          */
 
-         getAttrs: function() {
 
-             return getAttrs(this);
 
-         },
 
-         /**
 
-          * @return un-cloned attr value collections
 
-          */
 
-         getAttrVals:function() {
 
-             var self = this,
 
-                 o = {},
 
-                 a,
 
-                 attrs = getAttrs(self);
 
-             for (a in attrs) {
 
-                 o[a] = self.get(a);
 
-             }
 
-             return o;
 
-         },
 
-         /**
 
-          * Adds an attribute with the provided configuration to the host object.
 
-          * @param {String} name attrName
 
-          * @param {Object} attrConfig The config supports the following properties:
 
-          * {
 
-          *     value: 'the default value', // 最好不要使用自定义类生成的对象,这时使用 valueFn
 
-          *     valueFn: function //
 
-          *     setter: function
 
-          *     getter: function
 
-          * }
 
-          * @param {boolean} override whether override existing attribute config ,default true
 
-          */
 
-         addAttr: function(name, attrConfig, override) {
 
-             var self = this,
 
-                 attrs = getAttrs(self),
 
-                 cfg = S.clone(attrConfig);
 
-             if (!attrs[name]) {
 
-                 attrs[name] = cfg;
 
-             } else {
 
-                 S.mix(attrs[name], cfg, override);
 
-             }
 
-             return self;
 
-         },
 
-         /**
 
-          * Configures a group of attributes, and sets initial values.
 
-          * @param {Object} attrConfigs  An object with attribute name/configuration pairs.
 
-          * @param {Object} initialValues user defined initial values
 
-          */
 
-         addAttrs: function(attrConfigs, initialValues) {
 
-             var self = this;
 
-             S.each(attrConfigs, function(attrConfig, name) {
 
-                 self.addAttr(name, attrConfig);
 
-             });
 
-             if (initialValues) {
 
-                 self.set(initialValues);
 
-             }
 
-             return self;
 
-         },
 
-         /**
 
-          * Checks if the given attribute has been added to the host.
 
-          */
 
-         hasAttr: function(name) {
 
-             return name && getAttrs(this).hasOwnProperty(name);
 
-         },
 
-         /**
 
-          * Removes an attribute from the host object.
 
-          */
 
-         removeAttr: function(name) {
 
-             var self = this;
 
-             if (self.hasAttr(name)) {
 
-                 delete getAttrs(self)[name];
 
-                 delete getAttrVals(self)[name];
 
-             }
 
-             return self;
 
-         },
 
-         /**
 
-          * Sets the value of an attribute.
 
-          */
 
-         set: function(name, value, opts) {
 
-             var ret,self = this;
 
-             if (S.isPlainObject(name)) {
 
-                 var all = name;
 
-                 name = 0;
 
-                 ret = true;
 
-                 opts = value;
 
-                 var attrs = [];
 
-                 for (name in all) {
 
-                     ret = setInternal(self, name, all[name], opts, attrs);
 
-                     if (ret === false) {
 
-                         break;
 
-                     }
 
-                 }
 
-                 var attrNames = [],
 
-                     prevVals = [],
 
-                     newVals = [],
 
-                     subAttrNames = [];
 
-                 S.each(attrs, function(attr) {
 
-                     prevVals.push(attr.prevVal);
 
-                     newVals.push(attr.newVal);
 
-                     attrNames.push(attr.attrName);
 
-                     subAttrNames.push(attr.subAttrName);
 
-                 });
 
-                 if (attrNames.length) {
 
-                     __fireAttrChange(self,
 
-                         '',
 
-                         '*',
 
-                         prevVals,
 
-                         newVals,
 
-                         subAttrNames,
 
-                         attrNames);
 
-                 }
 
-                 return ret;
 
-             }
 
-             return setInternal(self, name, value, opts);
 
-         },
 
-         /**
 
-          * internal use, no event involved, just set.
 
-          * @protected overriden by mvc/model
 
-          */
 
-         __set: function(name, value) {
 
-             var self = this,
 
-                 setValue,
 
-                 // if host does not have meta info corresponding to (name,value)
 
-                 // then register on demand in order to collect all data meta info
 
-                 // 一定要注册属性元数据,否则其他模块通过 _attrs 不能枚举到所有有效属性
 
-                 // 因为属性在声明注册前可以直接设置值
 
-                 attrConfig = ensureNonEmpty(getAttrs(self), name, true),
 
-                 validator = attrConfig['validator'],
 
-                 setter = attrConfig['setter'];
 
-             // validator check
 
-             if (validator = normalFn(self, validator)) {
 
-                 if (validator.call(self, value, name) === false) {
 
-                     return false;
 
-                 }
 
-             }
 
-             // if setter has effect
 
-             if (setter = normalFn(self, setter)) {
 
-                 setValue = setter.call(self, value, name);
 
-             }
 
-             if (setValue === INVALID) {
 
-                 return false;
 
-             }
 
-             if (setValue !== undef) {
 
-                 value = setValue;
 
-             }
 
-             // finally set
 
-             getAttrVals(self)[name] = value;
 
-         },
 
-         /**
 
-          * Gets the current value of the attribute.
 
-          */
 
-         get: function(name) {
 
-             var self = this,
 
-                 dot = ".",
 
-                 path,
 
-                 attrConfig,
 
-                 getter, ret;
 
-             if (name.indexOf(dot) !== -1) {
 
-                 path = name.split(dot);
 
-                 name = path.shift();
 
-             }
 
-             attrConfig = ensureNonEmpty(getAttrs(self), name);
 
-             getter = attrConfig['getter'];
 
-             // get user-set value or default value
 
-             //user-set value takes privilege
 
-             ret = name in getAttrVals(self) ?
 
-                 getAttrVals(self)[name] :
 
-                 self.__getDefAttrVal(name);
 
-             // invoke getter for this attribute
 
-             if (getter = normalFn(self, getter)) {
 
-                 ret = getter.call(self, ret, name);
 
-             }
 
-             if (path) {
 
-                 ret = getValueByPath(ret, path);
 
-             }
 
-             return ret;
 
-         },
 
-         /**
 
-          * get default attribute value from valueFn/value
 
-          * @private
 
-          * @param name
 
-          */
 
-         __getDefAttrVal: function(name) {
 
-             var self = this,
 
-                 attrConfig = ensureNonEmpty(getAttrs(self), name),
 
-                 valFn,
 
-                 val;
 
-             if ((valFn = normalFn(self, attrConfig.valueFn))) {
 
-                 val = valFn.call(self);
 
-                 if (val !== undef) {
 
-                     attrConfig.value = val;
 
-                 }
 
-                 delete attrConfig.valueFn;
 
-                 getAttrs(self)[name] = attrConfig;
 
-             }
 
-             return attrConfig.value;
 
-         },
 
-         /**
 
-          * Resets the value of an attribute.just reset what addAttr set  (not what invoker set when call new Xx(cfg))
 
-          * @param {String} name name of attribute
 
-          */
 
-         reset: function (name, opts) {
 
-             var self = this;
 
-             if (S.isString(name)) {
 
-                 if (self.hasAttr(name)) {
 
-                     // if attribute does not have default value, then set to undefined.
 
-                     return self.set(name, self.__getDefAttrVal(name), opts);
 
-                 }
 
-                 else {
 
-                     return self;
 
-                 }
 
-             }
 
-             opts = name;
 
-             var attrs = getAttrs(self),
 
-                 values = {};
 
-             // reset all
 
-             for (name in attrs) {
 
-                 values[name] = self.__getDefAttrVal(name);
 
-             }
 
-             self.set(values, opts);
 
-             return self;
 
-         }
 
-     });
 
-     function capitalFirst(s) {
 
-         return s.charAt(0).toUpperCase() + s.substring(1);
 
-     }
 
-     if (undef) {
 
-         Attribute.prototype.addAttrs = undef;
 
-     }
 
-     return Attribute;
 
- });
 
- /**
 
-  *  2011-10-18
 
-  *    get/set sub attribute value ,set("x.y",val) x 最好为 {} ,不要是 new Clz() 出来的
 
-  *    add validator
 
-  */
 
- /**
 
-  * @module  Base
 
-  * @author  yiminghe@gmail.com,lifesinger@gmail.com
 
-  */
 
- KISSY.add('base/base', function (S, Attribute, Event) {
 
-     /**
 
-      * Base for class-based component
 
-      * @name Base
 
-      * @extends Event.Target
 
-      * @extends Attribute
 
-      * @class
 
-      */
 
-     function Base(config) {
 
-         var c = this.constructor;
 
-         // define
 
-         while (c) {
 
-             addAttrs(this, c['ATTRS']);
 
-             c = c.superclass ? c.superclass.constructor : null;
 
-         }
 
-         // initial
 
-         initAttrs(this, config);
 
-     }
 
-     function addAttrs(host, attrs) {
 
-         if (attrs) {
 
-             for (var attr in attrs) {
 
-                 // 子类上的 ATTRS 配置优先
 
-                 if (attrs.hasOwnProperty(attr)) {
 
-                     // 父类后加,父类不覆盖子类的相同设置
 
-                     // 属性对象会 merge   a: {y:{getter:fn}}, b:{y:{value:3}}, b extends a => b {y:{value:3}}
 
-                     host.addAttr(attr, attrs[attr], false);
 
-                 }
 
-             }
 
-         }
 
-     }
 
-     function initAttrs(host, config) {
 
-         if (config) {
 
-             for (var attr in config) {
 
-                 if (config.hasOwnProperty(attr)) {
 
-                     //用户设置会调用 setter/validator 的,但不会触发属性变化事件
 
-                     host.__set(attr, config[attr]);
 
-                 }
 
-             }
 
-         }
 
-     }
 
-     S.augment(Base, Event.Target, Attribute);
 
-     return Base;
 
- }, {
 
-     requires:["./attribute","event"]
 
- });
 
- KISSY.add("base", function(S, Base, Attribute) {
 
-     Base.Attribute = Attribute;
 
-     return Base;
 
- }, {
 
-     requires:["base/base","base/attribute"]
 
- });
 
- /**
 
-  * @module  cookie
 
-  * @author  lifesinger@gmail.com
 
-  */
 
- KISSY.add('cookie/base', function(S) {
 
-     var doc = document,
 
-         MILLISECONDS_OF_DAY = 24 * 60 * 60 * 1000,
 
-         encode = encodeURIComponent,
 
-         decode = decodeURIComponent;
 
-     function isNotEmptyString(val) {
 
-         return S.isString(val) && val !== '';
 
-     }
 
-     return {
 
-         /**
 
-          * 获取 cookie 值
 
-          * @return {string} 如果 name 不存在,返回 undefined
 
-          */
 
-         get: function(name) {
 
-             var ret, m;
 
-             if (isNotEmptyString(name)) {
 
-                 if ((m = String(doc.cookie).match(
 
-                     new RegExp('(?:^| )' + name + '(?:(?:=([^;]*))|;|$)')))) {
 
-                     ret = m[1] ? decode(m[1]) : '';
 
-                 }
 
-             }
 
-             return ret;
 
-         },
 
-         set: function(name, val, expires, domain, path, secure) {
 
-             var text = String(encode(val)), date = expires;
 
-             // 从当前时间开始,多少天后过期
 
-             if (typeof date === 'number') {
 
-                 date = new Date();
 
-                 date.setTime(date.getTime() + expires * MILLISECONDS_OF_DAY);
 
-             }
 
-             // expiration date
 
-             if (date instanceof Date) {
 
-                 text += '; expires=' + date.toUTCString();
 
-             }
 
-             // domain
 
-             if (isNotEmptyString(domain)) {
 
-                 text += '; domain=' + domain;
 
-             }
 
-             // path
 
-             if (isNotEmptyString(path)) {
 
-                 text += '; path=' + path;
 
-             }
 
-             // secure
 
-             if (secure) {
 
-                 text += '; secure';
 
-             }
 
-             //S.log(text);
 
-             doc.cookie = name + '=' + text;
 
-         },
 
-         remove: function(name, domain, path, secure) {
 
-             // 置空,并立刻过期
 
-             this.set(name, '', -1, domain, path, secure);
 
-         }
 
-     };
 
- });
 
- /**
 
-  * NOTES:
 
-  *
 
-  *  2010.04
 
-  *   - get 方法要考虑 ie 下,
 
-  *     值为空的 cookie 为 'test3; test3=3; test3tt=2; test1=t1test3; test3', 没有等于号。
 
-  *     除了正则获取,还可以 split 字符串的方式来获取。
 
-  *   - api 设计上,原本想借鉴 jQuery 的简明风格:S.cookie(name, ...), 但考虑到可扩展性,目前
 
-  *     独立成静态工具类的方式更优。
 
-  */
 
- KISSY.add("cookie", function(S,C) {
 
-     return C;
 
- }, {
 
-     requires:["cookie/base"]
 
- });
 
- KISSY.add("core", function(S, UA, DOM, Event, Node, JSON, Ajax, Anim, Base, Cookie) {
 
-     var re = {
 
-         UA:UA,
 
-         DOM:DOM,
 
-         Event:Event,
 
-         EventTarget:Event.Target,
 
-         "EventObject":Event.Object,
 
-         Node:Node,
 
-         NodeList:Node,
 
-         JSON:JSON,
 
-         "Ajax":Ajax,
 
-         "IO":Ajax,
 
-         ajax:Ajax,
 
-         io:Ajax,
 
-         jsonp:Ajax.jsonp,
 
-         Anim:Anim,
 
-         Easing:Anim.Easing,
 
-         Base:Base,
 
-         "Cookie":Cookie,
 
-         one:Node.one,
 
-         all:Node.all,
 
-         get:DOM.get,
 
-         query:DOM.query
 
-     };
 
-     S.mix(S, re);
 
-     return re;
 
- }, {
 
-     requires:[
 
-         "ua",
 
-         "dom",
 
-         "event",
 
-         "node",
 
-         "json",
 
-         "ajax",
 
-         "anim",
 
-         "base",
 
-         "cookie"
 
-     ]
 
- });
 
- KISSY.use('core');
 
 
  |