cos-js-sdk-v5.js 419 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079
  1. (function webpackUniversalModuleDefinition(root, factory) {
  2. if(typeof exports === 'object' && typeof module === 'object')
  3. module.exports = factory();
  4. else if(typeof define === 'function' && define.amd)
  5. define([], factory);
  6. else if(typeof exports === 'object')
  7. exports["COS"] = factory();
  8. else
  9. root["COS"] = factory();
  10. })(typeof self !== 'undefined' ? self : this, function() {
  11. return /******/ (function(modules) { // webpackBootstrap
  12. /******/ // The module cache
  13. /******/ var installedModules = {};
  14. /******/
  15. /******/ // The require function
  16. /******/ function __webpack_require__(moduleId) {
  17. /******/
  18. /******/ // Check if module is in cache
  19. /******/ if(installedModules[moduleId]) {
  20. /******/ return installedModules[moduleId].exports;
  21. /******/ }
  22. /******/ // Create a new module (and put it into the cache)
  23. /******/ var module = installedModules[moduleId] = {
  24. /******/ i: moduleId,
  25. /******/ l: false,
  26. /******/ exports: {}
  27. /******/ };
  28. /******/
  29. /******/ // Execute the module function
  30. /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  31. /******/
  32. /******/ // Flag the module as loaded
  33. /******/ module.l = true;
  34. /******/
  35. /******/ // Return the exports of the module
  36. /******/ return module.exports;
  37. /******/ }
  38. /******/
  39. /******/
  40. /******/ // expose the modules object (__webpack_modules__)
  41. /******/ __webpack_require__.m = modules;
  42. /******/
  43. /******/ // expose the module cache
  44. /******/ __webpack_require__.c = installedModules;
  45. /******/
  46. /******/ // define getter function for harmony exports
  47. /******/ __webpack_require__.d = function(exports, name, getter) {
  48. /******/ if(!__webpack_require__.o(exports, name)) {
  49. /******/ Object.defineProperty(exports, name, {
  50. /******/ configurable: false,
  51. /******/ enumerable: true,
  52. /******/ get: getter
  53. /******/ });
  54. /******/ }
  55. /******/ };
  56. /******/
  57. /******/ // getDefaultExport function for compatibility with non-harmony modules
  58. /******/ __webpack_require__.n = function(module) {
  59. /******/ var getter = module && module.__esModule ?
  60. /******/ function getDefault() { return module['default']; } :
  61. /******/ function getModuleExports() { return module; };
  62. /******/ __webpack_require__.d(getter, 'a', getter);
  63. /******/ return getter;
  64. /******/ };
  65. /******/
  66. /******/ // Object.prototype.hasOwnProperty.call
  67. /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
  68. /******/
  69. /******/ // __webpack_public_path__
  70. /******/ __webpack_require__.p = "/dist/";
  71. /******/
  72. /******/ // Load entry module and return exports
  73. /******/ return __webpack_require__(__webpack_require__.s = 4);
  74. /******/ })
  75. /************************************************************************/
  76. /******/ ([
  77. /* 0 */
  78. /***/ (function(module, exports, __webpack_require__) {
  79. "use strict";
  80. var md5 = __webpack_require__(6);
  81. var CryptoJS = __webpack_require__(7);
  82. var xml2json = __webpack_require__(8);
  83. var json2xml = __webpack_require__(11);
  84. function camSafeUrlEncode(str) {
  85. return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A');
  86. }
  87. //测试用的key后面可以去掉
  88. var getAuth = function (opt) {
  89. opt = opt || {};
  90. var SecretId = opt.SecretId;
  91. var SecretKey = opt.SecretKey;
  92. var KeyTime = opt.KeyTime;
  93. var method = (opt.method || opt.Method || 'get').toLowerCase();
  94. var queryParams = clone(opt.Query || opt.params || {});
  95. var headers = clone(opt.Headers || opt.headers || {});
  96. var Key = opt.Key || '';
  97. var pathname;
  98. if (opt.UseRawKey) {
  99. pathname = opt.Pathname || opt.pathname || '/' + Key;
  100. } else {
  101. pathname = opt.Pathname || opt.pathname || Key;
  102. pathname.indexOf('/') !== 0 && (pathname = '/' + pathname);
  103. }
  104. if (!SecretId) return console.error('missing param SecretId');
  105. if (!SecretKey) return console.error('missing param SecretKey');
  106. var getObjectKeys = function (obj) {
  107. var list = [];
  108. for (var key in obj) {
  109. if (obj.hasOwnProperty(key)) {
  110. list.push(key);
  111. }
  112. }
  113. return list.sort(function (a, b) {
  114. a = a.toLowerCase();
  115. b = b.toLowerCase();
  116. return a === b ? 0 : a > b ? 1 : -1;
  117. });
  118. };
  119. var obj2str = function (obj) {
  120. var i, key, val;
  121. var list = [];
  122. var keyList = getObjectKeys(obj);
  123. for (i = 0; i < keyList.length; i++) {
  124. key = keyList[i];
  125. val = obj[key] === undefined || obj[key] === null ? '' : '' + obj[key];
  126. key = key.toLowerCase();
  127. key = camSafeUrlEncode(key);
  128. val = camSafeUrlEncode(val) || '';
  129. list.push(key + '=' + val);
  130. }
  131. return list.join('&');
  132. };
  133. // 签名有效起止时间
  134. var now = Math.round(getSkewTime(opt.SystemClockOffset) / 1000) - 1;
  135. var exp = now;
  136. var Expires = opt.Expires || opt.expires;
  137. if (Expires === undefined) {
  138. exp += 900; // 签名过期时间为当前 + 900s
  139. } else {
  140. exp += Expires * 1 || 0;
  141. }
  142. // 要用到的 Authorization 参数列表
  143. var qSignAlgorithm = 'sha1';
  144. var qAk = SecretId;
  145. var qSignTime = KeyTime || now + ';' + exp;
  146. var qKeyTime = KeyTime || now + ';' + exp;
  147. var qHeaderList = getObjectKeys(headers).join(';').toLowerCase();
  148. var qUrlParamList = getObjectKeys(queryParams).join(';').toLowerCase();
  149. // 签名算法说明文档:https://www.qcloud.com/document/product/436/7778
  150. // 步骤一:计算 SignKey
  151. var signKey = CryptoJS.HmacSHA1(qKeyTime, SecretKey).toString();
  152. // 步骤二:构成 FormatString
  153. var formatString = [method, pathname, obj2str(queryParams), obj2str(headers), ''].join('\n');
  154. // 步骤三:计算 StringToSign
  155. var stringToSign = ['sha1', qSignTime, CryptoJS.SHA1(formatString).toString(), ''].join('\n');
  156. // 步骤四:计算 Signature
  157. var qSignature = CryptoJS.HmacSHA1(stringToSign, signKey).toString();
  158. // 步骤五:构造 Authorization
  159. var authorization = ['q-sign-algorithm=' + qSignAlgorithm, 'q-ak=' + qAk, 'q-sign-time=' + qSignTime, 'q-key-time=' + qKeyTime, 'q-header-list=' + qHeaderList, 'q-url-param-list=' + qUrlParamList, 'q-signature=' + qSignature].join('&');
  160. return authorization;
  161. };
  162. var noop = function () {};
  163. // 清除对象里值为的 undefined 或 null 的属性
  164. var clearKey = function (obj) {
  165. var retObj = {};
  166. for (var key in obj) {
  167. if (obj.hasOwnProperty(key) && obj[key] !== undefined && obj[key] !== null) {
  168. retObj[key] = obj[key];
  169. }
  170. }
  171. return retObj;
  172. };
  173. var readAsBinaryString = function (blob, callback) {
  174. var readFun;
  175. var fr = new FileReader();
  176. if (FileReader.prototype.readAsBinaryString) {
  177. readFun = FileReader.prototype.readAsBinaryString;
  178. fr.onload = function () {
  179. callback(this.result);
  180. };
  181. } else if (FileReader.prototype.readAsArrayBuffer) {
  182. // 在 ie11 添加 readAsBinaryString 兼容
  183. readFun = function (fileData) {
  184. var binary = "";
  185. var pt = this;
  186. var reader = new FileReader();
  187. reader.onload = function (e) {
  188. var bytes = new Uint8Array(reader.result);
  189. var length = bytes.byteLength;
  190. for (var i = 0; i < length; i++) {
  191. binary += String.fromCharCode(bytes[i]);
  192. }
  193. callback(binary);
  194. };
  195. reader.readAsArrayBuffer(fileData);
  196. };
  197. } else {
  198. console.error('FileReader not support readAsBinaryString');
  199. }
  200. readFun.call(fr, blob);
  201. };
  202. var fileSliceNeedCopy = function () {
  203. var compareVersion = function (a, b) {
  204. a = a.split('.');
  205. b = b.split('.');
  206. for (var i = 0; i < b.length; i++) {
  207. if (a[i] !== b[i]) {
  208. return parseInt(a[i]) > parseInt(b[i]) ? 1 : -1;
  209. }
  210. }
  211. return 0;
  212. };
  213. var check = function (ua) {
  214. var ChromeVersion = (ua.match(/Chrome\/([.\d]+)/) || [])[1];
  215. var QBCoreVersion = (ua.match(/QBCore\/([.\d]+)/) || [])[1];
  216. var QQBrowserVersion = (ua.match(/QQBrowser\/([.\d]+)/) || [])[1];
  217. var need = ChromeVersion && compareVersion(ChromeVersion, '53.0.2785.116') < 0 && QBCoreVersion && compareVersion(QBCoreVersion, '3.53.991.400') < 0 && QQBrowserVersion && compareVersion(QQBrowserVersion, '9.0.2524.400') <= 0 || false;
  218. return need;
  219. };
  220. return check(navigator && navigator.userAgent);
  221. }();
  222. // 获取文件分片
  223. var fileSlice = function (file, start, end, isUseToUpload, callback) {
  224. var blob;
  225. if (file.slice) {
  226. blob = file.slice(start, end);
  227. } else if (file.mozSlice) {
  228. blob = file.mozSlice(start, end);
  229. } else if (file.webkitSlice) {
  230. blob = file.webkitSlice(start, end);
  231. }
  232. if (isUseToUpload && fileSliceNeedCopy) {
  233. var reader = new FileReader();
  234. reader.onload = function (e) {
  235. blob = null;
  236. callback(new Blob([reader.result]));
  237. };
  238. reader.readAsArrayBuffer(blob);
  239. } else {
  240. callback(blob);
  241. }
  242. };
  243. // 获取文件内容的 MD5
  244. var getBodyMd5 = function (UploadCheckContentMd5, Body, callback, onProgress) {
  245. callback = callback || noop;
  246. if (UploadCheckContentMd5) {
  247. if (typeof Body === 'string') {
  248. callback(util.md5(Body, true));
  249. } else if (Blob && Body instanceof Blob) {
  250. util.getFileMd5(Body, function (err, md5) {
  251. callback(md5);
  252. }, onProgress);
  253. } else {
  254. callback();
  255. }
  256. } else {
  257. callback();
  258. }
  259. };
  260. // 获取文件 md5 值
  261. var md5ChunkSize = 1024 * 1024;
  262. var getFileMd5 = function (blob, callback, onProgress) {
  263. var size = blob.size;
  264. var loaded = 0;
  265. var md5ctx = md5.getCtx();
  266. var next = function (start) {
  267. if (start >= size) {
  268. var hash = md5ctx.digest('hex');
  269. callback(null, hash);
  270. return;
  271. }
  272. var end = Math.min(size, start + md5ChunkSize);
  273. util.fileSlice(blob, start, end, false, function (chunk) {
  274. readAsBinaryString(chunk, function (content) {
  275. chunk = null;
  276. md5ctx = md5ctx.update(content, true);
  277. loaded += content.length;
  278. content = null;
  279. if (onProgress) onProgress({ loaded: loaded, total: size, percent: Math.round(loaded / size * 10000) / 10000 });
  280. next(start + md5ChunkSize);
  281. });
  282. });
  283. };
  284. next(0);
  285. };
  286. function clone(obj) {
  287. return map(obj, function (v) {
  288. return typeof v === 'object' ? clone(v) : v;
  289. });
  290. }
  291. function extend(target, source) {
  292. each(source, function (val, key) {
  293. target[key] = source[key];
  294. });
  295. return target;
  296. }
  297. function isArray(arr) {
  298. return arr instanceof Array;
  299. }
  300. function isInArray(arr, item) {
  301. var flag = false;
  302. for (var i = 0; i < arr.length; i++) {
  303. if (item === arr[i]) {
  304. flag = true;
  305. break;
  306. }
  307. }
  308. return flag;
  309. }
  310. function makeArray(arr) {
  311. return isArray(arr) ? arr : [arr];
  312. }
  313. function each(obj, fn) {
  314. for (var i in obj) {
  315. if (obj.hasOwnProperty(i)) {
  316. fn(obj[i], i);
  317. }
  318. }
  319. }
  320. function map(obj, fn) {
  321. var o = isArray(obj) ? [] : {};
  322. for (var i in obj) {
  323. if (obj.hasOwnProperty(i)) {
  324. o[i] = fn(obj[i], i);
  325. }
  326. }
  327. return o;
  328. }
  329. function filter(obj, fn) {
  330. var iaArr = isArray(obj);
  331. var o = iaArr ? [] : {};
  332. for (var i in obj) {
  333. if (obj.hasOwnProperty(i)) {
  334. if (fn(obj[i], i)) {
  335. if (iaArr) {
  336. o.push(obj[i]);
  337. } else {
  338. o[i] = obj[i];
  339. }
  340. }
  341. }
  342. }
  343. return o;
  344. }
  345. var binaryBase64 = function (str) {
  346. var i,
  347. len,
  348. char,
  349. res = '';
  350. for (i = 0, len = str.length / 2; i < len; i++) {
  351. char = parseInt(str[i * 2] + str[i * 2 + 1], 16);
  352. res += String.fromCharCode(char);
  353. }
  354. return btoa(res);
  355. };
  356. var uuid = function () {
  357. var S4 = function () {
  358. return ((1 + Math.random()) * 0x10000 | 0).toString(16).substring(1);
  359. };
  360. return S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4();
  361. };
  362. var hasMissingParams = function (apiName, params) {
  363. var Bucket = params.Bucket;
  364. var Region = params.Region;
  365. var Key = params.Key;
  366. if (apiName.indexOf('Bucket') > -1 || apiName === 'deleteMultipleObject' || apiName === 'multipartList' || apiName === 'listObjectVersions') {
  367. if (!Bucket) return 'Bucket';
  368. if (!Region) return 'Region';
  369. } else if (apiName.indexOf('Object') > -1 || apiName.indexOf('multipart') > -1 || apiName === 'sliceUploadFile' || apiName === 'abortUploadTask') {
  370. if (!Bucket) return 'Bucket';
  371. if (!Region) return 'Region';
  372. if (!Key) return 'Key';
  373. }
  374. return false;
  375. };
  376. var formatParams = function (apiName, params) {
  377. // 复制参数对象
  378. params = extend({}, params);
  379. // 统一处理 Headers
  380. if (apiName !== 'getAuth' && apiName !== 'getV4Auth' && apiName !== 'getObjectUrl') {
  381. var Headers = params.Headers || {};
  382. if (params && typeof params === 'object') {
  383. (function () {
  384. for (var key in params) {
  385. if (params.hasOwnProperty(key) && key.indexOf('x-cos-') > -1) {
  386. Headers[key] = params[key];
  387. }
  388. }
  389. })();
  390. var headerMap = {
  391. // params headers
  392. 'x-cos-mfa': 'MFA',
  393. 'Content-MD5': 'ContentMD5',
  394. 'Content-Length': 'ContentLength',
  395. 'Content-Type': 'ContentType',
  396. 'Expect': 'Expect',
  397. 'Expires': 'Expires',
  398. 'Cache-Control': 'CacheControl',
  399. 'Content-Disposition': 'ContentDisposition',
  400. 'Content-Encoding': 'ContentEncoding',
  401. 'Range': 'Range',
  402. 'If-Modified-Since': 'IfModifiedSince',
  403. 'If-Unmodified-Since': 'IfUnmodifiedSince',
  404. 'If-Match': 'IfMatch',
  405. 'If-None-Match': 'IfNoneMatch',
  406. 'x-cos-copy-source': 'CopySource',
  407. 'x-cos-copy-source-Range': 'CopySourceRange',
  408. 'x-cos-metadata-directive': 'MetadataDirective',
  409. 'x-cos-copy-source-If-Modified-Since': 'CopySourceIfModifiedSince',
  410. 'x-cos-copy-source-If-Unmodified-Since': 'CopySourceIfUnmodifiedSince',
  411. 'x-cos-copy-source-If-Match': 'CopySourceIfMatch',
  412. 'x-cos-copy-source-If-None-Match': 'CopySourceIfNoneMatch',
  413. 'x-cos-acl': 'ACL',
  414. 'x-cos-grant-read': 'GrantRead',
  415. 'x-cos-grant-write': 'GrantWrite',
  416. 'x-cos-grant-full-control': 'GrantFullControl',
  417. 'x-cos-grant-read-acp': 'GrantReadAcp',
  418. 'x-cos-grant-write-acp': 'GrantWriteAcp',
  419. 'x-cos-storage-class': 'StorageClass',
  420. // SSE-C
  421. 'x-cos-server-side-encryption-customer-algorithm': 'SSECustomerAlgorithm',
  422. 'x-cos-server-side-encryption-customer-key': 'SSECustomerKey',
  423. 'x-cos-server-side-encryption-customer-key-MD5': 'SSECustomerKeyMD5',
  424. // SSE-COS、SSE-KMS
  425. 'x-cos-server-side-encryption': 'ServerSideEncryption',
  426. 'x-cos-server-side-encryption-cos-kms-key-id': 'SSEKMSKeyId',
  427. 'x-cos-server-side-encryption-context': 'SSEContext'
  428. };
  429. util.each(headerMap, function (paramKey, headerKey) {
  430. if (params[paramKey] !== undefined) {
  431. Headers[headerKey] = params[paramKey];
  432. }
  433. });
  434. params.Headers = clearKey(Headers);
  435. }
  436. }
  437. return params;
  438. };
  439. var apiWrapper = function (apiName, apiFn) {
  440. return function (params, callback) {
  441. // 处理参数
  442. if (typeof params === 'function') {
  443. callback = params;
  444. params = {};
  445. }
  446. // 整理参数格式
  447. params = formatParams(apiName, params);
  448. // 代理回调函数
  449. var formatResult = function (result) {
  450. if (result && result.headers) {
  451. result.headers['x-cos-version-id'] && (result.VersionId = result.headers['x-cos-version-id']);
  452. result.headers['x-cos-delete-marker'] && (result.DeleteMarker = result.headers['x-cos-delete-marker']);
  453. }
  454. return result;
  455. };
  456. var _callback = function (err, data) {
  457. callback && callback(formatResult(err), formatResult(data));
  458. };
  459. if (apiName !== 'getService' && apiName !== 'abortUploadTask') {
  460. // 判断参数是否完整
  461. var missingResult;
  462. if (missingResult = hasMissingParams(apiName, params)) {
  463. _callback({ error: 'missing param ' + missingResult });
  464. return;
  465. }
  466. // 判断 region 格式
  467. if (params.Region) {
  468. if (params.Region.indexOf('cos.') > -1) {
  469. _callback({ error: 'param Region should not be start with "cos."' });
  470. return;
  471. } else if (!/^([a-z\d-]+)$/.test(params.Region)) {
  472. _callback({ error: 'Region format error.' });
  473. return;
  474. }
  475. // 判断 region 格式
  476. if (!this.options.CompatibilityMode && params.Region.indexOf('-') === -1 && params.Region !== 'yfb' && params.Region !== 'default') {
  477. console.warn('warning: param Region format error, find help here: https://cloud.tencent.com/document/product/436/6224');
  478. }
  479. }
  480. // 兼容不带 AppId 的 Bucket
  481. if (params.Bucket) {
  482. if (!/^([a-z\d-]+)-(\d+)$/.test(params.Bucket)) {
  483. if (params.AppId) {
  484. params.Bucket = params.Bucket + '-' + params.AppId;
  485. } else if (this.options.AppId) {
  486. params.Bucket = params.Bucket + '-' + this.options.AppId;
  487. } else {
  488. _callback({ error: 'Bucket should format as "test-1250000000".' });
  489. return;
  490. }
  491. }
  492. if (params.AppId) {
  493. console.warn('warning: AppId has been deprecated, Please put it at the end of parameter Bucket(E.g Bucket:"test-1250000000" ).');
  494. delete params.AppId;
  495. }
  496. }
  497. // 如果 Key 是 / 开头,强制去掉第一个 /
  498. if (!this.options.UseRawKey && params.Key && params.Key.substr(0, 1) === '/') {
  499. params.Key = params.Key.substr(1);
  500. }
  501. }
  502. var res = apiFn.call(this, params, _callback);
  503. if (apiName === 'getAuth' || apiName === 'getObjectUrl') {
  504. return res;
  505. }
  506. };
  507. };
  508. var throttleOnProgress = function (total, onProgress) {
  509. var self = this;
  510. var size0 = 0;
  511. var size1 = 0;
  512. var time0 = Date.now();
  513. var time1;
  514. var timer;
  515. function update() {
  516. timer = 0;
  517. if (onProgress && typeof onProgress === 'function') {
  518. time1 = Date.now();
  519. var speed = Math.max(0, Math.round((size1 - size0) / ((time1 - time0) / 1000) * 100) / 100);
  520. var percent;
  521. if (size1 === 0 && total === 0) {
  522. percent = 1;
  523. } else {
  524. percent = Math.round(size1 / total * 100) / 100 || 0;
  525. }
  526. time0 = time1;
  527. size0 = size1;
  528. try {
  529. onProgress({ loaded: size1, total: total, speed: speed, percent: percent });
  530. } catch (e) {}
  531. }
  532. }
  533. return function (info, immediately) {
  534. if (info) {
  535. size1 = info.loaded;
  536. total = info.total;
  537. }
  538. if (immediately) {
  539. clearTimeout(timer);
  540. update();
  541. } else {
  542. if (timer) return;
  543. timer = setTimeout(update, self.options.ProgressInterval);
  544. }
  545. };
  546. };
  547. var getFileSize = function (api, params, callback) {
  548. var size;
  549. if (typeof params.Body === 'string') {
  550. params.Body = new Blob([params.Body], { type: 'text/plain' });
  551. }
  552. if (params.Body && (params.Body instanceof Blob || params.Body.toString() === '[object File]' || params.Body.toString() === '[object Blob]')) {
  553. size = params.Body.size;
  554. } else {
  555. callback({ error: 'params body format error, Only allow File|Blob|String.' });
  556. return;
  557. }
  558. params.ContentLength = size;
  559. callback(null, size);
  560. };
  561. // 获取调正的时间戳
  562. var getSkewTime = function (offset) {
  563. return Date.now() + (offset || 0);
  564. };
  565. var util = {
  566. noop: noop,
  567. formatParams: formatParams,
  568. apiWrapper: apiWrapper,
  569. xml2json: xml2json,
  570. json2xml: json2xml,
  571. md5: md5,
  572. clearKey: clearKey,
  573. fileSlice: fileSlice,
  574. getBodyMd5: getBodyMd5,
  575. getFileMd5: getFileMd5,
  576. binaryBase64: binaryBase64,
  577. extend: extend,
  578. isArray: isArray,
  579. isInArray: isInArray,
  580. makeArray: makeArray,
  581. each: each,
  582. map: map,
  583. filter: filter,
  584. clone: clone,
  585. uuid: uuid,
  586. camSafeUrlEncode: camSafeUrlEncode,
  587. throttleOnProgress: throttleOnProgress,
  588. getFileSize: getFileSize,
  589. getSkewTime: getSkewTime,
  590. getAuth: getAuth,
  591. isBrowser: true
  592. };
  593. module.exports = util;
  594. /***/ }),
  595. /* 1 */
  596. /***/ (function(module, exports) {
  597. /*
  598. * DOM Level 2
  599. * Object DOMException
  600. * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
  601. * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
  602. */
  603. function copy(src,dest){
  604. for(var p in src){
  605. dest[p] = src[p];
  606. }
  607. }
  608. /**
  609. ^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));?
  610. ^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));?
  611. */
  612. function _extends(Class,Super){
  613. var pt = Class.prototype;
  614. if(Object.create){
  615. var ppt = Object.create(Super.prototype)
  616. pt.__proto__ = ppt;
  617. }
  618. if(!(pt instanceof Super)){
  619. function t(){};
  620. t.prototype = Super.prototype;
  621. t = new t();
  622. copy(pt,t);
  623. Class.prototype = pt = t;
  624. }
  625. if(pt.constructor != Class){
  626. if(typeof Class != 'function'){
  627. console.error("unknow Class:"+Class)
  628. }
  629. pt.constructor = Class
  630. }
  631. }
  632. var htmlns = 'http://www.w3.org/1999/xhtml' ;
  633. // Node Types
  634. var NodeType = {}
  635. var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1;
  636. var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2;
  637. var TEXT_NODE = NodeType.TEXT_NODE = 3;
  638. var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4;
  639. var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5;
  640. var ENTITY_NODE = NodeType.ENTITY_NODE = 6;
  641. var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
  642. var COMMENT_NODE = NodeType.COMMENT_NODE = 8;
  643. var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9;
  644. var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10;
  645. var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11;
  646. var NOTATION_NODE = NodeType.NOTATION_NODE = 12;
  647. // ExceptionCode
  648. var ExceptionCode = {}
  649. var ExceptionMessage = {};
  650. var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1]="Index size error"),1);
  651. var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2]="DOMString size error"),2);
  652. var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3]="Hierarchy request error"),3);
  653. var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4]="Wrong document"),4);
  654. var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5]="Invalid character"),5);
  655. var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6]="No data allowed"),6);
  656. var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7]="No modification allowed"),7);
  657. var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8]="Not found"),8);
  658. var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9]="Not supported"),9);
  659. var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10]="Attribute in use"),10);
  660. //level2
  661. var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11]="Invalid state"),11);
  662. var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12]="Syntax error"),12);
  663. var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13]="Invalid modification"),13);
  664. var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14]="Invalid namespace"),14);
  665. var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15]="Invalid access"),15);
  666. function DOMException(code, message) {
  667. if(message instanceof Error){
  668. var error = message;
  669. }else{
  670. error = this;
  671. Error.call(this, ExceptionMessage[code]);
  672. this.message = ExceptionMessage[code];
  673. if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
  674. }
  675. error.code = code;
  676. if(message) this.message = this.message + ": " + message;
  677. return error;
  678. };
  679. DOMException.prototype = Error.prototype;
  680. copy(ExceptionCode,DOMException)
  681. /**
  682. * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
  683. * The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live.
  684. * The items in the NodeList are accessible via an integral index, starting from 0.
  685. */
  686. function NodeList() {
  687. };
  688. NodeList.prototype = {
  689. /**
  690. * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
  691. * @standard level1
  692. */
  693. length:0,
  694. /**
  695. * Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null.
  696. * @standard level1
  697. * @param index unsigned long
  698. * Index into the collection.
  699. * @return Node
  700. * The node at the indexth position in the NodeList, or null if that is not a valid index.
  701. */
  702. item: function(index) {
  703. return this[index] || null;
  704. },
  705. toString:function(isHTML,nodeFilter){
  706. for(var buf = [], i = 0;i<this.length;i++){
  707. serializeToString(this[i],buf,isHTML,nodeFilter);
  708. }
  709. return buf.join('');
  710. }
  711. };
  712. function LiveNodeList(node,refresh){
  713. this._node = node;
  714. this._refresh = refresh
  715. _updateLiveList(this);
  716. }
  717. function _updateLiveList(list){
  718. var inc = list._node._inc || list._node.ownerDocument._inc;
  719. if(list._inc != inc){
  720. var ls = list._refresh(list._node);
  721. //console.log(ls.length)
  722. __set__(list,'length',ls.length);
  723. copy(ls,list);
  724. list._inc = inc;
  725. }
  726. }
  727. LiveNodeList.prototype.item = function(i){
  728. _updateLiveList(this);
  729. return this[i];
  730. }
  731. _extends(LiveNodeList,NodeList);
  732. /**
  733. *
  734. * Objects implementing the NamedNodeMap interface are used to represent collections of nodes that can be accessed by name. Note that NamedNodeMap does not inherit from NodeList; NamedNodeMaps are not maintained in any particular order. Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index, but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, and does not imply that the DOM specifies an order to these Nodes.
  735. * NamedNodeMap objects in the DOM are live.
  736. * used for attributes or DocumentType entities
  737. */
  738. function NamedNodeMap() {
  739. };
  740. function _findNodeIndex(list,node){
  741. var i = list.length;
  742. while(i--){
  743. if(list[i] === node){return i}
  744. }
  745. }
  746. function _addNamedNode(el,list,newAttr,oldAttr){
  747. if(oldAttr){
  748. list[_findNodeIndex(list,oldAttr)] = newAttr;
  749. }else{
  750. list[list.length++] = newAttr;
  751. }
  752. if(el){
  753. newAttr.ownerElement = el;
  754. var doc = el.ownerDocument;
  755. if(doc){
  756. oldAttr && _onRemoveAttribute(doc,el,oldAttr);
  757. _onAddAttribute(doc,el,newAttr);
  758. }
  759. }
  760. }
  761. function _removeNamedNode(el,list,attr){
  762. //console.log('remove attr:'+attr)
  763. var i = _findNodeIndex(list,attr);
  764. if(i>=0){
  765. var lastIndex = list.length-1
  766. while(i<lastIndex){
  767. list[i] = list[++i]
  768. }
  769. list.length = lastIndex;
  770. if(el){
  771. var doc = el.ownerDocument;
  772. if(doc){
  773. _onRemoveAttribute(doc,el,attr);
  774. attr.ownerElement = null;
  775. }
  776. }
  777. }else{
  778. throw DOMException(NOT_FOUND_ERR,new Error(el.tagName+'@'+attr))
  779. }
  780. }
  781. NamedNodeMap.prototype = {
  782. length:0,
  783. item:NodeList.prototype.item,
  784. getNamedItem: function(key) {
  785. // if(key.indexOf(':')>0 || key == 'xmlns'){
  786. // return null;
  787. // }
  788. //console.log()
  789. var i = this.length;
  790. while(i--){
  791. var attr = this[i];
  792. //console.log(attr.nodeName,key)
  793. if(attr.nodeName == key){
  794. return attr;
  795. }
  796. }
  797. },
  798. setNamedItem: function(attr) {
  799. var el = attr.ownerElement;
  800. if(el && el!=this._ownerElement){
  801. throw new DOMException(INUSE_ATTRIBUTE_ERR);
  802. }
  803. var oldAttr = this.getNamedItem(attr.nodeName);
  804. _addNamedNode(this._ownerElement,this,attr,oldAttr);
  805. return oldAttr;
  806. },
  807. /* returns Node */
  808. setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR
  809. var el = attr.ownerElement, oldAttr;
  810. if(el && el!=this._ownerElement){
  811. throw new DOMException(INUSE_ATTRIBUTE_ERR);
  812. }
  813. oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName);
  814. _addNamedNode(this._ownerElement,this,attr,oldAttr);
  815. return oldAttr;
  816. },
  817. /* returns Node */
  818. removeNamedItem: function(key) {
  819. var attr = this.getNamedItem(key);
  820. _removeNamedNode(this._ownerElement,this,attr);
  821. return attr;
  822. },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
  823. //for level2
  824. removeNamedItemNS:function(namespaceURI,localName){
  825. var attr = this.getNamedItemNS(namespaceURI,localName);
  826. _removeNamedNode(this._ownerElement,this,attr);
  827. return attr;
  828. },
  829. getNamedItemNS: function(namespaceURI, localName) {
  830. var i = this.length;
  831. while(i--){
  832. var node = this[i];
  833. if(node.localName == localName && node.namespaceURI == namespaceURI){
  834. return node;
  835. }
  836. }
  837. return null;
  838. }
  839. };
  840. /**
  841. * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490
  842. */
  843. function DOMImplementation(/* Object */ features) {
  844. this._features = {};
  845. if (features) {
  846. for (var feature in features) {
  847. this._features = features[feature];
  848. }
  849. }
  850. };
  851. DOMImplementation.prototype = {
  852. hasFeature: function(/* string */ feature, /* string */ version) {
  853. var versions = this._features[feature.toLowerCase()];
  854. if (versions && (!version || version in versions)) {
  855. return true;
  856. } else {
  857. return false;
  858. }
  859. },
  860. // Introduced in DOM Level 2:
  861. createDocument:function(namespaceURI, qualifiedName, doctype){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR
  862. var doc = new Document();
  863. doc.implementation = this;
  864. doc.childNodes = new NodeList();
  865. doc.doctype = doctype;
  866. if(doctype){
  867. doc.appendChild(doctype);
  868. }
  869. if(qualifiedName){
  870. var root = doc.createElementNS(namespaceURI,qualifiedName);
  871. doc.appendChild(root);
  872. }
  873. return doc;
  874. },
  875. // Introduced in DOM Level 2:
  876. createDocumentType:function(qualifiedName, publicId, systemId){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR
  877. var node = new DocumentType();
  878. node.name = qualifiedName;
  879. node.nodeName = qualifiedName;
  880. node.publicId = publicId;
  881. node.systemId = systemId;
  882. // Introduced in DOM Level 2:
  883. //readonly attribute DOMString internalSubset;
  884. //TODO:..
  885. // readonly attribute NamedNodeMap entities;
  886. // readonly attribute NamedNodeMap notations;
  887. return node;
  888. }
  889. };
  890. /**
  891. * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
  892. */
  893. function Node() {
  894. };
  895. Node.prototype = {
  896. firstChild : null,
  897. lastChild : null,
  898. previousSibling : null,
  899. nextSibling : null,
  900. attributes : null,
  901. parentNode : null,
  902. childNodes : null,
  903. ownerDocument : null,
  904. nodeValue : null,
  905. namespaceURI : null,
  906. prefix : null,
  907. localName : null,
  908. // Modified in DOM Level 2:
  909. insertBefore:function(newChild, refChild){//raises
  910. return _insertBefore(this,newChild,refChild);
  911. },
  912. replaceChild:function(newChild, oldChild){//raises
  913. this.insertBefore(newChild,oldChild);
  914. if(oldChild){
  915. this.removeChild(oldChild);
  916. }
  917. },
  918. removeChild:function(oldChild){
  919. return _removeChild(this,oldChild);
  920. },
  921. appendChild:function(newChild){
  922. return this.insertBefore(newChild,null);
  923. },
  924. hasChildNodes:function(){
  925. return this.firstChild != null;
  926. },
  927. cloneNode:function(deep){
  928. return cloneNode(this.ownerDocument||this,this,deep);
  929. },
  930. // Modified in DOM Level 2:
  931. normalize:function(){
  932. var child = this.firstChild;
  933. while(child){
  934. var next = child.nextSibling;
  935. if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){
  936. this.removeChild(next);
  937. child.appendData(next.data);
  938. }else{
  939. child.normalize();
  940. child = next;
  941. }
  942. }
  943. },
  944. // Introduced in DOM Level 2:
  945. isSupported:function(feature, version){
  946. return this.ownerDocument.implementation.hasFeature(feature,version);
  947. },
  948. // Introduced in DOM Level 2:
  949. hasAttributes:function(){
  950. return this.attributes.length>0;
  951. },
  952. lookupPrefix:function(namespaceURI){
  953. var el = this;
  954. while(el){
  955. var map = el._nsMap;
  956. //console.dir(map)
  957. if(map){
  958. for(var n in map){
  959. if(map[n] == namespaceURI){
  960. return n;
  961. }
  962. }
  963. }
  964. el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
  965. }
  966. return null;
  967. },
  968. // Introduced in DOM Level 3:
  969. lookupNamespaceURI:function(prefix){
  970. var el = this;
  971. while(el){
  972. var map = el._nsMap;
  973. //console.dir(map)
  974. if(map){
  975. if(prefix in map){
  976. return map[prefix] ;
  977. }
  978. }
  979. el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
  980. }
  981. return null;
  982. },
  983. // Introduced in DOM Level 3:
  984. isDefaultNamespace:function(namespaceURI){
  985. var prefix = this.lookupPrefix(namespaceURI);
  986. return prefix == null;
  987. }
  988. };
  989. function _xmlEncoder(c){
  990. return c == '<' && '&lt;' ||
  991. c == '>' && '&gt;' ||
  992. c == '&' && '&amp;' ||
  993. c == '"' && '&quot;' ||
  994. '&#'+c.charCodeAt()+';'
  995. }
  996. copy(NodeType,Node);
  997. copy(NodeType,Node.prototype);
  998. /**
  999. * @param callback return true for continue,false for break
  1000. * @return boolean true: break visit;
  1001. */
  1002. function _visitNode(node,callback){
  1003. if(callback(node)){
  1004. return true;
  1005. }
  1006. if(node = node.firstChild){
  1007. do{
  1008. if(_visitNode(node,callback)){return true}
  1009. }while(node=node.nextSibling)
  1010. }
  1011. }
  1012. function Document(){
  1013. }
  1014. function _onAddAttribute(doc,el,newAttr){
  1015. doc && doc._inc++;
  1016. var ns = newAttr.namespaceURI ;
  1017. if(ns == 'http://www.w3.org/2000/xmlns/'){
  1018. //update namespace
  1019. el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value
  1020. }
  1021. }
  1022. function _onRemoveAttribute(doc,el,newAttr,remove){
  1023. doc && doc._inc++;
  1024. var ns = newAttr.namespaceURI ;
  1025. if(ns == 'http://www.w3.org/2000/xmlns/'){
  1026. //update namespace
  1027. delete el._nsMap[newAttr.prefix?newAttr.localName:'']
  1028. }
  1029. }
  1030. function _onUpdateChild(doc,el,newChild){
  1031. if(doc && doc._inc){
  1032. doc._inc++;
  1033. //update childNodes
  1034. var cs = el.childNodes;
  1035. if(newChild){
  1036. cs[cs.length++] = newChild;
  1037. }else{
  1038. //console.log(1)
  1039. var child = el.firstChild;
  1040. var i = 0;
  1041. while(child){
  1042. cs[i++] = child;
  1043. child =child.nextSibling;
  1044. }
  1045. cs.length = i;
  1046. }
  1047. }
  1048. }
  1049. /**
  1050. * attributes;
  1051. * children;
  1052. *
  1053. * writeable properties:
  1054. * nodeValue,Attr:value,CharacterData:data
  1055. * prefix
  1056. */
  1057. function _removeChild(parentNode,child){
  1058. var previous = child.previousSibling;
  1059. var next = child.nextSibling;
  1060. if(previous){
  1061. previous.nextSibling = next;
  1062. }else{
  1063. parentNode.firstChild = next
  1064. }
  1065. if(next){
  1066. next.previousSibling = previous;
  1067. }else{
  1068. parentNode.lastChild = previous;
  1069. }
  1070. _onUpdateChild(parentNode.ownerDocument,parentNode);
  1071. return child;
  1072. }
  1073. /**
  1074. * preformance key(refChild == null)
  1075. */
  1076. function _insertBefore(parentNode,newChild,nextChild){
  1077. var cp = newChild.parentNode;
  1078. if(cp){
  1079. cp.removeChild(newChild);//remove and update
  1080. }
  1081. if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
  1082. var newFirst = newChild.firstChild;
  1083. if (newFirst == null) {
  1084. return newChild;
  1085. }
  1086. var newLast = newChild.lastChild;
  1087. }else{
  1088. newFirst = newLast = newChild;
  1089. }
  1090. var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild;
  1091. newFirst.previousSibling = pre;
  1092. newLast.nextSibling = nextChild;
  1093. if(pre){
  1094. pre.nextSibling = newFirst;
  1095. }else{
  1096. parentNode.firstChild = newFirst;
  1097. }
  1098. if(nextChild == null){
  1099. parentNode.lastChild = newLast;
  1100. }else{
  1101. nextChild.previousSibling = newLast;
  1102. }
  1103. do{
  1104. newFirst.parentNode = parentNode;
  1105. }while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
  1106. _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode);
  1107. //console.log(parentNode.lastChild.nextSibling == null)
  1108. if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
  1109. newChild.firstChild = newChild.lastChild = null;
  1110. }
  1111. return newChild;
  1112. }
  1113. function _appendSingleChild(parentNode,newChild){
  1114. var cp = newChild.parentNode;
  1115. if(cp){
  1116. var pre = parentNode.lastChild;
  1117. cp.removeChild(newChild);//remove and update
  1118. var pre = parentNode.lastChild;
  1119. }
  1120. var pre = parentNode.lastChild;
  1121. newChild.parentNode = parentNode;
  1122. newChild.previousSibling = pre;
  1123. newChild.nextSibling = null;
  1124. if(pre){
  1125. pre.nextSibling = newChild;
  1126. }else{
  1127. parentNode.firstChild = newChild;
  1128. }
  1129. parentNode.lastChild = newChild;
  1130. _onUpdateChild(parentNode.ownerDocument,parentNode,newChild);
  1131. return newChild;
  1132. //console.log("__aa",parentNode.lastChild.nextSibling == null)
  1133. }
  1134. Document.prototype = {
  1135. //implementation : null,
  1136. nodeName : '#document',
  1137. nodeType : DOCUMENT_NODE,
  1138. doctype : null,
  1139. documentElement : null,
  1140. _inc : 1,
  1141. insertBefore : function(newChild, refChild){//raises
  1142. if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){
  1143. var child = newChild.firstChild;
  1144. while(child){
  1145. var next = child.nextSibling;
  1146. this.insertBefore(child,refChild);
  1147. child = next;
  1148. }
  1149. return newChild;
  1150. }
  1151. if(this.documentElement == null && newChild.nodeType == ELEMENT_NODE){
  1152. this.documentElement = newChild;
  1153. }
  1154. return _insertBefore(this,newChild,refChild),(newChild.ownerDocument = this),newChild;
  1155. },
  1156. removeChild : function(oldChild){
  1157. if(this.documentElement == oldChild){
  1158. this.documentElement = null;
  1159. }
  1160. return _removeChild(this,oldChild);
  1161. },
  1162. // Introduced in DOM Level 2:
  1163. importNode : function(importedNode,deep){
  1164. return importNode(this,importedNode,deep);
  1165. },
  1166. // Introduced in DOM Level 2:
  1167. getElementById : function(id){
  1168. var rtv = null;
  1169. _visitNode(this.documentElement,function(node){
  1170. if(node.nodeType == ELEMENT_NODE){
  1171. if(node.getAttribute('id') == id){
  1172. rtv = node;
  1173. return true;
  1174. }
  1175. }
  1176. })
  1177. return rtv;
  1178. },
  1179. //document factory method:
  1180. createElement : function(tagName){
  1181. var node = new Element();
  1182. node.ownerDocument = this;
  1183. node.nodeName = tagName;
  1184. node.tagName = tagName;
  1185. node.childNodes = new NodeList();
  1186. var attrs = node.attributes = new NamedNodeMap();
  1187. attrs._ownerElement = node;
  1188. return node;
  1189. },
  1190. createDocumentFragment : function(){
  1191. var node = new DocumentFragment();
  1192. node.ownerDocument = this;
  1193. node.childNodes = new NodeList();
  1194. return node;
  1195. },
  1196. createTextNode : function(data){
  1197. var node = new Text();
  1198. node.ownerDocument = this;
  1199. node.appendData(data)
  1200. return node;
  1201. },
  1202. createComment : function(data){
  1203. var node = new Comment();
  1204. node.ownerDocument = this;
  1205. node.appendData(data)
  1206. return node;
  1207. },
  1208. createCDATASection : function(data){
  1209. var node = new CDATASection();
  1210. node.ownerDocument = this;
  1211. node.appendData(data)
  1212. return node;
  1213. },
  1214. createProcessingInstruction : function(target,data){
  1215. var node = new ProcessingInstruction();
  1216. node.ownerDocument = this;
  1217. node.tagName = node.target = target;
  1218. node.nodeValue= node.data = data;
  1219. return node;
  1220. },
  1221. createAttribute : function(name){
  1222. var node = new Attr();
  1223. node.ownerDocument = this;
  1224. node.name = name;
  1225. node.nodeName = name;
  1226. node.localName = name;
  1227. node.specified = true;
  1228. return node;
  1229. },
  1230. createEntityReference : function(name){
  1231. var node = new EntityReference();
  1232. node.ownerDocument = this;
  1233. node.nodeName = name;
  1234. return node;
  1235. },
  1236. // Introduced in DOM Level 2:
  1237. createElementNS : function(namespaceURI,qualifiedName){
  1238. var node = new Element();
  1239. var pl = qualifiedName.split(':');
  1240. var attrs = node.attributes = new NamedNodeMap();
  1241. node.childNodes = new NodeList();
  1242. node.ownerDocument = this;
  1243. node.nodeName = qualifiedName;
  1244. node.tagName = qualifiedName;
  1245. node.namespaceURI = namespaceURI;
  1246. if(pl.length == 2){
  1247. node.prefix = pl[0];
  1248. node.localName = pl[1];
  1249. }else{
  1250. //el.prefix = null;
  1251. node.localName = qualifiedName;
  1252. }
  1253. attrs._ownerElement = node;
  1254. return node;
  1255. },
  1256. // Introduced in DOM Level 2:
  1257. createAttributeNS : function(namespaceURI,qualifiedName){
  1258. var node = new Attr();
  1259. var pl = qualifiedName.split(':');
  1260. node.ownerDocument = this;
  1261. node.nodeName = qualifiedName;
  1262. node.name = qualifiedName;
  1263. node.namespaceURI = namespaceURI;
  1264. node.specified = true;
  1265. if(pl.length == 2){
  1266. node.prefix = pl[0];
  1267. node.localName = pl[1];
  1268. }else{
  1269. //el.prefix = null;
  1270. node.localName = qualifiedName;
  1271. }
  1272. return node;
  1273. }
  1274. };
  1275. _extends(Document,Node);
  1276. function Element() {
  1277. this._nsMap = {};
  1278. };
  1279. Element.prototype = {
  1280. nodeType : ELEMENT_NODE,
  1281. hasAttribute : function(name){
  1282. return this.getAttributeNode(name)!=null;
  1283. },
  1284. getAttribute : function(name){
  1285. var attr = this.getAttributeNode(name);
  1286. return attr && attr.value || '';
  1287. },
  1288. getAttributeNode : function(name){
  1289. return this.attributes.getNamedItem(name);
  1290. },
  1291. setAttribute : function(name, value){
  1292. var attr = this.ownerDocument.createAttribute(name);
  1293. attr.value = attr.nodeValue = "" + value;
  1294. this.setAttributeNode(attr)
  1295. },
  1296. removeAttribute : function(name){
  1297. var attr = this.getAttributeNode(name)
  1298. attr && this.removeAttributeNode(attr);
  1299. },
  1300. //four real opeartion method
  1301. appendChild:function(newChild){
  1302. if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
  1303. return this.insertBefore(newChild,null);
  1304. }else{
  1305. return _appendSingleChild(this,newChild);
  1306. }
  1307. },
  1308. setAttributeNode : function(newAttr){
  1309. return this.attributes.setNamedItem(newAttr);
  1310. },
  1311. setAttributeNodeNS : function(newAttr){
  1312. return this.attributes.setNamedItemNS(newAttr);
  1313. },
  1314. removeAttributeNode : function(oldAttr){
  1315. //console.log(this == oldAttr.ownerElement)
  1316. return this.attributes.removeNamedItem(oldAttr.nodeName);
  1317. },
  1318. //get real attribute name,and remove it by removeAttributeNode
  1319. removeAttributeNS : function(namespaceURI, localName){
  1320. var old = this.getAttributeNodeNS(namespaceURI, localName);
  1321. old && this.removeAttributeNode(old);
  1322. },
  1323. hasAttributeNS : function(namespaceURI, localName){
  1324. return this.getAttributeNodeNS(namespaceURI, localName)!=null;
  1325. },
  1326. getAttributeNS : function(namespaceURI, localName){
  1327. var attr = this.getAttributeNodeNS(namespaceURI, localName);
  1328. return attr && attr.value || '';
  1329. },
  1330. setAttributeNS : function(namespaceURI, qualifiedName, value){
  1331. var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
  1332. attr.value = attr.nodeValue = "" + value;
  1333. this.setAttributeNode(attr)
  1334. },
  1335. getAttributeNodeNS : function(namespaceURI, localName){
  1336. return this.attributes.getNamedItemNS(namespaceURI, localName);
  1337. },
  1338. getElementsByTagName : function(tagName){
  1339. return new LiveNodeList(this,function(base){
  1340. var ls = [];
  1341. _visitNode(base,function(node){
  1342. if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){
  1343. ls.push(node);
  1344. }
  1345. });
  1346. return ls;
  1347. });
  1348. },
  1349. getElementsByTagNameNS : function(namespaceURI, localName){
  1350. return new LiveNodeList(this,function(base){
  1351. var ls = [];
  1352. _visitNode(base,function(node){
  1353. if(node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)){
  1354. ls.push(node);
  1355. }
  1356. });
  1357. return ls;
  1358. });
  1359. }
  1360. };
  1361. Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
  1362. Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
  1363. _extends(Element,Node);
  1364. function Attr() {
  1365. };
  1366. Attr.prototype.nodeType = ATTRIBUTE_NODE;
  1367. _extends(Attr,Node);
  1368. function CharacterData() {
  1369. };
  1370. CharacterData.prototype = {
  1371. data : '',
  1372. substringData : function(offset, count) {
  1373. return this.data.substring(offset, offset+count);
  1374. },
  1375. appendData: function(text) {
  1376. text = this.data+text;
  1377. this.nodeValue = this.data = text;
  1378. this.length = text.length;
  1379. },
  1380. insertData: function(offset,text) {
  1381. this.replaceData(offset,0,text);
  1382. },
  1383. appendChild:function(newChild){
  1384. throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR])
  1385. },
  1386. deleteData: function(offset, count) {
  1387. this.replaceData(offset,count,"");
  1388. },
  1389. replaceData: function(offset, count, text) {
  1390. var start = this.data.substring(0,offset);
  1391. var end = this.data.substring(offset+count);
  1392. text = start + text + end;
  1393. this.nodeValue = this.data = text;
  1394. this.length = text.length;
  1395. }
  1396. }
  1397. _extends(CharacterData,Node);
  1398. function Text() {
  1399. };
  1400. Text.prototype = {
  1401. nodeName : "#text",
  1402. nodeType : TEXT_NODE,
  1403. splitText : function(offset) {
  1404. var text = this.data;
  1405. var newText = text.substring(offset);
  1406. text = text.substring(0, offset);
  1407. this.data = this.nodeValue = text;
  1408. this.length = text.length;
  1409. var newNode = this.ownerDocument.createTextNode(newText);
  1410. if(this.parentNode){
  1411. this.parentNode.insertBefore(newNode, this.nextSibling);
  1412. }
  1413. return newNode;
  1414. }
  1415. }
  1416. _extends(Text,CharacterData);
  1417. function Comment() {
  1418. };
  1419. Comment.prototype = {
  1420. nodeName : "#comment",
  1421. nodeType : COMMENT_NODE
  1422. }
  1423. _extends(Comment,CharacterData);
  1424. function CDATASection() {
  1425. };
  1426. CDATASection.prototype = {
  1427. nodeName : "#cdata-section",
  1428. nodeType : CDATA_SECTION_NODE
  1429. }
  1430. _extends(CDATASection,CharacterData);
  1431. function DocumentType() {
  1432. };
  1433. DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
  1434. _extends(DocumentType,Node);
  1435. function Notation() {
  1436. };
  1437. Notation.prototype.nodeType = NOTATION_NODE;
  1438. _extends(Notation,Node);
  1439. function Entity() {
  1440. };
  1441. Entity.prototype.nodeType = ENTITY_NODE;
  1442. _extends(Entity,Node);
  1443. function EntityReference() {
  1444. };
  1445. EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
  1446. _extends(EntityReference,Node);
  1447. function DocumentFragment() {
  1448. };
  1449. DocumentFragment.prototype.nodeName = "#document-fragment";
  1450. DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE;
  1451. _extends(DocumentFragment,Node);
  1452. function ProcessingInstruction() {
  1453. }
  1454. ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
  1455. _extends(ProcessingInstruction,Node);
  1456. function XMLSerializer(){}
  1457. XMLSerializer.prototype.serializeToString = function(node,isHtml,nodeFilter){
  1458. return nodeSerializeToString.call(node,isHtml,nodeFilter);
  1459. }
  1460. Node.prototype.toString = nodeSerializeToString;
  1461. function nodeSerializeToString(isHtml,nodeFilter){
  1462. var buf = [];
  1463. var refNode = this.nodeType == 9?this.documentElement:this;
  1464. var prefix = refNode.prefix;
  1465. var uri = refNode.namespaceURI;
  1466. if(uri && prefix == null){
  1467. //console.log(prefix)
  1468. var prefix = refNode.lookupPrefix(uri);
  1469. if(prefix == null){
  1470. //isHTML = true;
  1471. var visibleNamespaces=[
  1472. {namespace:uri,prefix:null}
  1473. //{namespace:uri,prefix:''}
  1474. ]
  1475. }
  1476. }
  1477. serializeToString(this,buf,isHtml,nodeFilter,visibleNamespaces);
  1478. //console.log('###',this.nodeType,uri,prefix,buf.join(''))
  1479. return buf.join('');
  1480. }
  1481. function needNamespaceDefine(node,isHTML, visibleNamespaces) {
  1482. var prefix = node.prefix||'';
  1483. var uri = node.namespaceURI;
  1484. if (!prefix && !uri){
  1485. return false;
  1486. }
  1487. if (prefix === "xml" && uri === "http://www.w3.org/XML/1998/namespace"
  1488. || uri == 'http://www.w3.org/2000/xmlns/'){
  1489. return false;
  1490. }
  1491. var i = visibleNamespaces.length
  1492. //console.log('@@@@',node.tagName,prefix,uri,visibleNamespaces)
  1493. while (i--) {
  1494. var ns = visibleNamespaces[i];
  1495. // get namespace prefix
  1496. //console.log(node.nodeType,node.tagName,ns.prefix,prefix)
  1497. if (ns.prefix == prefix){
  1498. return ns.namespace != uri;
  1499. }
  1500. }
  1501. //console.log(isHTML,uri,prefix=='')
  1502. //if(isHTML && prefix ==null && uri == 'http://www.w3.org/1999/xhtml'){
  1503. // return false;
  1504. //}
  1505. //node.flag = '11111'
  1506. //console.error(3,true,node.flag,node.prefix,node.namespaceURI)
  1507. return true;
  1508. }
  1509. function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){
  1510. if(nodeFilter){
  1511. node = nodeFilter(node);
  1512. if(node){
  1513. if(typeof node == 'string'){
  1514. buf.push(node);
  1515. return;
  1516. }
  1517. }else{
  1518. return;
  1519. }
  1520. //buf.sort.apply(attrs, attributeSorter);
  1521. }
  1522. switch(node.nodeType){
  1523. case ELEMENT_NODE:
  1524. if (!visibleNamespaces) visibleNamespaces = [];
  1525. var startVisibleNamespaces = visibleNamespaces.length;
  1526. var attrs = node.attributes;
  1527. var len = attrs.length;
  1528. var child = node.firstChild;
  1529. var nodeName = node.tagName;
  1530. isHTML = (htmlns === node.namespaceURI) ||isHTML
  1531. buf.push('<',nodeName);
  1532. for(var i=0;i<len;i++){
  1533. // add namespaces for attributes
  1534. var attr = attrs.item(i);
  1535. if (attr.prefix == 'xmlns') {
  1536. visibleNamespaces.push({ prefix: attr.localName, namespace: attr.value });
  1537. }else if(attr.nodeName == 'xmlns'){
  1538. visibleNamespaces.push({ prefix: '', namespace: attr.value });
  1539. }
  1540. }
  1541. for(var i=0;i<len;i++){
  1542. var attr = attrs.item(i);
  1543. if (needNamespaceDefine(attr,isHTML, visibleNamespaces)) {
  1544. var prefix = attr.prefix||'';
  1545. var uri = attr.namespaceURI;
  1546. var ns = prefix ? ' xmlns:' + prefix : " xmlns";
  1547. buf.push(ns, '="' , uri , '"');
  1548. visibleNamespaces.push({ prefix: prefix, namespace:uri });
  1549. }
  1550. serializeToString(attr,buf,isHTML,nodeFilter,visibleNamespaces);
  1551. }
  1552. // add namespace for current node
  1553. if (needNamespaceDefine(node,isHTML, visibleNamespaces)) {
  1554. var prefix = node.prefix||'';
  1555. var uri = node.namespaceURI;
  1556. var ns = prefix ? ' xmlns:' + prefix : " xmlns";
  1557. buf.push(ns, '="' , uri , '"');
  1558. visibleNamespaces.push({ prefix: prefix, namespace:uri });
  1559. }
  1560. if(child || isHTML && !/^(?:meta|link|img|br|hr|input)$/i.test(nodeName)){
  1561. buf.push('>');
  1562. //if is cdata child node
  1563. if(isHTML && /^script$/i.test(nodeName)){
  1564. while(child){
  1565. if(child.data){
  1566. buf.push(child.data);
  1567. }else{
  1568. serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces);
  1569. }
  1570. child = child.nextSibling;
  1571. }
  1572. }else
  1573. {
  1574. while(child){
  1575. serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces);
  1576. child = child.nextSibling;
  1577. }
  1578. }
  1579. buf.push('</',nodeName,'>');
  1580. }else{
  1581. buf.push('/>');
  1582. }
  1583. // remove added visible namespaces
  1584. //visibleNamespaces.length = startVisibleNamespaces;
  1585. return;
  1586. case DOCUMENT_NODE:
  1587. case DOCUMENT_FRAGMENT_NODE:
  1588. var child = node.firstChild;
  1589. while(child){
  1590. serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces);
  1591. child = child.nextSibling;
  1592. }
  1593. return;
  1594. case ATTRIBUTE_NODE:
  1595. return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"');
  1596. case TEXT_NODE:
  1597. return buf.push(node.data.replace(/[<&]/g,_xmlEncoder));
  1598. case CDATA_SECTION_NODE:
  1599. return buf.push( '<![CDATA[',node.data,']]>');
  1600. case COMMENT_NODE:
  1601. return buf.push( "<!--",node.data,"-->");
  1602. case DOCUMENT_TYPE_NODE:
  1603. var pubid = node.publicId;
  1604. var sysid = node.systemId;
  1605. buf.push('<!DOCTYPE ',node.name);
  1606. if(pubid){
  1607. buf.push(' PUBLIC "',pubid);
  1608. if (sysid && sysid!='.') {
  1609. buf.push( '" "',sysid);
  1610. }
  1611. buf.push('">');
  1612. }else if(sysid && sysid!='.'){
  1613. buf.push(' SYSTEM "',sysid,'">');
  1614. }else{
  1615. var sub = node.internalSubset;
  1616. if(sub){
  1617. buf.push(" [",sub,"]");
  1618. }
  1619. buf.push(">");
  1620. }
  1621. return;
  1622. case PROCESSING_INSTRUCTION_NODE:
  1623. return buf.push( "<?",node.target," ",node.data,"?>");
  1624. case ENTITY_REFERENCE_NODE:
  1625. return buf.push( '&',node.nodeName,';');
  1626. //case ENTITY_NODE:
  1627. //case NOTATION_NODE:
  1628. default:
  1629. buf.push('??',node.nodeName);
  1630. }
  1631. }
  1632. function importNode(doc,node,deep){
  1633. var node2;
  1634. switch (node.nodeType) {
  1635. case ELEMENT_NODE:
  1636. node2 = node.cloneNode(false);
  1637. node2.ownerDocument = doc;
  1638. //var attrs = node2.attributes;
  1639. //var len = attrs.length;
  1640. //for(var i=0;i<len;i++){
  1641. //node2.setAttributeNodeNS(importNode(doc,attrs.item(i),deep));
  1642. //}
  1643. case DOCUMENT_FRAGMENT_NODE:
  1644. break;
  1645. case ATTRIBUTE_NODE:
  1646. deep = true;
  1647. break;
  1648. //case ENTITY_REFERENCE_NODE:
  1649. //case PROCESSING_INSTRUCTION_NODE:
  1650. ////case TEXT_NODE:
  1651. //case CDATA_SECTION_NODE:
  1652. //case COMMENT_NODE:
  1653. // deep = false;
  1654. // break;
  1655. //case DOCUMENT_NODE:
  1656. //case DOCUMENT_TYPE_NODE:
  1657. //cannot be imported.
  1658. //case ENTITY_NODE:
  1659. //case NOTATION_NODE:
  1660. //can not hit in level3
  1661. //default:throw e;
  1662. }
  1663. if(!node2){
  1664. node2 = node.cloneNode(false);//false
  1665. }
  1666. node2.ownerDocument = doc;
  1667. node2.parentNode = null;
  1668. if(deep){
  1669. var child = node.firstChild;
  1670. while(child){
  1671. node2.appendChild(importNode(doc,child,deep));
  1672. child = child.nextSibling;
  1673. }
  1674. }
  1675. return node2;
  1676. }
  1677. //
  1678. //var _relationMap = {firstChild:1,lastChild:1,previousSibling:1,nextSibling:1,
  1679. // attributes:1,childNodes:1,parentNode:1,documentElement:1,doctype,};
  1680. function cloneNode(doc,node,deep){
  1681. var node2 = new node.constructor();
  1682. for(var n in node){
  1683. var v = node[n];
  1684. if(typeof v != 'object' ){
  1685. if(v != node2[n]){
  1686. node2[n] = v;
  1687. }
  1688. }
  1689. }
  1690. if(node.childNodes){
  1691. node2.childNodes = new NodeList();
  1692. }
  1693. node2.ownerDocument = doc;
  1694. switch (node2.nodeType) {
  1695. case ELEMENT_NODE:
  1696. var attrs = node.attributes;
  1697. var attrs2 = node2.attributes = new NamedNodeMap();
  1698. var len = attrs.length
  1699. attrs2._ownerElement = node2;
  1700. for(var i=0;i<len;i++){
  1701. node2.setAttributeNode(cloneNode(doc,attrs.item(i),true));
  1702. }
  1703. break;;
  1704. case ATTRIBUTE_NODE:
  1705. deep = true;
  1706. }
  1707. if(deep){
  1708. var child = node.firstChild;
  1709. while(child){
  1710. node2.appendChild(cloneNode(doc,child,deep));
  1711. child = child.nextSibling;
  1712. }
  1713. }
  1714. return node2;
  1715. }
  1716. function __set__(object,key,value){
  1717. object[key] = value
  1718. }
  1719. //do dynamic
  1720. try{
  1721. if(Object.defineProperty){
  1722. Object.defineProperty(LiveNodeList.prototype,'length',{
  1723. get:function(){
  1724. _updateLiveList(this);
  1725. return this.$$length;
  1726. }
  1727. });
  1728. Object.defineProperty(Node.prototype,'textContent',{
  1729. get:function(){
  1730. return getTextContent(this);
  1731. },
  1732. set:function(data){
  1733. switch(this.nodeType){
  1734. case ELEMENT_NODE:
  1735. case DOCUMENT_FRAGMENT_NODE:
  1736. while(this.firstChild){
  1737. this.removeChild(this.firstChild);
  1738. }
  1739. if(data || String(data)){
  1740. this.appendChild(this.ownerDocument.createTextNode(data));
  1741. }
  1742. break;
  1743. default:
  1744. //TODO:
  1745. this.data = data;
  1746. this.value = data;
  1747. this.nodeValue = data;
  1748. }
  1749. }
  1750. })
  1751. function getTextContent(node){
  1752. switch(node.nodeType){
  1753. case ELEMENT_NODE:
  1754. case DOCUMENT_FRAGMENT_NODE:
  1755. var buf = [];
  1756. node = node.firstChild;
  1757. while(node){
  1758. if(node.nodeType!==7 && node.nodeType !==8){
  1759. buf.push(getTextContent(node));
  1760. }
  1761. node = node.nextSibling;
  1762. }
  1763. return buf.join('');
  1764. default:
  1765. return node.nodeValue;
  1766. }
  1767. }
  1768. __set__ = function(object,key,value){
  1769. //console.log(value)
  1770. object['$$'+key] = value
  1771. }
  1772. }
  1773. }catch(e){//ie8
  1774. }
  1775. //if(typeof require == 'function'){
  1776. exports.DOMImplementation = DOMImplementation;
  1777. exports.XMLSerializer = XMLSerializer;
  1778. //}
  1779. /***/ }),
  1780. /* 2 */
  1781. /***/ (function(module, exports) {
  1782. var initEvent = function (cos) {
  1783. var listeners = {};
  1784. var getList = function (action) {
  1785. !listeners[action] && (listeners[action] = []);
  1786. return listeners[action];
  1787. };
  1788. cos.on = function (action, callback) {
  1789. if (action === 'task-list-update') {
  1790. console.warn('warning: Event "' + action + '" has been deprecated. Please use "list-update" instead.');
  1791. }
  1792. getList(action).push(callback);
  1793. };
  1794. cos.off = function (action, callback) {
  1795. var list = getList(action);
  1796. for (var i = list.length - 1; i >= 0; i--) {
  1797. callback === list[i] && list.splice(i, 1);
  1798. }
  1799. };
  1800. cos.emit = function (action, data) {
  1801. var list = getList(action).map(function (cb) {
  1802. return cb;
  1803. });
  1804. for (var i = 0; i < list.length; i++) {
  1805. list[i](data);
  1806. }
  1807. };
  1808. };
  1809. var EventProxy = function () {
  1810. initEvent(this);
  1811. };
  1812. module.exports.init = initEvent;
  1813. module.exports.EventProxy = EventProxy;
  1814. /***/ }),
  1815. /* 3 */
  1816. /***/ (function(module, exports, __webpack_require__) {
  1817. var util = __webpack_require__(0);
  1818. // 按照文件特征值,缓存 UploadId
  1819. var cacheKey = 'cos_sdk_upload_cache';
  1820. var expires = 30 * 24 * 3600;
  1821. var cache;
  1822. var timer;
  1823. var init = function () {
  1824. if (cache) return;
  1825. cache = JSON.parse(localStorage.getItem(cacheKey) || '[]') || [];
  1826. // 清理太老旧的数据
  1827. var changed = false;
  1828. var now = Math.round(Date.now() / 1000);
  1829. for (var i = cache.length - 1; i >= 0; i--) {
  1830. var mtime = cache[i][2];
  1831. if (!mtime || mtime + expires < now) {
  1832. cache.splice(i, 1);
  1833. changed = true;
  1834. }
  1835. }
  1836. changed && localStorage.setItem(cacheKey, JSON.stringify(cache));
  1837. };
  1838. // 把缓存存到本地
  1839. var save = function () {
  1840. if (timer) return;
  1841. timer = setTimeout(function () {
  1842. localStorage.setItem(cacheKey, JSON.stringify(cache));
  1843. timer = null;
  1844. }, 400);
  1845. };
  1846. var mod = {
  1847. using: {},
  1848. // 标记 UploadId 正在使用
  1849. setUsing: function (uuid) {
  1850. mod.using[uuid] = true;
  1851. },
  1852. // 标记 UploadId 已经没在使用
  1853. removeUsing: function (uuid) {
  1854. delete mod.using[uuid];
  1855. },
  1856. // 用上传参数生成哈希值
  1857. getFileId: function (file, ChunkSize, Bucket, Key) {
  1858. if (file.name && file.size && file.lastModifiedDate && ChunkSize) {
  1859. return util.md5([file.name, file.size, file.lastModifiedDate, ChunkSize, Bucket, Key].join('::'));
  1860. } else {
  1861. return null;
  1862. }
  1863. },
  1864. // 获取文件对应的 UploadId 列表
  1865. getUploadIdList: function (uuid) {
  1866. if (!uuid) return null;
  1867. init();
  1868. var list = [];
  1869. for (var i = 0; i < cache.length; i++) {
  1870. if (cache[i][0] === uuid) list.push(cache[i][1]);
  1871. }
  1872. return list.length ? list : null;
  1873. },
  1874. // 缓存 UploadId
  1875. saveUploadId: function (uuid, UploadId, limit) {
  1876. init();
  1877. if (!uuid) return;
  1878. // 清理没用的 UploadId
  1879. for (var i = cache.length - 1; i >= 0; i--) {
  1880. var item = cache[i];
  1881. if (item[0] === uuid && item[1] === UploadId) {
  1882. cache.splice(i, 1);
  1883. }
  1884. }
  1885. cache.unshift([uuid, UploadId, Math.round(Date.now() / 1000)]);
  1886. if (cache.length > limit) cache.splice(limit);
  1887. save();
  1888. },
  1889. // UploadId 已用完,移除掉
  1890. removeUploadId: function (UploadId) {
  1891. init();
  1892. delete mod.using[UploadId];
  1893. for (var i = cache.length - 1; i >= 0; i--) {
  1894. if (cache[i][1] === UploadId) cache.splice(i, 1);
  1895. }
  1896. save();
  1897. }
  1898. };
  1899. module.exports = mod;
  1900. /***/ }),
  1901. /* 4 */
  1902. /***/ (function(module, exports, __webpack_require__) {
  1903. var COS = __webpack_require__(5);
  1904. module.exports = COS;
  1905. /***/ }),
  1906. /* 5 */
  1907. /***/ (function(module, exports, __webpack_require__) {
  1908. "use strict";
  1909. var util = __webpack_require__(0);
  1910. var event = __webpack_require__(2);
  1911. var task = __webpack_require__(12);
  1912. var base = __webpack_require__(13);
  1913. var advance = __webpack_require__(15);
  1914. var defaultOptions = {
  1915. AppId: '', // AppId 已废弃,请拼接到 Bucket 后传入,例如:test-1250000000
  1916. SecretId: '',
  1917. SecretKey: '',
  1918. XCosSecurityToken: '', // 使用临时密钥需要注意自行刷新 Token
  1919. ChunkRetryTimes: 2,
  1920. FileParallelLimit: 3,
  1921. ChunkParallelLimit: 3,
  1922. ChunkSize: 1024 * 1024,
  1923. SliceSize: 1024 * 1024,
  1924. CopyChunkParallelLimit: 20,
  1925. CopyChunkSize: 1024 * 1024 * 10,
  1926. CopySliceSize: 1024 * 1024 * 10,
  1927. MaxPartNumber: 10000,
  1928. ProgressInterval: 1000,
  1929. UploadQueueSize: 10000,
  1930. Domain: '',
  1931. ServiceDomain: '',
  1932. Protocol: '',
  1933. CompatibilityMode: false,
  1934. ForcePathStyle: false,
  1935. UseRawKey: false,
  1936. Timeout: 0, // 单位毫秒,0 代表不设置超时时间
  1937. CorrectClockSkew: true,
  1938. SystemClockOffset: 0, // 单位毫秒,ms
  1939. UploadCheckContentMd5: false,
  1940. UploadAddMetaMd5: false,
  1941. UploadIdCacheLimit: 50
  1942. };
  1943. // 对外暴露的类
  1944. var COS = function (options) {
  1945. this.options = util.extend(util.clone(defaultOptions), options || {});
  1946. this.options.FileParallelLimit = Math.max(1, this.options.FileParallelLimit);
  1947. this.options.ChunkParallelLimit = Math.max(1, this.options.ChunkParallelLimit);
  1948. this.options.ChunkRetryTimes = Math.max(0, this.options.ChunkRetryTimes);
  1949. this.options.ChunkSize = Math.max(1024 * 1024, this.options.ChunkSize);
  1950. this.options.CopyChunkParallelLimit = Math.max(1, this.options.CopyChunkParallelLimit);
  1951. this.options.CopyChunkSize = Math.max(1024 * 1024, this.options.CopyChunkSize);
  1952. this.options.CopySliceSize = Math.max(0, this.options.CopySliceSize);
  1953. this.options.MaxPartNumber = Math.max(1024, Math.min(10000, this.options.MaxPartNumber));
  1954. this.options.Timeout = Math.max(0, this.options.Timeout);
  1955. if (this.options.AppId) {
  1956. console.warn('warning: AppId has been deprecated, Please put it at the end of parameter Bucket(E.g: "test-1250000000").');
  1957. }
  1958. event.init(this);
  1959. task.init(this);
  1960. };
  1961. base.init(COS, task);
  1962. advance.init(COS, task);
  1963. COS.getAuthorization = util.getAuth;
  1964. COS.version = '0.5.27';
  1965. module.exports = COS;
  1966. /***/ }),
  1967. /* 6 */
  1968. /***/ (function(module, exports) {
  1969. /**
  1970. * http://www.myersdaily.org/joseph/javascript/md5-text.html
  1971. * http://pajhome.org.uk/crypt/md5
  1972. * https://github.com/wbond/md5-js
  1973. */
  1974. function md5cycle(x, k) {
  1975. var a = x[0],
  1976. b = x[1],
  1977. c = x[2],
  1978. d = x[3];
  1979. a = ff(a, b, c, d, k[0], 7, -680876936);
  1980. d = ff(d, a, b, c, k[1], 12, -389564586);
  1981. c = ff(c, d, a, b, k[2], 17, 606105819);
  1982. b = ff(b, c, d, a, k[3], 22, -1044525330);
  1983. a = ff(a, b, c, d, k[4], 7, -176418897);
  1984. d = ff(d, a, b, c, k[5], 12, 1200080426);
  1985. c = ff(c, d, a, b, k[6], 17, -1473231341);
  1986. b = ff(b, c, d, a, k[7], 22, -45705983);
  1987. a = ff(a, b, c, d, k[8], 7, 1770035416);
  1988. d = ff(d, a, b, c, k[9], 12, -1958414417);
  1989. c = ff(c, d, a, b, k[10], 17, -42063);
  1990. b = ff(b, c, d, a, k[11], 22, -1990404162);
  1991. a = ff(a, b, c, d, k[12], 7, 1804603682);
  1992. d = ff(d, a, b, c, k[13], 12, -40341101);
  1993. c = ff(c, d, a, b, k[14], 17, -1502002290);
  1994. b = ff(b, c, d, a, k[15], 22, 1236535329);
  1995. a = gg(a, b, c, d, k[1], 5, -165796510);
  1996. d = gg(d, a, b, c, k[6], 9, -1069501632);
  1997. c = gg(c, d, a, b, k[11], 14, 643717713);
  1998. b = gg(b, c, d, a, k[0], 20, -373897302);
  1999. a = gg(a, b, c, d, k[5], 5, -701558691);
  2000. d = gg(d, a, b, c, k[10], 9, 38016083);
  2001. c = gg(c, d, a, b, k[15], 14, -660478335);
  2002. b = gg(b, c, d, a, k[4], 20, -405537848);
  2003. a = gg(a, b, c, d, k[9], 5, 568446438);
  2004. d = gg(d, a, b, c, k[14], 9, -1019803690);
  2005. c = gg(c, d, a, b, k[3], 14, -187363961);
  2006. b = gg(b, c, d, a, k[8], 20, 1163531501);
  2007. a = gg(a, b, c, d, k[13], 5, -1444681467);
  2008. d = gg(d, a, b, c, k[2], 9, -51403784);
  2009. c = gg(c, d, a, b, k[7], 14, 1735328473);
  2010. b = gg(b, c, d, a, k[12], 20, -1926607734);
  2011. a = hh(a, b, c, d, k[5], 4, -378558);
  2012. d = hh(d, a, b, c, k[8], 11, -2022574463);
  2013. c = hh(c, d, a, b, k[11], 16, 1839030562);
  2014. b = hh(b, c, d, a, k[14], 23, -35309556);
  2015. a = hh(a, b, c, d, k[1], 4, -1530992060);
  2016. d = hh(d, a, b, c, k[4], 11, 1272893353);
  2017. c = hh(c, d, a, b, k[7], 16, -155497632);
  2018. b = hh(b, c, d, a, k[10], 23, -1094730640);
  2019. a = hh(a, b, c, d, k[13], 4, 681279174);
  2020. d = hh(d, a, b, c, k[0], 11, -358537222);
  2021. c = hh(c, d, a, b, k[3], 16, -722521979);
  2022. b = hh(b, c, d, a, k[6], 23, 76029189);
  2023. a = hh(a, b, c, d, k[9], 4, -640364487);
  2024. d = hh(d, a, b, c, k[12], 11, -421815835);
  2025. c = hh(c, d, a, b, k[15], 16, 530742520);
  2026. b = hh(b, c, d, a, k[2], 23, -995338651);
  2027. a = ii(a, b, c, d, k[0], 6, -198630844);
  2028. d = ii(d, a, b, c, k[7], 10, 1126891415);
  2029. c = ii(c, d, a, b, k[14], 15, -1416354905);
  2030. b = ii(b, c, d, a, k[5], 21, -57434055);
  2031. a = ii(a, b, c, d, k[12], 6, 1700485571);
  2032. d = ii(d, a, b, c, k[3], 10, -1894986606);
  2033. c = ii(c, d, a, b, k[10], 15, -1051523);
  2034. b = ii(b, c, d, a, k[1], 21, -2054922799);
  2035. a = ii(a, b, c, d, k[8], 6, 1873313359);
  2036. d = ii(d, a, b, c, k[15], 10, -30611744);
  2037. c = ii(c, d, a, b, k[6], 15, -1560198380);
  2038. b = ii(b, c, d, a, k[13], 21, 1309151649);
  2039. a = ii(a, b, c, d, k[4], 6, -145523070);
  2040. d = ii(d, a, b, c, k[11], 10, -1120210379);
  2041. c = ii(c, d, a, b, k[2], 15, 718787259);
  2042. b = ii(b, c, d, a, k[9], 21, -343485551);
  2043. x[0] = add32(a, x[0]);
  2044. x[1] = add32(b, x[1]);
  2045. x[2] = add32(c, x[2]);
  2046. x[3] = add32(d, x[3]);
  2047. }
  2048. function cmn(q, a, b, x, s, t) {
  2049. a = add32(add32(a, q), add32(x, t));
  2050. return add32(a << s | a >>> 32 - s, b);
  2051. }
  2052. function ff(a, b, c, d, x, s, t) {
  2053. return cmn(b & c | ~b & d, a, b, x, s, t);
  2054. }
  2055. function gg(a, b, c, d, x, s, t) {
  2056. return cmn(b & d | c & ~d, a, b, x, s, t);
  2057. }
  2058. function hh(a, b, c, d, x, s, t) {
  2059. return cmn(b ^ c ^ d, a, b, x, s, t);
  2060. }
  2061. function ii(a, b, c, d, x, s, t) {
  2062. return cmn(c ^ (b | ~d), a, b, x, s, t);
  2063. }
  2064. function md5blk(s) {
  2065. /* I figured global was faster. */
  2066. var md5blks = [],
  2067. i; /* Andy King said do it this way. */
  2068. for (i = 0; i < 64; i += 4) {
  2069. md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
  2070. }
  2071. return md5blks;
  2072. }
  2073. var hex_chr = '0123456789abcdef'.split('');
  2074. function rhex(n) {
  2075. var s = '',
  2076. j = 0;
  2077. for (; j < 4; j++) s += hex_chr[n >> j * 8 + 4 & 0x0F] + hex_chr[n >> j * 8 & 0x0F];
  2078. return s;
  2079. }
  2080. function hex(x) {
  2081. for (var i = 0; i < x.length; i++) x[i] = rhex(x[i]);
  2082. return x.join('');
  2083. }
  2084. var add32 = function (a, b) {
  2085. return a + b & 0xFFFFFFFF;
  2086. };
  2087. function getCtx() {
  2088. var ctx = {};
  2089. ctx.state = [1732584193, -271733879, -1732584194, 271733878];
  2090. ctx.tail = '';
  2091. ctx.size = 0;
  2092. ctx.update = function (s, isBinStr) {
  2093. if (!isBinStr) s = unescape(encodeURIComponent(s));
  2094. ctx.size += s.length;
  2095. s = ctx.tail + s;
  2096. var i,
  2097. state = ctx.state;
  2098. for (i = 64; i <= s.length; i += 64) {
  2099. md5cycle(state, md5blk(s.substring(i - 64, i)));
  2100. }
  2101. ctx.tail = s.substring(i - 64);
  2102. return ctx;
  2103. };
  2104. ctx.digest = function (encode) {
  2105. var i,
  2106. n = ctx.size,
  2107. state = ctx.state,
  2108. s = ctx.tail,
  2109. tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
  2110. for (i = 0; i < s.length; i++) tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3);
  2111. tail[i >> 2] |= 0x80 << (i % 4 << 3);
  2112. if (i > 55) {
  2113. md5cycle(state, tail);
  2114. for (i = 0; i < 16; i++) tail[i] = 0;
  2115. }
  2116. tail[14] = n * 8;
  2117. md5cycle(state, tail);
  2118. return hex(state);
  2119. };
  2120. return ctx;
  2121. }
  2122. var md5 = function (s, isBinStr) {
  2123. return getCtx().update(s, isBinStr).digest('hex');
  2124. };
  2125. if (md5('hello') !== '5d41402abc4b2a76b9719d911017c592') {
  2126. add32 = function (x, y) {
  2127. var lsw = (x & 0xFFFF) + (y & 0xFFFF),
  2128. msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  2129. return msw << 16 | lsw & 0xFFFF;
  2130. };
  2131. }
  2132. md5.getCtx = getCtx;
  2133. module.exports = md5;
  2134. /***/ }),
  2135. /* 7 */
  2136. /***/ (function(module, exports, __webpack_require__) {
  2137. /*
  2138. CryptoJS v3.1.2
  2139. code.google.com/p/crypto-js
  2140. (c) 2009-2013 by Jeff Mott. All rights reserved.
  2141. code.google.com/p/crypto-js/wiki/License
  2142. */
  2143. var CryptoJS = CryptoJS || function (g, l) {
  2144. var e = {},
  2145. d = e.lib = {},
  2146. m = function () {},
  2147. k = d.Base = { extend: function (a) {
  2148. m.prototype = this;var c = new m();a && c.mixIn(a);c.hasOwnProperty("init") || (c.init = function () {
  2149. c.$super.init.apply(this, arguments);
  2150. });c.init.prototype = c;c.$super = this;return c;
  2151. }, create: function () {
  2152. var a = this.extend();a.init.apply(a, arguments);return a;
  2153. }, init: function () {}, mixIn: function (a) {
  2154. for (var c in a) a.hasOwnProperty(c) && (this[c] = a[c]);a.hasOwnProperty("toString") && (this.toString = a.toString);
  2155. }, clone: function () {
  2156. return this.init.prototype.extend(this);
  2157. } },
  2158. p = d.WordArray = k.extend({ init: function (a, c) {
  2159. a = this.words = a || [];this.sigBytes = c != l ? c : 4 * a.length;
  2160. }, toString: function (a) {
  2161. return (a || n).stringify(this);
  2162. }, concat: function (a) {
  2163. var c = this.words,
  2164. q = a.words,
  2165. f = this.sigBytes;a = a.sigBytes;this.clamp();if (f % 4) for (var b = 0; b < a; b++) c[f + b >>> 2] |= (q[b >>> 2] >>> 24 - 8 * (b % 4) & 255) << 24 - 8 * ((f + b) % 4);else if (65535 < q.length) for (b = 0; b < a; b += 4) c[f + b >>> 2] = q[b >>> 2];else c.push.apply(c, q);this.sigBytes += a;return this;
  2166. }, clamp: function () {
  2167. var a = this.words,
  2168. c = this.sigBytes;a[c >>> 2] &= 4294967295 << 32 - 8 * (c % 4);a.length = g.ceil(c / 4);
  2169. }, clone: function () {
  2170. var a = k.clone.call(this);a.words = this.words.slice(0);return a;
  2171. }, random: function (a) {
  2172. for (var c = [], b = 0; b < a; b += 4) c.push(4294967296 * g.random() | 0);return new p.init(c, a);
  2173. } }),
  2174. b = e.enc = {},
  2175. n = b.Hex = { stringify: function (a) {
  2176. var c = a.words;a = a.sigBytes;for (var b = [], f = 0; f < a; f++) {
  2177. var d = c[f >>> 2] >>> 24 - 8 * (f % 4) & 255;b.push((d >>> 4).toString(16));b.push((d & 15).toString(16));
  2178. }return b.join("");
  2179. }, parse: function (a) {
  2180. for (var c = a.length, b = [], f = 0; f < c; f += 2) b[f >>> 3] |= parseInt(a.substr(f, 2), 16) << 24 - 4 * (f % 8);return new p.init(b, c / 2);
  2181. } },
  2182. j = b.Latin1 = { stringify: function (a) {
  2183. var c = a.words;a = a.sigBytes;for (var b = [], f = 0; f < a; f++) b.push(String.fromCharCode(c[f >>> 2] >>> 24 - 8 * (f % 4) & 255));return b.join("");
  2184. }, parse: function (a) {
  2185. for (var c = a.length, b = [], f = 0; f < c; f++) b[f >>> 2] |= (a.charCodeAt(f) & 255) << 24 - 8 * (f % 4);return new p.init(b, c);
  2186. } },
  2187. h = b.Utf8 = { stringify: function (a) {
  2188. try {
  2189. return decodeURIComponent(escape(j.stringify(a)));
  2190. } catch (c) {
  2191. throw Error("Malformed UTF-8 data");
  2192. }
  2193. }, parse: function (a) {
  2194. return j.parse(unescape(encodeURIComponent(a)));
  2195. } },
  2196. r = d.BufferedBlockAlgorithm = k.extend({ reset: function () {
  2197. this._data = new p.init();this._nDataBytes = 0;
  2198. }, _append: function (a) {
  2199. "string" == typeof a && (a = h.parse(a));this._data.concat(a);this._nDataBytes += a.sigBytes;
  2200. }, _process: function (a) {
  2201. var c = this._data,
  2202. b = c.words,
  2203. f = c.sigBytes,
  2204. d = this.blockSize,
  2205. e = f / (4 * d),
  2206. e = a ? g.ceil(e) : g.max((e | 0) - this._minBufferSize, 0);a = e * d;f = g.min(4 * a, f);if (a) {
  2207. for (var k = 0; k < a; k += d) this._doProcessBlock(b, k);k = b.splice(0, a);c.sigBytes -= f;
  2208. }return new p.init(k, f);
  2209. }, clone: function () {
  2210. var a = k.clone.call(this);
  2211. a._data = this._data.clone();return a;
  2212. }, _minBufferSize: 0 });d.Hasher = r.extend({ cfg: k.extend(), init: function (a) {
  2213. this.cfg = this.cfg.extend(a);this.reset();
  2214. }, reset: function () {
  2215. r.reset.call(this);this._doReset();
  2216. }, update: function (a) {
  2217. this._append(a);this._process();return this;
  2218. }, finalize: function (a) {
  2219. a && this._append(a);return this._doFinalize();
  2220. }, blockSize: 16, _createHelper: function (a) {
  2221. return function (b, d) {
  2222. return new a.init(d).finalize(b);
  2223. };
  2224. }, _createHmacHelper: function (a) {
  2225. return function (b, d) {
  2226. return new s.HMAC.init(a, d).finalize(b);
  2227. };
  2228. } });var s = e.algo = {};return e;
  2229. }(Math);
  2230. (function () {
  2231. var g = CryptoJS,
  2232. l = g.lib,
  2233. e = l.WordArray,
  2234. d = l.Hasher,
  2235. m = [],
  2236. l = g.algo.SHA1 = d.extend({ _doReset: function () {
  2237. this._hash = new e.init([1732584193, 4023233417, 2562383102, 271733878, 3285377520]);
  2238. }, _doProcessBlock: function (d, e) {
  2239. for (var b = this._hash.words, n = b[0], j = b[1], h = b[2], g = b[3], l = b[4], a = 0; 80 > a; a++) {
  2240. if (16 > a) m[a] = d[e + a] | 0;else {
  2241. var c = m[a - 3] ^ m[a - 8] ^ m[a - 14] ^ m[a - 16];m[a] = c << 1 | c >>> 31;
  2242. }c = (n << 5 | n >>> 27) + l + m[a];c = 20 > a ? c + ((j & h | ~j & g) + 1518500249) : 40 > a ? c + ((j ^ h ^ g) + 1859775393) : 60 > a ? c + ((j & h | j & g | h & g) - 1894007588) : c + ((j ^ h ^ g) - 899497514);l = g;g = h;h = j << 30 | j >>> 2;j = n;n = c;
  2243. }b[0] = b[0] + n | 0;b[1] = b[1] + j | 0;b[2] = b[2] + h | 0;b[3] = b[3] + g | 0;b[4] = b[4] + l | 0;
  2244. }, _doFinalize: function () {
  2245. var d = this._data,
  2246. e = d.words,
  2247. b = 8 * this._nDataBytes,
  2248. g = 8 * d.sigBytes;e[g >>> 5] |= 128 << 24 - g % 32;e[(g + 64 >>> 9 << 4) + 14] = Math.floor(b / 4294967296);e[(g + 64 >>> 9 << 4) + 15] = b;d.sigBytes = 4 * e.length;this._process();return this._hash;
  2249. }, clone: function () {
  2250. var e = d.clone.call(this);e._hash = this._hash.clone();return e;
  2251. } });g.SHA1 = d._createHelper(l);g.HmacSHA1 = d._createHmacHelper(l);
  2252. })();
  2253. (function () {
  2254. var g = CryptoJS,
  2255. l = g.enc.Utf8;g.algo.HMAC = g.lib.Base.extend({ init: function (e, d) {
  2256. e = this._hasher = new e.init();"string" == typeof d && (d = l.parse(d));var g = e.blockSize,
  2257. k = 4 * g;d.sigBytes > k && (d = e.finalize(d));d.clamp();for (var p = this._oKey = d.clone(), b = this._iKey = d.clone(), n = p.words, j = b.words, h = 0; h < g; h++) n[h] ^= 1549556828, j[h] ^= 909522486;p.sigBytes = b.sigBytes = k;this.reset();
  2258. }, reset: function () {
  2259. var e = this._hasher;e.reset();e.update(this._iKey);
  2260. }, update: function (e) {
  2261. this._hasher.update(e);return this;
  2262. }, finalize: function (e) {
  2263. var d = this._hasher;e = d.finalize(e);d.reset();return d.finalize(this._oKey.clone().concat(e));
  2264. } });
  2265. })();
  2266. (function () {
  2267. // Shortcuts
  2268. var C = CryptoJS;
  2269. var C_lib = C.lib;
  2270. var WordArray = C_lib.WordArray;
  2271. var C_enc = C.enc;
  2272. /**
  2273. * Base64 encoding strategy.
  2274. */
  2275. var Base64 = C_enc.Base64 = {
  2276. /**
  2277. * Converts a word array to a Base64 string.
  2278. *
  2279. * @param {WordArray} wordArray The word array.
  2280. *
  2281. * @return {string} The Base64 string.
  2282. *
  2283. * @static
  2284. *
  2285. * @example
  2286. *
  2287. * var base64String = CryptoJS.enc.Base64.stringify(wordArray);
  2288. */
  2289. stringify: function (wordArray) {
  2290. // Shortcuts
  2291. var words = wordArray.words;
  2292. var sigBytes = wordArray.sigBytes;
  2293. var map = this._map;
  2294. // Clamp excess bits
  2295. wordArray.clamp();
  2296. // Convert
  2297. var base64Chars = [];
  2298. for (var i = 0; i < sigBytes; i += 3) {
  2299. var byte1 = words[i >>> 2] >>> 24 - i % 4 * 8 & 0xff;
  2300. var byte2 = words[i + 1 >>> 2] >>> 24 - (i + 1) % 4 * 8 & 0xff;
  2301. var byte3 = words[i + 2 >>> 2] >>> 24 - (i + 2) % 4 * 8 & 0xff;
  2302. var triplet = byte1 << 16 | byte2 << 8 | byte3;
  2303. for (var j = 0; j < 4 && i + j * 0.75 < sigBytes; j++) {
  2304. base64Chars.push(map.charAt(triplet >>> 6 * (3 - j) & 0x3f));
  2305. }
  2306. }
  2307. // Add padding
  2308. var paddingChar = map.charAt(64);
  2309. if (paddingChar) {
  2310. while (base64Chars.length % 4) {
  2311. base64Chars.push(paddingChar);
  2312. }
  2313. }
  2314. return base64Chars.join('');
  2315. },
  2316. /**
  2317. * Converts a Base64 string to a word array.
  2318. *
  2319. * @param {string} base64Str The Base64 string.
  2320. *
  2321. * @return {WordArray} The word array.
  2322. *
  2323. * @static
  2324. *
  2325. * @example
  2326. *
  2327. * var wordArray = CryptoJS.enc.Base64.parse(base64String);
  2328. */
  2329. parse: function (base64Str) {
  2330. // Shortcuts
  2331. var base64StrLength = base64Str.length;
  2332. var map = this._map;
  2333. // Ignore padding
  2334. var paddingChar = map.charAt(64);
  2335. if (paddingChar) {
  2336. var paddingIndex = base64Str.indexOf(paddingChar);
  2337. if (paddingIndex != -1) {
  2338. base64StrLength = paddingIndex;
  2339. }
  2340. }
  2341. // Convert
  2342. var words = [];
  2343. var nBytes = 0;
  2344. for (var i = 0; i < base64StrLength; i++) {
  2345. if (i % 4) {
  2346. var bits1 = map.indexOf(base64Str.charAt(i - 1)) << i % 4 * 2;
  2347. var bits2 = map.indexOf(base64Str.charAt(i)) >>> 6 - i % 4 * 2;
  2348. words[nBytes >>> 2] |= (bits1 | bits2) << 24 - nBytes % 4 * 8;
  2349. nBytes++;
  2350. }
  2351. }
  2352. return WordArray.create(words, nBytes);
  2353. },
  2354. _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
  2355. };
  2356. })();
  2357. if (true) {
  2358. module.exports = CryptoJS;
  2359. } else {
  2360. window.CryptoJS = CryptoJS;
  2361. }
  2362. /***/ }),
  2363. /* 8 */
  2364. /***/ (function(module, exports, __webpack_require__) {
  2365. /* Copyright 2015 William Summers, MetaTribal LLC
  2366. * adapted from https://developer.mozilla.org/en-US/docs/JXON
  2367. *
  2368. * Licensed under the MIT License, Version 2.0 (the "License");
  2369. * you may not use this file except in compliance with the License.
  2370. * You may obtain a copy of the License at
  2371. *
  2372. * https://opensource.org/licenses/MIT
  2373. *
  2374. * Unless required by applicable law or agreed to in writing, software
  2375. * distributed under the License is distributed on an "AS IS" BASIS,
  2376. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2377. * See the License for the specific language governing permissions and
  2378. * limitations under the License.
  2379. */
  2380. /**
  2381. * @author William Summers
  2382. * https://github.com/metatribal/xmlToJSON
  2383. */
  2384. var DOMParser = __webpack_require__(9).DOMParser;
  2385. var xmlToJSON = function () {
  2386. this.version = "1.3.5";
  2387. var options = { // set up the default options
  2388. mergeCDATA: true, // extract cdata and merge with text
  2389. normalize: true, // collapse multiple spaces to single space
  2390. stripElemPrefix: true // for elements of same name in diff namespaces, you can enable namespaces and access the nskey property
  2391. };
  2392. var prefixMatch = new RegExp(/(?!xmlns)^.*:/);
  2393. var trimMatch = new RegExp(/^\s+|\s+$/g);
  2394. this.grokType = function (sValue) {
  2395. if (/^\s*$/.test(sValue)) {
  2396. return null;
  2397. }
  2398. if (/^(?:true|false)$/i.test(sValue)) {
  2399. return sValue.toLowerCase() === "true";
  2400. }
  2401. if (isFinite(sValue)) {
  2402. return parseFloat(sValue);
  2403. }
  2404. return sValue;
  2405. };
  2406. this.parseString = function (xmlString, opt) {
  2407. if (xmlString) {
  2408. var xml = this.stringToXML(xmlString);
  2409. if (xml.getElementsByTagName('parsererror').length) {
  2410. return null;
  2411. } else {
  2412. return this.parseXML(xml, opt);
  2413. }
  2414. } else {
  2415. return null;
  2416. }
  2417. };
  2418. this.parseXML = function (oXMLParent, opt) {
  2419. // initialize options
  2420. for (var key in opt) {
  2421. options[key] = opt[key];
  2422. }
  2423. var vResult = {},
  2424. nLength = 0,
  2425. sCollectedTxt = "";
  2426. // iterate over the children
  2427. var childNum = oXMLParent.childNodes.length;
  2428. if (childNum) {
  2429. for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {
  2430. oNode = oXMLParent.childNodes.item(nItem);
  2431. if (oNode.nodeType === 4) {
  2432. if (options.mergeCDATA) {
  2433. sCollectedTxt += oNode.nodeValue;
  2434. }
  2435. } /* nodeType is "CDATASection" (4) */
  2436. else if (oNode.nodeType === 3) {
  2437. sCollectedTxt += oNode.nodeValue;
  2438. } /* nodeType is "Text" (3) */
  2439. else if (oNode.nodeType === 1) {
  2440. /* nodeType is "Element" (1) */
  2441. if (nLength === 0) {
  2442. vResult = {};
  2443. }
  2444. // using nodeName to support browser (IE) implementation with no 'localName' property
  2445. if (options.stripElemPrefix) {
  2446. sProp = oNode.nodeName.replace(prefixMatch, '');
  2447. } else {
  2448. sProp = oNode.nodeName;
  2449. }
  2450. vContent = xmlToJSON.parseXML(oNode);
  2451. if (vResult.hasOwnProperty(sProp)) {
  2452. if (vResult[sProp].constructor !== Array) {
  2453. vResult[sProp] = [vResult[sProp]];
  2454. }
  2455. vResult[sProp].push(vContent);
  2456. } else {
  2457. vResult[sProp] = vContent;
  2458. nLength++;
  2459. }
  2460. }
  2461. }
  2462. }
  2463. if (!Object.keys(vResult).length) {
  2464. // vResult = sCollectedTxt.replace(trimMatch, '') || ''; // by carsonxu 修复 getBucket返回的 Key 是 " /" 这种场景
  2465. vResult = sCollectedTxt || '';
  2466. }
  2467. return vResult;
  2468. };
  2469. // Convert xmlDocument to a string
  2470. // Returns null on failure
  2471. this.xmlToString = function (xmlDoc) {
  2472. try {
  2473. var xmlString = xmlDoc.xml ? xmlDoc.xml : new XMLSerializer().serializeToString(xmlDoc);
  2474. return xmlString;
  2475. } catch (err) {
  2476. return null;
  2477. }
  2478. };
  2479. // Convert a string to XML Node Structure
  2480. // Returns null on failure
  2481. this.stringToXML = function (xmlString) {
  2482. try {
  2483. var xmlDoc = null;
  2484. if (window.DOMParser) {
  2485. var parser = new DOMParser();
  2486. xmlDoc = parser.parseFromString(xmlString, "text/xml");
  2487. return xmlDoc;
  2488. } else {
  2489. xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
  2490. xmlDoc.async = false;
  2491. xmlDoc.loadXML(xmlString);
  2492. return xmlDoc;
  2493. }
  2494. } catch (e) {
  2495. return null;
  2496. }
  2497. };
  2498. return this;
  2499. }.call({});
  2500. var xml2json = function (xmlString) {
  2501. return xmlToJSON.parseString(xmlString);
  2502. };
  2503. module.exports = xml2json;
  2504. /***/ }),
  2505. /* 9 */
  2506. /***/ (function(module, exports, __webpack_require__) {
  2507. function DOMParser(options){
  2508. this.options = options ||{locator:{}};
  2509. }
  2510. DOMParser.prototype.parseFromString = function(source,mimeType){
  2511. var options = this.options;
  2512. var sax = new XMLReader();
  2513. var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
  2514. var errorHandler = options.errorHandler;
  2515. var locator = options.locator;
  2516. var defaultNSMap = options.xmlns||{};
  2517. var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"}
  2518. if(locator){
  2519. domBuilder.setDocumentLocator(locator)
  2520. }
  2521. sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
  2522. sax.domBuilder = options.domBuilder || domBuilder;
  2523. if(/\/x?html?$/.test(mimeType)){
  2524. entityMap.nbsp = '\xa0';
  2525. entityMap.copy = '\xa9';
  2526. defaultNSMap['']= 'http://www.w3.org/1999/xhtml';
  2527. }
  2528. defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace';
  2529. if(source){
  2530. sax.parse(source,defaultNSMap,entityMap);
  2531. }else{
  2532. sax.errorHandler.error("invalid doc source");
  2533. }
  2534. return domBuilder.doc;
  2535. }
  2536. function buildErrorHandler(errorImpl,domBuilder,locator){
  2537. if(!errorImpl){
  2538. if(domBuilder instanceof DOMHandler){
  2539. return domBuilder;
  2540. }
  2541. errorImpl = domBuilder ;
  2542. }
  2543. var errorHandler = {}
  2544. var isCallback = errorImpl instanceof Function;
  2545. locator = locator||{}
  2546. function build(key){
  2547. var fn = errorImpl[key];
  2548. if(!fn && isCallback){
  2549. fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl;
  2550. }
  2551. errorHandler[key] = fn && function(msg){
  2552. fn('[xmldom '+key+']\t'+msg+_locator(locator));
  2553. }||function(){};
  2554. }
  2555. build('warning');
  2556. build('error');
  2557. build('fatalError');
  2558. return errorHandler;
  2559. }
  2560. //console.log('#\n\n\n\n\n\n\n####')
  2561. /**
  2562. * +ContentHandler+ErrorHandler
  2563. * +LexicalHandler+EntityResolver2
  2564. * -DeclHandler-DTDHandler
  2565. *
  2566. * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
  2567. * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
  2568. * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
  2569. */
  2570. function DOMHandler() {
  2571. this.cdata = false;
  2572. }
  2573. function position(locator,node){
  2574. node.lineNumber = locator.lineNumber;
  2575. node.columnNumber = locator.columnNumber;
  2576. }
  2577. /**
  2578. * @see org.xml.sax.ContentHandler#startDocument
  2579. * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
  2580. */
  2581. DOMHandler.prototype = {
  2582. startDocument : function() {
  2583. this.doc = new DOMImplementation().createDocument(null, null, null);
  2584. if (this.locator) {
  2585. this.doc.documentURI = this.locator.systemId;
  2586. }
  2587. },
  2588. startElement:function(namespaceURI, localName, qName, attrs) {
  2589. var doc = this.doc;
  2590. var el = doc.createElementNS(namespaceURI, qName||localName);
  2591. var len = attrs.length;
  2592. appendElement(this, el);
  2593. this.currentElement = el;
  2594. this.locator && position(this.locator,el)
  2595. for (var i = 0 ; i < len; i++) {
  2596. var namespaceURI = attrs.getURI(i);
  2597. var value = attrs.getValue(i);
  2598. var qName = attrs.getQName(i);
  2599. var attr = doc.createAttributeNS(namespaceURI, qName);
  2600. this.locator &&position(attrs.getLocator(i),attr);
  2601. attr.value = attr.nodeValue = value;
  2602. el.setAttributeNode(attr)
  2603. }
  2604. },
  2605. endElement:function(namespaceURI, localName, qName) {
  2606. var current = this.currentElement
  2607. var tagName = current.tagName;
  2608. this.currentElement = current.parentNode;
  2609. },
  2610. startPrefixMapping:function(prefix, uri) {
  2611. },
  2612. endPrefixMapping:function(prefix) {
  2613. },
  2614. processingInstruction:function(target, data) {
  2615. var ins = this.doc.createProcessingInstruction(target, data);
  2616. this.locator && position(this.locator,ins)
  2617. appendElement(this, ins);
  2618. },
  2619. ignorableWhitespace:function(ch, start, length) {
  2620. },
  2621. characters:function(chars, start, length) {
  2622. chars = _toString.apply(this,arguments)
  2623. //console.log(chars)
  2624. if(chars){
  2625. if (this.cdata) {
  2626. var charNode = this.doc.createCDATASection(chars);
  2627. } else {
  2628. var charNode = this.doc.createTextNode(chars);
  2629. }
  2630. if(this.currentElement){
  2631. this.currentElement.appendChild(charNode);
  2632. }else if(/^\s*$/.test(chars)){
  2633. this.doc.appendChild(charNode);
  2634. //process xml
  2635. }
  2636. this.locator && position(this.locator,charNode)
  2637. }
  2638. },
  2639. skippedEntity:function(name) {
  2640. },
  2641. endDocument:function() {
  2642. this.doc.normalize();
  2643. },
  2644. setDocumentLocator:function (locator) {
  2645. if(this.locator = locator){// && !('lineNumber' in locator)){
  2646. locator.lineNumber = 0;
  2647. }
  2648. },
  2649. //LexicalHandler
  2650. comment:function(chars, start, length) {
  2651. chars = _toString.apply(this,arguments)
  2652. var comm = this.doc.createComment(chars);
  2653. this.locator && position(this.locator,comm)
  2654. appendElement(this, comm);
  2655. },
  2656. startCDATA:function() {
  2657. //used in characters() methods
  2658. this.cdata = true;
  2659. },
  2660. endCDATA:function() {
  2661. this.cdata = false;
  2662. },
  2663. startDTD:function(name, publicId, systemId) {
  2664. var impl = this.doc.implementation;
  2665. if (impl && impl.createDocumentType) {
  2666. var dt = impl.createDocumentType(name, publicId, systemId);
  2667. this.locator && position(this.locator,dt)
  2668. appendElement(this, dt);
  2669. }
  2670. },
  2671. /**
  2672. * @see org.xml.sax.ErrorHandler
  2673. * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
  2674. */
  2675. warning:function(error) {
  2676. console.warn('[xmldom warning]\t'+error,_locator(this.locator));
  2677. },
  2678. error:function(error) {
  2679. console.error('[xmldom error]\t'+error,_locator(this.locator));
  2680. },
  2681. fatalError:function(error) {
  2682. console.error('[xmldom fatalError]\t'+error,_locator(this.locator));
  2683. throw error;
  2684. }
  2685. }
  2686. function _locator(l){
  2687. if(l){
  2688. return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
  2689. }
  2690. }
  2691. function _toString(chars,start,length){
  2692. if(typeof chars == 'string'){
  2693. return chars.substr(start,length)
  2694. }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
  2695. if(chars.length >= start+length || start){
  2696. return new java.lang.String(chars,start,length)+'';
  2697. }
  2698. return chars;
  2699. }
  2700. }
  2701. /*
  2702. * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
  2703. * used method of org.xml.sax.ext.LexicalHandler:
  2704. * #comment(chars, start, length)
  2705. * #startCDATA()
  2706. * #endCDATA()
  2707. * #startDTD(name, publicId, systemId)
  2708. *
  2709. *
  2710. * IGNORED method of org.xml.sax.ext.LexicalHandler:
  2711. * #endDTD()
  2712. * #startEntity(name)
  2713. * #endEntity(name)
  2714. *
  2715. *
  2716. * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
  2717. * IGNORED method of org.xml.sax.ext.DeclHandler
  2718. * #attributeDecl(eName, aName, type, mode, value)
  2719. * #elementDecl(name, model)
  2720. * #externalEntityDecl(name, publicId, systemId)
  2721. * #internalEntityDecl(name, value)
  2722. * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
  2723. * IGNORED method of org.xml.sax.EntityResolver2
  2724. * #resolveEntity(String name,String publicId,String baseURI,String systemId)
  2725. * #resolveEntity(publicId, systemId)
  2726. * #getExternalSubset(name, baseURI)
  2727. * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
  2728. * IGNORED method of org.xml.sax.DTDHandler
  2729. * #notationDecl(name, publicId, systemId) {};
  2730. * #unparsedEntityDecl(name, publicId, systemId, notationName) {};
  2731. */
  2732. "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
  2733. DOMHandler.prototype[key] = function(){return null}
  2734. })
  2735. /* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */
  2736. function appendElement (hander,node) {
  2737. if (!hander.currentElement) {
  2738. hander.doc.appendChild(node);
  2739. } else {
  2740. hander.currentElement.appendChild(node);
  2741. }
  2742. }//appendChild and setAttributeNS are preformance key
  2743. //if(typeof require == 'function'){
  2744. var XMLReader = __webpack_require__(10).XMLReader;
  2745. var DOMImplementation = exports.DOMImplementation = __webpack_require__(1).DOMImplementation;
  2746. exports.XMLSerializer = __webpack_require__(1).XMLSerializer ;
  2747. exports.DOMParser = DOMParser;
  2748. //}
  2749. /***/ }),
  2750. /* 10 */
  2751. /***/ (function(module, exports) {
  2752. //[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
  2753. //[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
  2754. //[5] Name ::= NameStartChar (NameChar)*
  2755. var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]///\u10000-\uEFFFF
  2756. var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]");
  2757. var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
  2758. //var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
  2759. //var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',')
  2760. //S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE
  2761. //S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE
  2762. var S_TAG = 0;//tag name offerring
  2763. var S_ATTR = 1;//attr name offerring
  2764. var S_ATTR_SPACE=2;//attr name end and space offer
  2765. var S_EQ = 3;//=space?
  2766. var S_ATTR_NOQUOT_VALUE = 4;//attr value(no quot value only)
  2767. var S_ATTR_END = 5;//attr value end and no space(quot end)
  2768. var S_TAG_SPACE = 6;//(attr value end || tag end ) && (space offer)
  2769. var S_TAG_CLOSE = 7;//closed el<el />
  2770. function XMLReader(){
  2771. }
  2772. XMLReader.prototype = {
  2773. parse:function(source,defaultNSMap,entityMap){
  2774. var domBuilder = this.domBuilder;
  2775. domBuilder.startDocument();
  2776. _copy(defaultNSMap ,defaultNSMap = {})
  2777. parse(source,defaultNSMap,entityMap,
  2778. domBuilder,this.errorHandler);
  2779. domBuilder.endDocument();
  2780. }
  2781. }
  2782. function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
  2783. function fixedFromCharCode(code) {
  2784. // String.prototype.fromCharCode does not supports
  2785. // > 2 bytes unicode chars directly
  2786. if (code > 0xffff) {
  2787. code -= 0x10000;
  2788. var surrogate1 = 0xd800 + (code >> 10)
  2789. , surrogate2 = 0xdc00 + (code & 0x3ff);
  2790. return String.fromCharCode(surrogate1, surrogate2);
  2791. } else {
  2792. return String.fromCharCode(code);
  2793. }
  2794. }
  2795. function entityReplacer(a){
  2796. var k = a.slice(1,-1);
  2797. if(k in entityMap){
  2798. return entityMap[k];
  2799. }else if(k.charAt(0) === '#'){
  2800. return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
  2801. }else{
  2802. errorHandler.error('entity not found:'+a);
  2803. return a;
  2804. }
  2805. }
  2806. function appendText(end){//has some bugs
  2807. if(end>start){
  2808. var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
  2809. locator&&position(start);
  2810. domBuilder.characters(xt,0,end-start);
  2811. start = end
  2812. }
  2813. }
  2814. function position(p,m){
  2815. while(p>=lineEnd && (m = linePattern.exec(source))){
  2816. lineStart = m.index;
  2817. lineEnd = lineStart + m[0].length;
  2818. locator.lineNumber++;
  2819. //console.log('line++:',locator,startPos,endPos)
  2820. }
  2821. locator.columnNumber = p-lineStart+1;
  2822. }
  2823. var lineStart = 0;
  2824. var lineEnd = 0;
  2825. var linePattern = /.*(?:\r\n?|\n)|.*$/g
  2826. var locator = domBuilder.locator;
  2827. var parseStack = [{currentNSMap:defaultNSMapCopy}]
  2828. var closeMap = {};
  2829. var start = 0;
  2830. while(true){
  2831. try{
  2832. var tagStart = source.indexOf('<',start);
  2833. if(tagStart<0){
  2834. if(!source.substr(start).match(/^\s*$/)){
  2835. var doc = domBuilder.doc;
  2836. var text = doc.createTextNode(source.substr(start));
  2837. doc.appendChild(text);
  2838. domBuilder.currentElement = text;
  2839. }
  2840. return;
  2841. }
  2842. if(tagStart>start){
  2843. appendText(tagStart);
  2844. }
  2845. switch(source.charAt(tagStart+1)){
  2846. case '/':
  2847. var end = source.indexOf('>',tagStart+3);
  2848. var tagName = source.substring(tagStart+2,end);
  2849. var config = parseStack.pop();
  2850. if(end<0){
  2851. tagName = source.substring(tagStart+2).replace(/[\s<].*/,'');
  2852. //console.error('#@@@@@@'+tagName)
  2853. errorHandler.error("end tag name: "+tagName+' is not complete:'+config.tagName);
  2854. end = tagStart+1+tagName.length;
  2855. }else if(tagName.match(/\s</)){
  2856. tagName = tagName.replace(/[\s<].*/,'');
  2857. errorHandler.error("end tag name: "+tagName+' maybe not complete');
  2858. end = tagStart+1+tagName.length;
  2859. }
  2860. //console.error(parseStack.length,parseStack)
  2861. //console.error(config);
  2862. var localNSMap = config.localNSMap;
  2863. var endMatch = config.tagName == tagName;
  2864. var endIgnoreCaseMach = endMatch || config.tagName&&config.tagName.toLowerCase() == tagName.toLowerCase()
  2865. if(endIgnoreCaseMach){
  2866. domBuilder.endElement(config.uri,config.localName,tagName);
  2867. if(localNSMap){
  2868. for(var prefix in localNSMap){
  2869. domBuilder.endPrefixMapping(prefix) ;
  2870. }
  2871. }
  2872. if(!endMatch){
  2873. errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName );
  2874. }
  2875. }else{
  2876. parseStack.push(config)
  2877. }
  2878. end++;
  2879. break;
  2880. // end elment
  2881. case '?':// <?...?>
  2882. locator&&position(tagStart);
  2883. end = parseInstruction(source,tagStart,domBuilder);
  2884. break;
  2885. case '!':// <!doctype,<![CDATA,<!--
  2886. locator&&position(tagStart);
  2887. end = parseDCC(source,tagStart,domBuilder,errorHandler);
  2888. break;
  2889. default:
  2890. locator&&position(tagStart);
  2891. var el = new ElementAttributes();
  2892. var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
  2893. //elStartEnd
  2894. var end = parseElementStartPart(source,tagStart,el,currentNSMap,entityReplacer,errorHandler);
  2895. var len = el.length;
  2896. if(!el.closed && fixSelfClosed(source,end,el.tagName,closeMap)){
  2897. el.closed = true;
  2898. if(!entityMap.nbsp){
  2899. errorHandler.warning('unclosed xml attribute');
  2900. }
  2901. }
  2902. if(locator && len){
  2903. var locator2 = copyLocator(locator,{});
  2904. //try{//attribute position fixed
  2905. for(var i = 0;i<len;i++){
  2906. var a = el[i];
  2907. position(a.offset);
  2908. a.locator = copyLocator(locator,{});
  2909. }
  2910. //}catch(e){console.error('@@@@@'+e)}
  2911. domBuilder.locator = locator2
  2912. if(appendElement(el,domBuilder,currentNSMap)){
  2913. parseStack.push(el)
  2914. }
  2915. domBuilder.locator = locator;
  2916. }else{
  2917. if(appendElement(el,domBuilder,currentNSMap)){
  2918. parseStack.push(el)
  2919. }
  2920. }
  2921. if(el.uri === 'http://www.w3.org/1999/xhtml' && !el.closed){
  2922. end = parseHtmlSpecialContent(source,end,el.tagName,entityReplacer,domBuilder)
  2923. }else{
  2924. end++;
  2925. }
  2926. }
  2927. }catch(e){
  2928. errorHandler.error('element parse error: '+e)
  2929. //errorHandler.error('element parse error: '+e);
  2930. end = -1;
  2931. //throw e;
  2932. }
  2933. if(end>start){
  2934. start = end;
  2935. }else{
  2936. //TODO: 这里有可能sax回退,有位置错误风险
  2937. appendText(Math.max(tagStart,start)+1);
  2938. }
  2939. }
  2940. }
  2941. function copyLocator(f,t){
  2942. t.lineNumber = f.lineNumber;
  2943. t.columnNumber = f.columnNumber;
  2944. return t;
  2945. }
  2946. /**
  2947. * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
  2948. * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
  2949. */
  2950. function parseElementStartPart(source,start,el,currentNSMap,entityReplacer,errorHandler){
  2951. var attrName;
  2952. var value;
  2953. var p = ++start;
  2954. var s = S_TAG;//status
  2955. while(true){
  2956. var c = source.charAt(p);
  2957. switch(c){
  2958. case '=':
  2959. if(s === S_ATTR){//attrName
  2960. attrName = source.slice(start,p);
  2961. s = S_EQ;
  2962. }else if(s === S_ATTR_SPACE){
  2963. s = S_EQ;
  2964. }else{
  2965. //fatalError: equal must after attrName or space after attrName
  2966. throw new Error('attribute equal must after attrName');
  2967. }
  2968. break;
  2969. case '\'':
  2970. case '"':
  2971. if(s === S_EQ || s === S_ATTR //|| s == S_ATTR_SPACE
  2972. ){//equal
  2973. if(s === S_ATTR){
  2974. errorHandler.warning('attribute value must after "="')
  2975. attrName = source.slice(start,p)
  2976. }
  2977. start = p+1;
  2978. p = source.indexOf(c,start)
  2979. if(p>0){
  2980. value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
  2981. el.add(attrName,value,start-1);
  2982. s = S_ATTR_END;
  2983. }else{
  2984. //fatalError: no end quot match
  2985. throw new Error('attribute value no end \''+c+'\' match');
  2986. }
  2987. }else if(s == S_ATTR_NOQUOT_VALUE){
  2988. value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
  2989. //console.log(attrName,value,start,p)
  2990. el.add(attrName,value,start);
  2991. //console.dir(el)
  2992. errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
  2993. start = p+1;
  2994. s = S_ATTR_END
  2995. }else{
  2996. //fatalError: no equal before
  2997. throw new Error('attribute value must after "="');
  2998. }
  2999. break;
  3000. case '/':
  3001. switch(s){
  3002. case S_TAG:
  3003. el.setTagName(source.slice(start,p));
  3004. case S_ATTR_END:
  3005. case S_TAG_SPACE:
  3006. case S_TAG_CLOSE:
  3007. s =S_TAG_CLOSE;
  3008. el.closed = true;
  3009. case S_ATTR_NOQUOT_VALUE:
  3010. case S_ATTR:
  3011. case S_ATTR_SPACE:
  3012. break;
  3013. //case S_EQ:
  3014. default:
  3015. throw new Error("attribute invalid close char('/')")
  3016. }
  3017. break;
  3018. case ''://end document
  3019. //throw new Error('unexpected end of input')
  3020. errorHandler.error('unexpected end of input');
  3021. if(s == S_TAG){
  3022. el.setTagName(source.slice(start,p));
  3023. }
  3024. return p;
  3025. case '>':
  3026. switch(s){
  3027. case S_TAG:
  3028. el.setTagName(source.slice(start,p));
  3029. case S_ATTR_END:
  3030. case S_TAG_SPACE:
  3031. case S_TAG_CLOSE:
  3032. break;//normal
  3033. case S_ATTR_NOQUOT_VALUE://Compatible state
  3034. case S_ATTR:
  3035. value = source.slice(start,p);
  3036. if(value.slice(-1) === '/'){
  3037. el.closed = true;
  3038. value = value.slice(0,-1)
  3039. }
  3040. case S_ATTR_SPACE:
  3041. if(s === S_ATTR_SPACE){
  3042. value = attrName;
  3043. }
  3044. if(s == S_ATTR_NOQUOT_VALUE){
  3045. errorHandler.warning('attribute "'+value+'" missed quot(")!!');
  3046. el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start)
  3047. }else{
  3048. if(currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !value.match(/^(?:disabled|checked|selected)$/i)){
  3049. errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!')
  3050. }
  3051. el.add(value,value,start)
  3052. }
  3053. break;
  3054. case S_EQ:
  3055. throw new Error('attribute value missed!!');
  3056. }
  3057. // console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
  3058. return p;
  3059. /*xml space '\x20' | #x9 | #xD | #xA; */
  3060. case '\u0080':
  3061. c = ' ';
  3062. default:
  3063. if(c<= ' '){//space
  3064. switch(s){
  3065. case S_TAG:
  3066. el.setTagName(source.slice(start,p));//tagName
  3067. s = S_TAG_SPACE;
  3068. break;
  3069. case S_ATTR:
  3070. attrName = source.slice(start,p)
  3071. s = S_ATTR_SPACE;
  3072. break;
  3073. case S_ATTR_NOQUOT_VALUE:
  3074. var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
  3075. errorHandler.warning('attribute "'+value+'" missed quot(")!!');
  3076. el.add(attrName,value,start)
  3077. case S_ATTR_END:
  3078. s = S_TAG_SPACE;
  3079. break;
  3080. //case S_TAG_SPACE:
  3081. //case S_EQ:
  3082. //case S_ATTR_SPACE:
  3083. // void();break;
  3084. //case S_TAG_CLOSE:
  3085. //ignore warning
  3086. }
  3087. }else{//not space
  3088. //S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE
  3089. //S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE
  3090. switch(s){
  3091. //case S_TAG:void();break;
  3092. //case S_ATTR:void();break;
  3093. //case S_ATTR_NOQUOT_VALUE:void();break;
  3094. case S_ATTR_SPACE:
  3095. var tagName = el.tagName;
  3096. if(currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !attrName.match(/^(?:disabled|checked|selected)$/i)){
  3097. errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead2!!')
  3098. }
  3099. el.add(attrName,attrName,start);
  3100. start = p;
  3101. s = S_ATTR;
  3102. break;
  3103. case S_ATTR_END:
  3104. errorHandler.warning('attribute space is required"'+attrName+'"!!')
  3105. case S_TAG_SPACE:
  3106. s = S_ATTR;
  3107. start = p;
  3108. break;
  3109. case S_EQ:
  3110. s = S_ATTR_NOQUOT_VALUE;
  3111. start = p;
  3112. break;
  3113. case S_TAG_CLOSE:
  3114. throw new Error("elements closed character '/' and '>' must be connected to");
  3115. }
  3116. }
  3117. }//end outer switch
  3118. //console.log('p++',p)
  3119. p++;
  3120. }
  3121. }
  3122. /**
  3123. * @return true if has new namespace define
  3124. */
  3125. function appendElement(el,domBuilder,currentNSMap){
  3126. var tagName = el.tagName;
  3127. var localNSMap = null;
  3128. //var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
  3129. var i = el.length;
  3130. while(i--){
  3131. var a = el[i];
  3132. var qName = a.qName;
  3133. var value = a.value;
  3134. var nsp = qName.indexOf(':');
  3135. if(nsp>0){
  3136. var prefix = a.prefix = qName.slice(0,nsp);
  3137. var localName = qName.slice(nsp+1);
  3138. var nsPrefix = prefix === 'xmlns' && localName
  3139. }else{
  3140. localName = qName;
  3141. prefix = null
  3142. nsPrefix = qName === 'xmlns' && ''
  3143. }
  3144. //can not set prefix,because prefix !== ''
  3145. a.localName = localName ;
  3146. //prefix == null for no ns prefix attribute
  3147. if(nsPrefix !== false){//hack!!
  3148. if(localNSMap == null){
  3149. localNSMap = {}
  3150. //console.log(currentNSMap,0)
  3151. _copy(currentNSMap,currentNSMap={})
  3152. //console.log(currentNSMap,1)
  3153. }
  3154. currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
  3155. a.uri = 'http://www.w3.org/2000/xmlns/'
  3156. domBuilder.startPrefixMapping(nsPrefix, value)
  3157. }
  3158. }
  3159. var i = el.length;
  3160. while(i--){
  3161. a = el[i];
  3162. var prefix = a.prefix;
  3163. if(prefix){//no prefix attribute has no namespace
  3164. if(prefix === 'xml'){
  3165. a.uri = 'http://www.w3.org/XML/1998/namespace';
  3166. }if(prefix !== 'xmlns'){
  3167. a.uri = currentNSMap[prefix || '']
  3168. //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
  3169. }
  3170. }
  3171. }
  3172. var nsp = tagName.indexOf(':');
  3173. if(nsp>0){
  3174. prefix = el.prefix = tagName.slice(0,nsp);
  3175. localName = el.localName = tagName.slice(nsp+1);
  3176. }else{
  3177. prefix = null;//important!!
  3178. localName = el.localName = tagName;
  3179. }
  3180. //no prefix element has default namespace
  3181. var ns = el.uri = currentNSMap[prefix || ''];
  3182. domBuilder.startElement(ns,localName,tagName,el);
  3183. //endPrefixMapping and startPrefixMapping have not any help for dom builder
  3184. //localNSMap = null
  3185. if(el.closed){
  3186. domBuilder.endElement(ns,localName,tagName);
  3187. if(localNSMap){
  3188. for(prefix in localNSMap){
  3189. domBuilder.endPrefixMapping(prefix)
  3190. }
  3191. }
  3192. }else{
  3193. el.currentNSMap = currentNSMap;
  3194. el.localNSMap = localNSMap;
  3195. //parseStack.push(el);
  3196. return true;
  3197. }
  3198. }
  3199. function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
  3200. if(/^(?:script|textarea)$/i.test(tagName)){
  3201. var elEndStart = source.indexOf('</'+tagName+'>',elStartEnd);
  3202. var text = source.substring(elStartEnd+1,elEndStart);
  3203. if(/[&<]/.test(text)){
  3204. if(/^script$/i.test(tagName)){
  3205. //if(!/\]\]>/.test(text)){
  3206. //lexHandler.startCDATA();
  3207. domBuilder.characters(text,0,text.length);
  3208. //lexHandler.endCDATA();
  3209. return elEndStart;
  3210. //}
  3211. }//}else{//text area
  3212. text = text.replace(/&#?\w+;/g,entityReplacer);
  3213. domBuilder.characters(text,0,text.length);
  3214. return elEndStart;
  3215. //}
  3216. }
  3217. }
  3218. return elStartEnd+1;
  3219. }
  3220. function fixSelfClosed(source,elStartEnd,tagName,closeMap){
  3221. //if(tagName in closeMap){
  3222. var pos = closeMap[tagName];
  3223. if(pos == null){
  3224. //console.log(tagName)
  3225. pos = source.lastIndexOf('</'+tagName+'>')
  3226. if(pos<elStartEnd){//忘记闭合
  3227. pos = source.lastIndexOf('</'+tagName)
  3228. }
  3229. closeMap[tagName] =pos
  3230. }
  3231. return pos<elStartEnd;
  3232. //}
  3233. }
  3234. function _copy(source,target){
  3235. for(var n in source){target[n] = source[n]}
  3236. }
  3237. function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
  3238. var next= source.charAt(start+2)
  3239. switch(next){
  3240. case '-':
  3241. if(source.charAt(start + 3) === '-'){
  3242. var end = source.indexOf('-->',start+4);
  3243. //append comment source.substring(4,end)//<!--
  3244. if(end>start){
  3245. domBuilder.comment(source,start+4,end-start-4);
  3246. return end+3;
  3247. }else{
  3248. errorHandler.error("Unclosed comment");
  3249. return -1;
  3250. }
  3251. }else{
  3252. //error
  3253. return -1;
  3254. }
  3255. default:
  3256. if(source.substr(start+3,6) == 'CDATA['){
  3257. var end = source.indexOf(']]>',start+9);
  3258. domBuilder.startCDATA();
  3259. domBuilder.characters(source,start+9,end-start-9);
  3260. domBuilder.endCDATA()
  3261. return end+3;
  3262. }
  3263. //<!DOCTYPE
  3264. //startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
  3265. var matchs = split(source,start);
  3266. var len = matchs.length;
  3267. if(len>1 && /!doctype/i.test(matchs[0][0])){
  3268. var name = matchs[1][0];
  3269. var pubid = len>3 && /^public$/i.test(matchs[2][0]) && matchs[3][0]
  3270. var sysid = len>4 && matchs[4][0];
  3271. var lastMatch = matchs[len-1]
  3272. domBuilder.startDTD(name,pubid && pubid.replace(/^(['"])(.*?)\1$/,'$2'),
  3273. sysid && sysid.replace(/^(['"])(.*?)\1$/,'$2'));
  3274. domBuilder.endDTD();
  3275. return lastMatch.index+lastMatch[0].length
  3276. }
  3277. }
  3278. return -1;
  3279. }
  3280. function parseInstruction(source,start,domBuilder){
  3281. var end = source.indexOf('?>',start);
  3282. if(end){
  3283. var match = source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
  3284. if(match){
  3285. var len = match[0].length;
  3286. domBuilder.processingInstruction(match[1], match[2]) ;
  3287. return end+2;
  3288. }else{//error
  3289. return -1;
  3290. }
  3291. }
  3292. return -1;
  3293. }
  3294. /**
  3295. * @param source
  3296. */
  3297. function ElementAttributes(source){
  3298. }
  3299. ElementAttributes.prototype = {
  3300. setTagName:function(tagName){
  3301. if(!tagNamePattern.test(tagName)){
  3302. throw new Error('invalid tagName:'+tagName)
  3303. }
  3304. this.tagName = tagName
  3305. },
  3306. add:function(qName,value,offset){
  3307. if(!tagNamePattern.test(qName)){
  3308. throw new Error('invalid attribute:'+qName)
  3309. }
  3310. this[this.length++] = {qName:qName,value:value,offset:offset}
  3311. },
  3312. length:0,
  3313. getLocalName:function(i){return this[i].localName},
  3314. getLocator:function(i){return this[i].locator},
  3315. getQName:function(i){return this[i].qName},
  3316. getURI:function(i){return this[i].uri},
  3317. getValue:function(i){return this[i].value}
  3318. // ,getIndex:function(uri, localName)){
  3319. // if(localName){
  3320. //
  3321. // }else{
  3322. // var qName = uri
  3323. // }
  3324. // },
  3325. // getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
  3326. // getType:function(uri,localName){}
  3327. // getType:function(i){},
  3328. }
  3329. function _set_proto_(thiz,parent){
  3330. thiz.__proto__ = parent;
  3331. return thiz;
  3332. }
  3333. if(!(_set_proto_({},_set_proto_.prototype) instanceof _set_proto_)){
  3334. _set_proto_ = function(thiz,parent){
  3335. function p(){};
  3336. p.prototype = parent;
  3337. p = new p();
  3338. for(parent in thiz){
  3339. p[parent] = thiz[parent];
  3340. }
  3341. return p;
  3342. }
  3343. }
  3344. function split(source,start){
  3345. var match;
  3346. var buf = [];
  3347. var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
  3348. reg.lastIndex = start;
  3349. reg.exec(source);//skip <
  3350. while(match = reg.exec(source)){
  3351. buf.push(match);
  3352. if(match[1])return buf;
  3353. }
  3354. }
  3355. exports.XMLReader = XMLReader;
  3356. /***/ }),
  3357. /* 11 */
  3358. /***/ (function(module, exports) {
  3359. //copyright Ryan Day 2010 <http://ryanday.org>, Joscha Feth 2013 <http://www.feth.com> [MIT Licensed]
  3360. var element_start_char = "a-zA-Z_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FFF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD";
  3361. var element_non_start_char = "\-.0-9\u00B7\u0300-\u036F\u203F\u2040";
  3362. var element_replace = new RegExp("^([^" + element_start_char + "])|^((x|X)(m|M)(l|L))|([^" + element_start_char + element_non_start_char + "])", "g");
  3363. var not_safe_in_xml = /[^\x09\x0A\x0D\x20-\xFF\x85\xA0-\uD7FF\uE000-\uFDCF\uFDE0-\uFFFD]/gm;
  3364. var objKeys = function (obj) {
  3365. var l = [];
  3366. if (obj instanceof Object) {
  3367. for (var k in obj) {
  3368. if (obj.hasOwnProperty(k)) {
  3369. l.push(k);
  3370. }
  3371. }
  3372. }
  3373. return l;
  3374. };
  3375. var process_to_xml = function (node_data, options) {
  3376. var makeNode = function (name, content, attributes, level, hasSubNodes) {
  3377. var indent_value = options.indent !== undefined ? options.indent : "\t";
  3378. var indent = options.prettyPrint ? '\n' + new Array(level).join(indent_value) : '';
  3379. if (options.removeIllegalNameCharacters) {
  3380. name = name.replace(element_replace, '_');
  3381. }
  3382. var node = [indent, '<', name, attributes || ''];
  3383. if (content && content.length > 0) {
  3384. node.push('>');
  3385. node.push(content);
  3386. hasSubNodes && node.push(indent);
  3387. node.push('</');
  3388. node.push(name);
  3389. node.push('>');
  3390. } else {
  3391. node.push('/>');
  3392. }
  3393. return node.join('');
  3394. };
  3395. return function fn(node_data, node_descriptor, level) {
  3396. var type = typeof node_data;
  3397. if (Array.isArray ? Array.isArray(node_data) : node_data instanceof Array) {
  3398. type = 'array';
  3399. } else if (node_data instanceof Date) {
  3400. type = 'date';
  3401. }
  3402. switch (type) {
  3403. //if value is an array create child nodes from values
  3404. case 'array':
  3405. var ret = [];
  3406. node_data.map(function (v) {
  3407. ret.push(fn(v, 1, level + 1));
  3408. //entries that are values of an array are the only ones that can be special node descriptors
  3409. });
  3410. options.prettyPrint && ret.push('\n');
  3411. return ret.join('');
  3412. break;
  3413. case 'date':
  3414. // cast dates to ISO 8601 date (soap likes it)
  3415. return node_data.toJSON ? node_data.toJSON() : node_data + '';
  3416. break;
  3417. case 'object':
  3418. var nodes = [];
  3419. for (var name in node_data) {
  3420. if (node_data.hasOwnProperty(name)) {
  3421. if (node_data[name] instanceof Array) {
  3422. for (var j = 0; j < node_data[name].length; j++) {
  3423. if (node_data[name].hasOwnProperty(j)) {
  3424. nodes.push(makeNode(name, fn(node_data[name][j], 0, level + 1), null, level + 1, objKeys(node_data[name][j]).length));
  3425. }
  3426. }
  3427. } else {
  3428. nodes.push(makeNode(name, fn(node_data[name], 0, level + 1), null, level + 1));
  3429. }
  3430. }
  3431. }
  3432. options.prettyPrint && nodes.length > 0 && nodes.push('\n');
  3433. return nodes.join('');
  3434. break;
  3435. case 'function':
  3436. return node_data();
  3437. break;
  3438. default:
  3439. return options.escape ? esc(node_data) : '' + node_data;
  3440. }
  3441. }(node_data, 0, 0);
  3442. };
  3443. var xml_header = function (standalone) {
  3444. var ret = ['<?xml version="1.0" encoding="UTF-8"'];
  3445. if (standalone) {
  3446. ret.push(' standalone="yes"');
  3447. }
  3448. ret.push('?>');
  3449. return ret.join('');
  3450. };
  3451. function esc(str) {
  3452. return ('' + str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/'/g, '&apos;').replace(/"/g, '&quot;').replace(not_safe_in_xml, '');
  3453. }
  3454. module.exports = function (obj, options) {
  3455. if (!options) {
  3456. options = {
  3457. xmlHeader: {
  3458. standalone: true
  3459. },
  3460. prettyPrint: true,
  3461. indent: " ",
  3462. escape: true
  3463. };
  3464. }
  3465. if (typeof obj == 'string') {
  3466. try {
  3467. obj = JSON.parse(obj.toString());
  3468. } catch (e) {
  3469. return false;
  3470. }
  3471. }
  3472. var xmlheader = '';
  3473. var docType = '';
  3474. if (options) {
  3475. if (typeof options == 'object') {
  3476. // our config is an object
  3477. if (options.xmlHeader) {
  3478. // the user wants an xml header
  3479. xmlheader = xml_header(!!options.xmlHeader.standalone);
  3480. }
  3481. if (typeof options.docType != 'undefined') {
  3482. docType = '<!DOCTYPE ' + options.docType + '>';
  3483. }
  3484. } else {
  3485. // our config is a boolean value, so just add xml header
  3486. xmlheader = xml_header();
  3487. }
  3488. }
  3489. options = options || {};
  3490. var ret = [xmlheader, options.prettyPrint && docType ? '\n' : '', docType, process_to_xml(obj, options)];
  3491. return ret.join('').replace(/\n{2,}/g, '\n').replace(/\s+$/g, '');
  3492. };
  3493. /***/ }),
  3494. /* 12 */
  3495. /***/ (function(module, exports, __webpack_require__) {
  3496. var session = __webpack_require__(3);
  3497. var util = __webpack_require__(0);
  3498. var originApiMap = {};
  3499. var transferToTaskMethod = function (apiMap, apiName) {
  3500. originApiMap[apiName] = apiMap[apiName];
  3501. apiMap[apiName] = function (params, callback) {
  3502. if (params.SkipTask) {
  3503. originApiMap[apiName].call(this, params, callback);
  3504. } else {
  3505. this._addTask(apiName, params, callback);
  3506. }
  3507. };
  3508. };
  3509. var initTask = function (cos) {
  3510. var queue = [];
  3511. var tasks = {};
  3512. var uploadingFileCount = 0;
  3513. var nextUploadIndex = 0;
  3514. // 接口返回简略的任务信息
  3515. var formatTask = function (task) {
  3516. var t = {
  3517. id: task.id,
  3518. Bucket: task.Bucket,
  3519. Region: task.Region,
  3520. Key: task.Key,
  3521. FilePath: task.FilePath,
  3522. state: task.state,
  3523. loaded: task.loaded,
  3524. size: task.size,
  3525. speed: task.speed,
  3526. percent: task.percent,
  3527. hashPercent: task.hashPercent,
  3528. error: task.error
  3529. };
  3530. if (task.FilePath) t.FilePath = task.FilePath;
  3531. if (task._custom) t._custom = task._custom;
  3532. return t;
  3533. };
  3534. var emitListUpdate = function () {
  3535. var timer;
  3536. var emit = function () {
  3537. timer = 0;
  3538. cos.emit('task-list-update', { list: util.map(queue, formatTask) });
  3539. cos.emit('list-update', { list: util.map(queue, formatTask) });
  3540. };
  3541. return function () {
  3542. if (!timer) timer = setTimeout(emit);
  3543. };
  3544. }();
  3545. var clearQueue = function () {
  3546. if (queue.length <= cos.options.UploadQueueSize) return;
  3547. for (var i = 0; i < nextUploadIndex && // 小于当前操作的 index 才清理
  3548. i < queue.length && // 大于队列才清理
  3549. queue.length > cos.options.UploadQueueSize // 如果还太多,才继续清理
  3550. ;) {
  3551. var isActive = queue[i].state === 'waiting' || queue[i].state === 'checking' || queue[i].state === 'uploading';
  3552. if (!queue[i] || !isActive) {
  3553. tasks[queue[i].id] && delete tasks[queue[i].id];
  3554. queue.splice(i, 1);
  3555. nextUploadIndex--;
  3556. } else {
  3557. i++;
  3558. }
  3559. }
  3560. emitListUpdate();
  3561. };
  3562. var startNextTask = function () {
  3563. // 检查是否允许增加执行进程
  3564. if (uploadingFileCount >= cos.options.FileParallelLimit) return;
  3565. // 跳过不可执行的任务
  3566. while (queue[nextUploadIndex] && queue[nextUploadIndex].state !== 'waiting') nextUploadIndex++;
  3567. // 检查是否已遍历结束
  3568. if (nextUploadIndex >= queue.length) return;
  3569. // 上传该遍历到的任务
  3570. var task = queue[nextUploadIndex];
  3571. nextUploadIndex++;
  3572. uploadingFileCount++;
  3573. task.state = 'checking';
  3574. task.params.onTaskStart && task.params.onTaskStart(formatTask(task));
  3575. !task.params.UploadData && (task.params.UploadData = {});
  3576. var apiParams = util.formatParams(task.api, task.params);
  3577. originApiMap[task.api].call(cos, apiParams, function (err, data) {
  3578. if (!cos._isRunningTask(task.id)) return;
  3579. if (task.state === 'checking' || task.state === 'uploading') {
  3580. task.state = err ? 'error' : 'success';
  3581. err && (task.error = err);
  3582. uploadingFileCount--;
  3583. emitListUpdate();
  3584. startNextTask();
  3585. task.callback && task.callback(err, data);
  3586. if (task.state === 'success') {
  3587. if (task.params) {
  3588. delete task.params.UploadData;
  3589. delete task.params.Body;
  3590. delete task.params;
  3591. }
  3592. delete task.callback;
  3593. }
  3594. }
  3595. clearQueue();
  3596. });
  3597. emitListUpdate();
  3598. // 异步执行下一个任务
  3599. setTimeout(startNextTask);
  3600. };
  3601. var killTask = function (id, switchToState) {
  3602. var task = tasks[id];
  3603. if (!task) return;
  3604. var waiting = task && task.state === 'waiting';
  3605. var running = task && (task.state === 'checking' || task.state === 'uploading');
  3606. if (switchToState === 'canceled' && task.state !== 'canceled' || switchToState === 'paused' && waiting || switchToState === 'paused' && running) {
  3607. if (switchToState === 'paused' && task.params.Body && typeof task.params.Body.pipe === 'function') {
  3608. console.error('stream not support pause');
  3609. return;
  3610. }
  3611. task.state = switchToState;
  3612. cos.emit('inner-kill-task', { TaskId: id, toState: switchToState });
  3613. try {
  3614. var UploadId = task && task.params && task.params.UploadData.UploadId;
  3615. } catch (e) {}
  3616. if (switchToState === 'canceled' && UploadId) session.removeUsing(UploadId);
  3617. emitListUpdate();
  3618. if (running) {
  3619. uploadingFileCount--;
  3620. startNextTask();
  3621. }
  3622. if (switchToState === 'canceled') {
  3623. if (task.params) {
  3624. delete task.params.UploadData;
  3625. delete task.params.Body;
  3626. delete task.params;
  3627. }
  3628. delete task.callback;
  3629. }
  3630. }
  3631. clearQueue();
  3632. };
  3633. cos._addTasks = function (taskList) {
  3634. util.each(taskList, function (task) {
  3635. cos._addTask(task.api, task.params, task.callback, true);
  3636. });
  3637. emitListUpdate();
  3638. };
  3639. var isTaskReadyWarning = true;
  3640. cos._addTask = function (api, params, callback, ignoreAddEvent) {
  3641. // 复制参数对象
  3642. params = util.formatParams(api, params);
  3643. // 生成 id
  3644. var id = util.uuid();
  3645. params.TaskId = id;
  3646. params.onTaskReady && params.onTaskReady(id);
  3647. if (params.TaskReady) {
  3648. params.TaskReady(id);
  3649. isTaskReadyWarning && console.warn('warning: Param "TaskReady" has been deprecated. Please use "onTaskReady" instead.');
  3650. isTaskReadyWarning = false;
  3651. }
  3652. var task = {
  3653. // env
  3654. params: params,
  3655. callback: callback,
  3656. api: api,
  3657. index: queue.length,
  3658. // task
  3659. id: id,
  3660. Bucket: params.Bucket,
  3661. Region: params.Region,
  3662. Key: params.Key,
  3663. FilePath: params.FilePath || '',
  3664. state: 'waiting',
  3665. loaded: 0,
  3666. size: 0,
  3667. speed: 0,
  3668. percent: 0,
  3669. hashPercent: 0,
  3670. error: null,
  3671. _custom: params._custom
  3672. };
  3673. var onHashProgress = params.onHashProgress;
  3674. params.onHashProgress = function (info) {
  3675. if (!cos._isRunningTask(task.id)) return;
  3676. task.hashPercent = info.percent;
  3677. onHashProgress && onHashProgress(info);
  3678. emitListUpdate();
  3679. };
  3680. var onProgress = params.onProgress;
  3681. params.onProgress = function (info) {
  3682. if (!cos._isRunningTask(task.id)) return;
  3683. task.state === 'checking' && (task.state = 'uploading');
  3684. task.loaded = info.loaded;
  3685. task.speed = info.speed;
  3686. task.percent = info.percent;
  3687. onProgress && onProgress(info);
  3688. emitListUpdate();
  3689. };
  3690. // 异步获取 filesize
  3691. util.getFileSize(api, params, function (err, size) {
  3692. // 开始处理上传
  3693. if (err) {
  3694. // 如果获取大小出错,不加入队列
  3695. callback(err);
  3696. return;
  3697. }
  3698. // 获取完文件大小再把任务加入队列
  3699. tasks[id] = task;
  3700. queue.push(task);
  3701. task.size = size;
  3702. !ignoreAddEvent && emitListUpdate();
  3703. startNextTask();
  3704. clearQueue();
  3705. });
  3706. return id;
  3707. };
  3708. cos._isRunningTask = function (id) {
  3709. var task = tasks[id];
  3710. return !!(task && (task.state === 'checking' || task.state === 'uploading'));
  3711. };
  3712. cos.getTaskList = function () {
  3713. return util.map(queue, formatTask);
  3714. };
  3715. cos.cancelTask = function (id) {
  3716. killTask(id, 'canceled');
  3717. };
  3718. cos.pauseTask = function (id) {
  3719. killTask(id, 'paused');
  3720. };
  3721. cos.restartTask = function (id) {
  3722. var task = tasks[id];
  3723. if (task && (task.state === 'paused' || task.state === 'error')) {
  3724. task.state = 'waiting';
  3725. emitListUpdate();
  3726. nextUploadIndex = Math.min(nextUploadIndex, task.index);
  3727. startNextTask();
  3728. }
  3729. };
  3730. cos.isUploadRunning = function () {
  3731. return uploadingFileCount || nextUploadIndex < queue.length;
  3732. };
  3733. };
  3734. module.exports.transferToTaskMethod = transferToTaskMethod;
  3735. module.exports.init = initTask;
  3736. /***/ }),
  3737. /* 13 */
  3738. /***/ (function(module, exports, __webpack_require__) {
  3739. var REQUEST = __webpack_require__(14);
  3740. var util = __webpack_require__(0);
  3741. // Bucket 相关
  3742. /**
  3743. * 获取用户的 bucket 列表
  3744. * @param {Object} params 回调函数,必须,下面为参数列表
  3745. * 无特殊参数
  3746. * @param {Function} callback 回调函数,必须
  3747. */
  3748. function getService(params, callback) {
  3749. if (typeof params === 'function') {
  3750. callback = params;
  3751. params = {};
  3752. }
  3753. var protocol = this.options.Protocol || (util.isBrowser && location.protocol === 'http:' ? 'http:' : 'https:');
  3754. var domain = this.options.ServiceDomain;
  3755. var region = params.Region;
  3756. if (domain) {
  3757. domain = domain.replace(/\{Region\}/ig, region || '').replace(/\{.*?\}/ig, '');
  3758. if (!/^[a-zA-Z]+:\/\//.test(domain)) {
  3759. domain = protocol + '//' + domain;
  3760. }
  3761. if (domain.slice(-1) === '/') {
  3762. domain = domain.slice(0, -1);
  3763. }
  3764. } else if (region) {
  3765. domain = protocol + '//cos.' + region + '.myqcloud.com';
  3766. } else {
  3767. domain = protocol + '//service.cos.myqcloud.com';
  3768. }
  3769. submitRequest.call(this, {
  3770. Action: 'name/cos:GetService',
  3771. url: domain,
  3772. method: 'GET',
  3773. headers: params.Headers
  3774. }, function (err, data) {
  3775. if (err) {
  3776. return callback(err);
  3777. }
  3778. var buckets = data && data.ListAllMyBucketsResult && data.ListAllMyBucketsResult.Buckets && data.ListAllMyBucketsResult.Buckets.Bucket || [];
  3779. buckets = util.isArray(buckets) ? buckets : [buckets];
  3780. var owner = data && data.ListAllMyBucketsResult && data.ListAllMyBucketsResult.Owner || {};
  3781. callback(null, {
  3782. Buckets: buckets,
  3783. Owner: owner,
  3784. statusCode: data.statusCode,
  3785. headers: data.headers
  3786. });
  3787. });
  3788. }
  3789. /**
  3790. * 创建 Bucket,并初始化访问权限
  3791. * @param {Object} params 参数对象,必须
  3792. * @param {String} params.Bucket Bucket名称,必须
  3793. * @param {String} params.Region 地域名称,必须
  3794. * @param {String} params.ACL 用户自定义文件权限,可以设置:private,public-read;默认值:private,非必须
  3795. * @param {String} params.GrantRead 赋予被授权者读的权限,格式x-cos-grant-read: uin=" ",uin=" ",非必须
  3796. * @param {String} params.GrantWrite 赋予被授权者写的权限,格式x-cos-grant-write: uin=" ",uin=" ",非必须
  3797. * @param {String} params.GrantFullControl 赋予被授权者读写权限,格式x-cos-grant-full-control: uin=" ",uin=" ",非必须
  3798. * @param {Function} callback 回调函数,必须
  3799. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  3800. * @return {Object} data 返回的数据
  3801. * @return {String} data.Location 操作地址
  3802. */
  3803. function putBucket(params, callback) {
  3804. var self = this;
  3805. submitRequest.call(this, {
  3806. Action: 'name/cos:PutBucket',
  3807. method: 'PUT',
  3808. Bucket: params.Bucket,
  3809. Region: params.Region,
  3810. headers: params.Headers
  3811. }, function (err, data) {
  3812. if (err) {
  3813. return callback(err);
  3814. }
  3815. var url = getUrl({
  3816. protocol: self.options.Protocol,
  3817. domain: self.options.Domain,
  3818. bucket: params.Bucket,
  3819. region: params.Region,
  3820. isLocation: true
  3821. });
  3822. callback(null, {
  3823. Location: url,
  3824. statusCode: data.statusCode,
  3825. headers: data.headers
  3826. });
  3827. });
  3828. }
  3829. /**
  3830. * 查看是否存在该Bucket,是否有权限访问
  3831. * @param {Object} params 参数对象,必须
  3832. * @param {String} params.Bucket Bucket名称,必须
  3833. * @param {String} params.Region 地域名称,必须
  3834. * @param {Function} callback 回调函数,必须
  3835. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  3836. * @return {Object} data 返回的数据
  3837. * @return {Boolean} data.BucketExist Bucket是否存在
  3838. * @return {Boolean} data.BucketAuth 是否有 Bucket 的访问权限
  3839. */
  3840. function headBucket(params, callback) {
  3841. submitRequest.call(this, {
  3842. Action: 'name/cos:HeadBucket',
  3843. Bucket: params.Bucket,
  3844. Region: params.Region,
  3845. headers: params.Headers,
  3846. method: 'HEAD'
  3847. }, function (err, data) {
  3848. callback(err, data);
  3849. });
  3850. }
  3851. /**
  3852. * 获取 Bucket 下的 object 列表
  3853. * @param {Object} params 参数对象,必须
  3854. * @param {String} params.Bucket Bucket名称,必须
  3855. * @param {String} params.Region 地域名称,必须
  3856. * @param {String} params.Prefix 前缀匹配,用来规定返回的文件前缀地址,非必须
  3857. * @param {String} params.Delimiter 定界符为一个符号,如果有Prefix,则将Prefix到delimiter之间的相同路径归为一类,非必须
  3858. * @param {String} params.Marker 默认以UTF-8二进制顺序列出条目,所有列出条目从marker开始,非必须
  3859. * @param {String} params.MaxKeys 单次返回最大的条目数量,默认1000,非必须
  3860. * @param {String} params.EncodingType 规定返回值的编码方式,非必须
  3861. * @param {Function} callback 回调函数,必须
  3862. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  3863. * @return {Object} data 返回的数据
  3864. * @return {Object} data.ListBucketResult 返回的 object 列表信息
  3865. */
  3866. function getBucket(params, callback) {
  3867. var reqParams = {};
  3868. reqParams['prefix'] = params['Prefix'] || '';
  3869. reqParams['delimiter'] = params['Delimiter'];
  3870. reqParams['marker'] = params['Marker'];
  3871. reqParams['max-keys'] = params['MaxKeys'];
  3872. reqParams['encoding-type'] = params['EncodingType'];
  3873. submitRequest.call(this, {
  3874. Action: 'name/cos:GetBucket',
  3875. ResourceKey: reqParams['prefix'],
  3876. method: 'GET',
  3877. Bucket: params.Bucket,
  3878. Region: params.Region,
  3879. headers: params.Headers,
  3880. qs: reqParams
  3881. }, function (err, data) {
  3882. if (err) {
  3883. return callback(err);
  3884. }
  3885. var ListBucketResult = data.ListBucketResult || {};
  3886. var Contents = ListBucketResult.Contents || [];
  3887. var CommonPrefixes = ListBucketResult.CommonPrefixes || [];
  3888. Contents = util.isArray(Contents) ? Contents : [Contents];
  3889. CommonPrefixes = util.isArray(CommonPrefixes) ? CommonPrefixes : [CommonPrefixes];
  3890. var result = util.clone(ListBucketResult);
  3891. util.extend(result, {
  3892. Contents: Contents,
  3893. CommonPrefixes: CommonPrefixes,
  3894. statusCode: data.statusCode,
  3895. headers: data.headers
  3896. });
  3897. callback(null, result);
  3898. });
  3899. }
  3900. /**
  3901. * 删除 Bucket
  3902. * @param {Object} params 参数对象,必须
  3903. * @param {String} params.Bucket Bucket名称,必须
  3904. * @param {String} params.Region 地域名称,必须
  3905. * @param {Function} callback 回调函数,必须
  3906. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  3907. * @return {Object} data 返回的数据
  3908. * @return {String} data.Location 操作地址
  3909. */
  3910. function deleteBucket(params, callback) {
  3911. submitRequest.call(this, {
  3912. Action: 'name/cos:DeleteBucket',
  3913. Bucket: params.Bucket,
  3914. Region: params.Region,
  3915. headers: params.Headers,
  3916. method: 'DELETE'
  3917. }, function (err, data) {
  3918. if (err && err.statusCode === 204) {
  3919. return callback(null, { statusCode: err.statusCode });
  3920. } else if (err) {
  3921. return callback(err);
  3922. }
  3923. callback(null, {
  3924. statusCode: data.statusCode,
  3925. headers: data.headers
  3926. });
  3927. });
  3928. }
  3929. /**
  3930. * 设置 Bucket 的 权限列表
  3931. * @param {Object} params 参数对象,必须
  3932. * @param {String} params.Bucket Bucket名称,必须
  3933. * @param {String} params.Region 地域名称,必须
  3934. * @param {String} params.ACL 用户自定义文件权限,可以设置:private,public-read;默认值:private,非必须
  3935. * @param {String} params.GrantRead 赋予被授权者读的权限,格式x-cos-grant-read: uin=" ",uin=" ",非必须
  3936. * @param {String} params.GrantWrite 赋予被授权者写的权限,格式x-cos-grant-write: uin=" ",uin=" ",非必须
  3937. * @param {String} params.GrantFullControl 赋予被授权者读写权限,格式x-cos-grant-full-control: uin=" ",uin=" ",非必须
  3938. * @param {Function} callback 回调函数,必须
  3939. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  3940. * @return {Object} data 返回的数据
  3941. */
  3942. function putBucketAcl(params, callback) {
  3943. var headers = params.Headers;
  3944. var xml = '';
  3945. if (params['AccessControlPolicy']) {
  3946. var AccessControlPolicy = util.clone(params['AccessControlPolicy'] || {});
  3947. var Grants = AccessControlPolicy.Grants || AccessControlPolicy.Grant;
  3948. Grants = util.isArray(Grants) ? Grants : [Grants];
  3949. delete AccessControlPolicy.Grant;
  3950. delete AccessControlPolicy.Grants;
  3951. AccessControlPolicy.AccessControlList = { Grant: Grants };
  3952. xml = util.json2xml({ AccessControlPolicy: AccessControlPolicy });
  3953. headers['Content-Type'] = 'application/xml';
  3954. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  3955. }
  3956. // Grant Header 去重
  3957. util.each(headers, function (val, key) {
  3958. if (key.indexOf('x-cos-grant-') === 0) {
  3959. headers[key] = uniqGrant(headers[key]);
  3960. }
  3961. });
  3962. submitRequest.call(this, {
  3963. Action: 'name/cos:PutBucketACL',
  3964. method: 'PUT',
  3965. Bucket: params.Bucket,
  3966. Region: params.Region,
  3967. headers: headers,
  3968. action: 'acl',
  3969. body: xml
  3970. }, function (err, data) {
  3971. if (err) {
  3972. return callback(err);
  3973. }
  3974. callback(null, {
  3975. statusCode: data.statusCode,
  3976. headers: data.headers
  3977. });
  3978. });
  3979. }
  3980. /**
  3981. * 获取 Bucket 的 权限列表
  3982. * @param {Object} params 参数对象,必须
  3983. * @param {String} params.Bucket Bucket名称,必须
  3984. * @param {String} params.Region 地域名称,必须
  3985. * @param {Function} callback 回调函数,必须
  3986. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  3987. * @return {Object} data 返回的数据
  3988. * @return {Object} data.AccessControlPolicy 访问权限信息
  3989. */
  3990. function getBucketAcl(params, callback) {
  3991. submitRequest.call(this, {
  3992. Action: 'name/cos:GetBucketACL',
  3993. method: 'GET',
  3994. Bucket: params.Bucket,
  3995. Region: params.Region,
  3996. headers: params.Headers,
  3997. action: 'acl'
  3998. }, function (err, data) {
  3999. if (err) {
  4000. return callback(err);
  4001. }
  4002. var AccessControlPolicy = data.AccessControlPolicy || {};
  4003. var Owner = AccessControlPolicy.Owner || {};
  4004. var Grant = AccessControlPolicy.AccessControlList.Grant || [];
  4005. Grant = util.isArray(Grant) ? Grant : [Grant];
  4006. var result = decodeAcl(AccessControlPolicy);
  4007. if (data.headers && data.headers['x-cos-acl']) {
  4008. result.ACL = data.headers['x-cos-acl'];
  4009. }
  4010. result = util.extend(result, {
  4011. Owner: Owner,
  4012. Grants: Grant,
  4013. statusCode: data.statusCode,
  4014. headers: data.headers
  4015. });
  4016. callback(null, result);
  4017. });
  4018. }
  4019. /**
  4020. * 设置 Bucket 的 跨域设置
  4021. * @param {Object} params 参数对象,必须
  4022. * @param {String} params.Bucket Bucket名称,必须
  4023. * @param {String} params.Region 地域名称,必须
  4024. * @param {Object} params.CORSConfiguration 相关的跨域设置,必须
  4025. * @param {Array} params.CORSConfiguration.CORSRules 对应的跨域规则
  4026. * @param {Function} callback 回调函数,必须
  4027. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4028. * @return {Object} data 返回的数据
  4029. */
  4030. function putBucketCors(params, callback) {
  4031. var CORSConfiguration = params['CORSConfiguration'] || {};
  4032. var CORSRules = CORSConfiguration['CORSRules'] || params['CORSRules'] || [];
  4033. CORSRules = util.clone(util.isArray(CORSRules) ? CORSRules : [CORSRules]);
  4034. util.each(CORSRules, function (rule) {
  4035. util.each(['AllowedOrigin', 'AllowedHeader', 'AllowedMethod', 'ExposeHeader'], function (key, k) {
  4036. var sKey = key + 's';
  4037. var val = rule[sKey] || rule[key] || [];
  4038. delete rule[sKey];
  4039. rule[key] = util.isArray(val) ? val : [val];
  4040. });
  4041. });
  4042. var xml = util.json2xml({ CORSConfiguration: { CORSRule: CORSRules } });
  4043. var headers = params.Headers;
  4044. headers['Content-Type'] = 'application/xml';
  4045. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  4046. submitRequest.call(this, {
  4047. Action: 'name/cos:PutBucketCORS',
  4048. method: 'PUT',
  4049. Bucket: params.Bucket,
  4050. Region: params.Region,
  4051. body: xml,
  4052. action: 'cors',
  4053. headers: headers
  4054. }, function (err, data) {
  4055. if (err) {
  4056. return callback(err);
  4057. }
  4058. callback(null, {
  4059. statusCode: data.statusCode,
  4060. headers: data.headers
  4061. });
  4062. });
  4063. }
  4064. /**
  4065. * 获取 Bucket 的 跨域设置
  4066. * @param {Object} params 参数对象,必须
  4067. * @param {String} params.Bucket Bucket名称,必须
  4068. * @param {String} params.Region 地域名称,必须
  4069. * @param {Function} callback 回调函数,必须
  4070. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4071. * @return {Object} data 返回的数据
  4072. * @return {Object} data.CORSRules Bucket的跨域设置
  4073. */
  4074. function getBucketCors(params, callback) {
  4075. submitRequest.call(this, {
  4076. Action: 'name/cos:GetBucketCORS',
  4077. method: 'GET',
  4078. Bucket: params.Bucket,
  4079. Region: params.Region,
  4080. headers: params.Headers,
  4081. action: 'cors'
  4082. }, function (err, data) {
  4083. if (err) {
  4084. if (err.statusCode === 404 && err.error && err.error.Code === 'NoSuchCORSConfiguration') {
  4085. var result = {
  4086. CORSRules: [],
  4087. statusCode: err.statusCode
  4088. };
  4089. err.headers && (result.headers = err.headers);
  4090. callback(null, result);
  4091. } else {
  4092. callback(err);
  4093. }
  4094. return;
  4095. }
  4096. var CORSConfiguration = data.CORSConfiguration || {};
  4097. var CORSRules = CORSConfiguration.CORSRules || CORSConfiguration.CORSRule || [];
  4098. CORSRules = util.clone(util.isArray(CORSRules) ? CORSRules : [CORSRules]);
  4099. util.each(CORSRules, function (rule) {
  4100. util.each(['AllowedOrigin', 'AllowedHeader', 'AllowedMethod', 'ExposeHeader'], function (key, j) {
  4101. var sKey = key + 's';
  4102. var val = rule[sKey] || rule[key] || [];
  4103. delete rule[key];
  4104. rule[sKey] = util.isArray(val) ? val : [val];
  4105. });
  4106. });
  4107. callback(null, {
  4108. CORSRules: CORSRules,
  4109. statusCode: data.statusCode,
  4110. headers: data.headers
  4111. });
  4112. });
  4113. }
  4114. /**
  4115. * 删除 Bucket 的 跨域设置
  4116. * @param {Object} params 参数对象,必须
  4117. * @param {String} params.Bucket Bucket名称,必须
  4118. * @param {String} params.Region 地域名称,必须
  4119. * @param {Function} callback 回调函数,必须
  4120. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4121. * @return {Object} data 返回的数据
  4122. */
  4123. function deleteBucketCors(params, callback) {
  4124. submitRequest.call(this, {
  4125. Action: 'name/cos:DeleteBucketCORS',
  4126. method: 'DELETE',
  4127. Bucket: params.Bucket,
  4128. Region: params.Region,
  4129. headers: params.Headers,
  4130. action: 'cors'
  4131. }, function (err, data) {
  4132. if (err && err.statusCode === 204) {
  4133. return callback(null, { statusCode: err.statusCode });
  4134. } else if (err) {
  4135. return callback(err);
  4136. }
  4137. callback(null, {
  4138. statusCode: data.statusCode || err.statusCode,
  4139. headers: data.headers
  4140. });
  4141. });
  4142. }
  4143. /**
  4144. * 获取 Bucket 的 地域信息
  4145. * @param {Object} params 参数对象,必须
  4146. * @param {String} params.Bucket Bucket名称,必须
  4147. * @param {String} params.Region 地域名称,必须
  4148. * @param {Function} callback 回调函数,必须
  4149. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4150. * @return {Object} data 返回数据,包含地域信息 LocationConstraint
  4151. */
  4152. function getBucketLocation(params, callback) {
  4153. submitRequest.call(this, {
  4154. Action: 'name/cos:GetBucketLocation',
  4155. method: 'GET',
  4156. Bucket: params.Bucket,
  4157. Region: params.Region,
  4158. headers: params.Headers,
  4159. action: 'location'
  4160. }, function (err, data) {
  4161. if (err) {
  4162. return callback(err);
  4163. }
  4164. callback(null, data);
  4165. });
  4166. }
  4167. function putBucketPolicy(params, callback) {
  4168. var Policy = params['Policy'];
  4169. var PolicyStr = Policy;
  4170. try {
  4171. if (typeof Policy === 'string') {
  4172. Policy = JSON.parse(PolicyStr);
  4173. } else {
  4174. PolicyStr = JSON.stringify(Policy);
  4175. }
  4176. } catch (e) {
  4177. callback({ error: 'Policy format error' });
  4178. }
  4179. var headers = params.Headers;
  4180. headers['Content-Type'] = 'application/json';
  4181. headers['Content-MD5'] = util.binaryBase64(util.md5(PolicyStr));
  4182. submitRequest.call(this, {
  4183. Action: 'name/cos:PutBucketPolicy',
  4184. method: 'PUT',
  4185. Bucket: params.Bucket,
  4186. Region: params.Region,
  4187. action: 'policy',
  4188. body: util.isBrowser ? PolicyStr : Policy,
  4189. headers: headers,
  4190. json: true
  4191. }, function (err, data) {
  4192. if (err && err.statusCode === 204) {
  4193. return callback(null, { statusCode: err.statusCode });
  4194. } else if (err) {
  4195. return callback(err);
  4196. }
  4197. callback(null, {
  4198. statusCode: data.statusCode,
  4199. headers: data.headers
  4200. });
  4201. });
  4202. }
  4203. /**
  4204. * 获取 Bucket 的读取权限策略
  4205. * @param {Object} params 参数对象,必须
  4206. * @param {String} params.Bucket Bucket名称,必须
  4207. * @param {String} params.Region 地域名称,必须
  4208. * @param {Function} callback 回调函数,必须
  4209. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4210. * @return {Object} data 返回数据
  4211. */
  4212. function getBucketPolicy(params, callback) {
  4213. submitRequest.call(this, {
  4214. Action: 'name/cos:GetBucketPolicy',
  4215. method: 'GET',
  4216. Bucket: params.Bucket,
  4217. Region: params.Region,
  4218. headers: params.Headers,
  4219. action: 'policy',
  4220. rawBody: true
  4221. }, function (err, data) {
  4222. if (err) {
  4223. if (err.statusCode && err.statusCode === 403) {
  4224. return callback({ ErrorStatus: 'Access Denied' });
  4225. }
  4226. if (err.statusCode && err.statusCode === 405) {
  4227. return callback({ ErrorStatus: 'Method Not Allowed' });
  4228. }
  4229. if (err.statusCode && err.statusCode === 404) {
  4230. return callback({ ErrorStatus: 'Policy Not Found' });
  4231. }
  4232. return callback(err);
  4233. }
  4234. var Policy = {};
  4235. try {
  4236. Policy = JSON.parse(data.body);
  4237. } catch (e) {}
  4238. callback(null, {
  4239. Policy: Policy,
  4240. statusCode: data.statusCode,
  4241. headers: data.headers
  4242. });
  4243. });
  4244. }
  4245. /**
  4246. * 删除 Bucket 的 跨域设置
  4247. * @param {Object} params 参数对象,必须
  4248. * @param {String} params.Bucket Bucket名称,必须
  4249. * @param {String} params.Region 地域名称,必须
  4250. * @param {Function} callback 回调函数,必须
  4251. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4252. * @return {Object} data 返回的数据
  4253. */
  4254. function deleteBucketPolicy(params, callback) {
  4255. submitRequest.call(this, {
  4256. Action: 'name/cos:DeleteBucketPolicy',
  4257. method: 'DELETE',
  4258. Bucket: params.Bucket,
  4259. Region: params.Region,
  4260. headers: params.Headers,
  4261. action: 'policy'
  4262. }, function (err, data) {
  4263. if (err && err.statusCode === 204) {
  4264. return callback(null, { statusCode: err.statusCode });
  4265. } else if (err) {
  4266. return callback(err);
  4267. }
  4268. callback(null, {
  4269. statusCode: data.statusCode || err.statusCode,
  4270. headers: data.headers
  4271. });
  4272. });
  4273. }
  4274. /**
  4275. * 设置 Bucket 的标签
  4276. * @param {Object} params 参数对象,必须
  4277. * @param {String} params.Bucket Bucket名称,必须
  4278. * @param {String} params.Region 地域名称,必须
  4279. * @param {Array} params.TagSet 标签设置,必须
  4280. * @param {Function} callback 回调函数,必须
  4281. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4282. * @return {Object} data 返回数据
  4283. */
  4284. function putBucketTagging(params, callback) {
  4285. var Tagging = params['Tagging'] || {};
  4286. var Tags = Tagging.TagSet || Tagging.Tags || params['Tags'] || [];
  4287. Tags = util.clone(util.isArray(Tags) ? Tags : [Tags]);
  4288. var xml = util.json2xml({ Tagging: { TagSet: { Tag: Tags } } });
  4289. var headers = params.Headers;
  4290. headers['Content-Type'] = 'application/xml';
  4291. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  4292. submitRequest.call(this, {
  4293. Action: 'name/cos:PutBucketTagging',
  4294. method: 'PUT',
  4295. Bucket: params.Bucket,
  4296. Region: params.Region,
  4297. body: xml,
  4298. action: 'tagging',
  4299. headers: headers
  4300. }, function (err, data) {
  4301. if (err && err.statusCode === 204) {
  4302. return callback(null, { statusCode: err.statusCode });
  4303. } else if (err) {
  4304. return callback(err);
  4305. }
  4306. callback(null, {
  4307. statusCode: data.statusCode,
  4308. headers: data.headers
  4309. });
  4310. });
  4311. }
  4312. /**
  4313. * 获取 Bucket 的标签设置
  4314. * @param {Object} params 参数对象,必须
  4315. * @param {String} params.Bucket Bucket名称,必须
  4316. * @param {String} params.Region 地域名称,必须
  4317. * @param {Function} callback 回调函数,必须
  4318. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4319. * @return {Object} data 返回数据
  4320. */
  4321. function getBucketTagging(params, callback) {
  4322. submitRequest.call(this, {
  4323. Action: 'name/cos:GetBucketTagging',
  4324. method: 'GET',
  4325. Bucket: params.Bucket,
  4326. Region: params.Region,
  4327. headers: params.Headers,
  4328. action: 'tagging'
  4329. }, function (err, data) {
  4330. if (err) {
  4331. if (err.statusCode === 404 && err.error && (err.error === "Not Found" || err.error.Code === 'NoSuchTagSet')) {
  4332. var result = {
  4333. Tags: [],
  4334. statusCode: err.statusCode
  4335. };
  4336. err.headers && (result.headers = err.headers);
  4337. callback(null, result);
  4338. } else {
  4339. callback(err);
  4340. }
  4341. return;
  4342. }
  4343. var Tags = [];
  4344. try {
  4345. Tags = data.Tagging.TagSet.Tag || [];
  4346. } catch (e) {}
  4347. Tags = util.clone(util.isArray(Tags) ? Tags : [Tags]);
  4348. callback(null, {
  4349. Tags: Tags,
  4350. statusCode: data.statusCode,
  4351. headers: data.headers
  4352. });
  4353. });
  4354. }
  4355. /**
  4356. * 删除 Bucket 的 标签设置
  4357. * @param {Object} params 参数对象,必须
  4358. * @param {String} params.Bucket Bucket名称,必须
  4359. * @param {String} params.Region 地域名称,必须
  4360. * @param {Function} callback 回调函数,必须
  4361. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4362. * @return {Object} data 返回的数据
  4363. */
  4364. function deleteBucketTagging(params, callback) {
  4365. submitRequest.call(this, {
  4366. Action: 'name/cos:DeleteBucketTagging',
  4367. method: 'DELETE',
  4368. Bucket: params.Bucket,
  4369. Region: params.Region,
  4370. headers: params.Headers,
  4371. action: 'tagging'
  4372. }, function (err, data) {
  4373. if (err && err.statusCode === 204) {
  4374. return callback(null, { statusCode: err.statusCode });
  4375. } else if (err) {
  4376. return callback(err);
  4377. }
  4378. callback(null, {
  4379. statusCode: data.statusCode,
  4380. headers: data.headers
  4381. });
  4382. });
  4383. }
  4384. function putBucketLifecycle(params, callback) {
  4385. var LifecycleConfiguration = params['LifecycleConfiguration'] || {};
  4386. var Rules = LifecycleConfiguration.Rules || params.Rules || [];
  4387. Rules = util.clone(Rules);
  4388. var xml = util.json2xml({ LifecycleConfiguration: { Rule: Rules } });
  4389. var headers = params.Headers;
  4390. headers['Content-Type'] = 'application/xml';
  4391. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  4392. submitRequest.call(this, {
  4393. Action: 'name/cos:PutBucketLifecycle',
  4394. method: 'PUT',
  4395. Bucket: params.Bucket,
  4396. Region: params.Region,
  4397. body: xml,
  4398. action: 'lifecycle',
  4399. headers: headers
  4400. }, function (err, data) {
  4401. if (err && err.statusCode === 204) {
  4402. return callback(null, { statusCode: err.statusCode });
  4403. } else if (err) {
  4404. return callback(err);
  4405. }
  4406. callback(null, {
  4407. statusCode: data.statusCode,
  4408. headers: data.headers
  4409. });
  4410. });
  4411. }
  4412. function getBucketLifecycle(params, callback) {
  4413. submitRequest.call(this, {
  4414. Action: 'name/cos:GetBucketLifecycle',
  4415. method: 'GET',
  4416. Bucket: params.Bucket,
  4417. Region: params.Region,
  4418. headers: params.Headers,
  4419. action: 'lifecycle'
  4420. }, function (err, data) {
  4421. if (err) {
  4422. if (err.statusCode === 404 && err.error && err.error.Code === 'NoSuchLifecycleConfiguration') {
  4423. var result = {
  4424. Rules: [],
  4425. statusCode: err.statusCode
  4426. };
  4427. err.headers && (result.headers = err.headers);
  4428. callback(null, result);
  4429. } else {
  4430. callback(err);
  4431. }
  4432. return;
  4433. }
  4434. var Rules = [];
  4435. try {
  4436. Rules = data.LifecycleConfiguration.Rule || [];
  4437. } catch (e) {}
  4438. Rules = util.clone(util.isArray(Rules) ? Rules : [Rules]);
  4439. callback(null, {
  4440. Rules: Rules,
  4441. statusCode: data.statusCode,
  4442. headers: data.headers
  4443. });
  4444. });
  4445. }
  4446. function deleteBucketLifecycle(params, callback) {
  4447. submitRequest.call(this, {
  4448. Action: 'name/cos:DeleteBucketLifecycle',
  4449. method: 'DELETE',
  4450. Bucket: params.Bucket,
  4451. Region: params.Region,
  4452. headers: params.Headers,
  4453. action: 'lifecycle'
  4454. }, function (err, data) {
  4455. if (err && err.statusCode === 204) {
  4456. return callback(null, { statusCode: err.statusCode });
  4457. } else if (err) {
  4458. return callback(err);
  4459. }
  4460. callback(null, {
  4461. statusCode: data.statusCode,
  4462. headers: data.headers
  4463. });
  4464. });
  4465. }
  4466. function putBucketVersioning(params, callback) {
  4467. if (!params['VersioningConfiguration']) {
  4468. callback({ error: 'missing param VersioningConfiguration' });
  4469. return;
  4470. }
  4471. var VersioningConfiguration = params['VersioningConfiguration'] || {};
  4472. var xml = util.json2xml({ VersioningConfiguration: VersioningConfiguration });
  4473. var headers = params.Headers;
  4474. headers['Content-Type'] = 'application/xml';
  4475. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  4476. submitRequest.call(this, {
  4477. Action: 'name/cos:PutBucketVersioning',
  4478. method: 'PUT',
  4479. Bucket: params.Bucket,
  4480. Region: params.Region,
  4481. body: xml,
  4482. action: 'versioning',
  4483. headers: headers
  4484. }, function (err, data) {
  4485. if (err && err.statusCode === 204) {
  4486. return callback(null, { statusCode: err.statusCode });
  4487. } else if (err) {
  4488. return callback(err);
  4489. }
  4490. callback(null, {
  4491. statusCode: data.statusCode,
  4492. headers: data.headers
  4493. });
  4494. });
  4495. }
  4496. function getBucketVersioning(params, callback) {
  4497. submitRequest.call(this, {
  4498. Action: 'name/cos:GetBucketVersioning',
  4499. method: 'GET',
  4500. Bucket: params.Bucket,
  4501. Region: params.Region,
  4502. headers: params.Headers,
  4503. action: 'versioning'
  4504. }, function (err, data) {
  4505. if (!err) {
  4506. !data.VersioningConfiguration && (data.VersioningConfiguration = {});
  4507. }
  4508. callback(err, data);
  4509. });
  4510. }
  4511. function putBucketReplication(params, callback) {
  4512. var ReplicationConfiguration = util.clone(params.ReplicationConfiguration);
  4513. var xml = util.json2xml({ ReplicationConfiguration: ReplicationConfiguration });
  4514. xml = xml.replace(/<(\/?)Rules>/ig, '<$1Rule>');
  4515. xml = xml.replace(/<(\/?)Tags>/ig, '<$1Tag>');
  4516. var headers = params.Headers;
  4517. headers['Content-Type'] = 'application/xml';
  4518. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  4519. submitRequest.call(this, {
  4520. Action: 'name/cos:PutBucketReplication',
  4521. method: 'PUT',
  4522. Bucket: params.Bucket,
  4523. Region: params.Region,
  4524. body: xml,
  4525. action: 'replication',
  4526. headers: headers
  4527. }, function (err, data) {
  4528. if (err && err.statusCode === 204) {
  4529. return callback(null, { statusCode: err.statusCode });
  4530. } else if (err) {
  4531. return callback(err);
  4532. }
  4533. callback(null, {
  4534. statusCode: data.statusCode,
  4535. headers: data.headers
  4536. });
  4537. });
  4538. }
  4539. function getBucketReplication(params, callback) {
  4540. submitRequest.call(this, {
  4541. Action: 'name/cos:GetBucketReplication',
  4542. method: 'GET',
  4543. Bucket: params.Bucket,
  4544. Region: params.Region,
  4545. headers: params.Headers,
  4546. action: 'replication'
  4547. }, function (err, data) {
  4548. if (err) {
  4549. if (err.statusCode === 404 && err.error && (err.error === 'Not Found' || err.error.Code === 'ReplicationConfigurationnotFoundError')) {
  4550. var result = {
  4551. ReplicationConfiguration: { Rules: [] },
  4552. statusCode: err.statusCode
  4553. };
  4554. err.headers && (result.headers = err.headers);
  4555. callback(null, result);
  4556. } else {
  4557. callback(err);
  4558. }
  4559. return;
  4560. }
  4561. if (!err) {
  4562. !data.ReplicationConfiguration && (data.ReplicationConfiguration = {});
  4563. }
  4564. if (data.ReplicationConfiguration.Rule) {
  4565. data.ReplicationConfiguration.Rules = data.ReplicationConfiguration.Rule;
  4566. delete data.ReplicationConfiguration.Rule;
  4567. }
  4568. callback(err, data);
  4569. });
  4570. }
  4571. function deleteBucketReplication(params, callback) {
  4572. submitRequest.call(this, {
  4573. Action: 'name/cos:DeleteBucketReplication',
  4574. method: 'DELETE',
  4575. Bucket: params.Bucket,
  4576. Region: params.Region,
  4577. headers: params.Headers,
  4578. action: 'replication'
  4579. }, function (err, data) {
  4580. if (err && err.statusCode === 204) {
  4581. return callback(null, { statusCode: err.statusCode });
  4582. } else if (err) {
  4583. return callback(err);
  4584. }
  4585. callback(null, {
  4586. statusCode: data.statusCode,
  4587. headers: data.headers
  4588. });
  4589. });
  4590. }
  4591. /**
  4592. * 设置 Bucket 静态网站配置信息
  4593. * @param {Object} params 参数对象,必须
  4594. * @param {String} params.Bucket Bucket名称,必须
  4595. * @param {String} params.Region 地域名称,必须
  4596. * @param {Object} params.WebsiteConfiguration 地域名称,必须
  4597. * @param {Object} WebsiteConfiguration.IndexDocument 索引文档,必须
  4598. * @param {Object} WebsiteConfiguration.ErrorDocument 错误文档,非必须
  4599. * @param {Object} WebsiteConfiguration.RedirectAllRequestsTo 重定向所有请求,非必须
  4600. * @param {Array} params.RoutingRules 重定向规则,非必须
  4601. * @param {Function} callback 回调函数,必须
  4602. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4603. * @return {Object} data 返回数据
  4604. */
  4605. function putBucketWebsite(params, callback) {
  4606. if (!params['WebsiteConfiguration']) {
  4607. callback({ error: 'missing param WebsiteConfiguration' });
  4608. return;
  4609. }
  4610. var WebsiteConfiguration = util.clone(params['WebsiteConfiguration'] || {});
  4611. var RoutingRules = WebsiteConfiguration['RoutingRules'] || WebsiteConfiguration['RoutingRule'] || [];
  4612. RoutingRules = util.isArray(RoutingRules) ? RoutingRules : [RoutingRules];
  4613. delete WebsiteConfiguration.RoutingRule;
  4614. delete WebsiteConfiguration.RoutingRules;
  4615. RoutingRules.length > 0 && (WebsiteConfiguration.RoutingRules = { RoutingRule: RoutingRules });
  4616. var xml = util.json2xml({ WebsiteConfiguration: WebsiteConfiguration });
  4617. var headers = params.Headers;
  4618. headers['Content-Type'] = 'application/xml';
  4619. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  4620. submitRequest.call(this, {
  4621. Action: 'name/cos:PutBucketWebsite',
  4622. method: 'PUT',
  4623. Bucket: params.Bucket,
  4624. Region: params.Region,
  4625. body: xml,
  4626. action: 'website',
  4627. headers: headers
  4628. }, function (err, data) {
  4629. if (err && err.statusCode === 204) {
  4630. return callback(null, { statusCode: err.statusCode });
  4631. } else if (err) {
  4632. return callback(err);
  4633. }
  4634. callback(null, {
  4635. statusCode: data.statusCode,
  4636. headers: data.headers
  4637. });
  4638. });
  4639. }
  4640. /**
  4641. * 获取 Bucket 的静态网站配置信息
  4642. * @param {Object} params 参数对象,必须
  4643. * @param {String} params.Bucket Bucket名称,必须
  4644. * @param {String} params.Region 地域名称,必须
  4645. * @param {Function} callback 回调函数,必须
  4646. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4647. * @return {Object} data 返回数据
  4648. */
  4649. function getBucketWebsite(params, callback) {
  4650. submitRequest.call(this, {
  4651. Action: 'name/cos:GetBucketWebsite',
  4652. method: 'GET',
  4653. Bucket: params.Bucket,
  4654. Region: params.Region,
  4655. Key: params.Key,
  4656. headers: params.Headers,
  4657. action: 'website'
  4658. }, function (err, data) {
  4659. if (err) {
  4660. if (err.statusCode === 404 && err.error.Code === 'NoSuchWebsiteConfiguration') {
  4661. var result = {
  4662. WebsiteConfiguration: {},
  4663. statusCode: err.statusCode
  4664. };
  4665. err.headers && (result.headers = err.headers);
  4666. callback(null, result);
  4667. } else {
  4668. callback(err);
  4669. }
  4670. return;
  4671. }
  4672. var WebsiteConfiguration = data.WebsiteConfiguration || {};
  4673. if (WebsiteConfiguration['RoutingRules']) {
  4674. var RoutingRules = util.clone(WebsiteConfiguration['RoutingRules'].RoutingRule || []);
  4675. RoutingRules = util.makeArray(RoutingRules);
  4676. WebsiteConfiguration.RoutingRules = RoutingRules;
  4677. }
  4678. callback(null, {
  4679. WebsiteConfiguration: WebsiteConfiguration,
  4680. statusCode: data.statusCode,
  4681. headers: data.headers
  4682. });
  4683. });
  4684. }
  4685. /**
  4686. * 删除 Bucket 的静态网站配置
  4687. * @param {Object} params 参数对象,必须
  4688. * @param {String} params.Bucket Bucket名称,必须
  4689. * @param {String} params.Region 地域名称,必须
  4690. * @param {Function} callback 回调函数,必须
  4691. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4692. * @return {Object} data 返回数据
  4693. */
  4694. function deleteBucketWebsite(params, callback) {
  4695. submitRequest.call(this, {
  4696. Action: 'name/cos:DeleteBucketWebsite',
  4697. method: 'DELETE',
  4698. Bucket: params.Bucket,
  4699. Region: params.Region,
  4700. headers: params.Headers,
  4701. action: 'website'
  4702. }, function (err, data) {
  4703. if (err && err.statusCode === 204) {
  4704. return callback(null, { statusCode: err.statusCode });
  4705. } else if (err) {
  4706. return callback(err);
  4707. }
  4708. callback(null, {
  4709. statusCode: data.statusCode,
  4710. headers: data.headers
  4711. });
  4712. });
  4713. }
  4714. // Object 相关
  4715. /**
  4716. * 取回对应Object的元数据,Head的权限与Get的权限一致
  4717. * @param {Object} params 参数对象,必须
  4718. * @param {String} params.Bucket Bucket名称,必须
  4719. * @param {String} params.Region 地域名称,必须
  4720. * @param {String} params.Key 文件名称,必须
  4721. * @param {String} params.IfModifiedSince 当Object在指定时间后被修改,则返回对应Object元信息,否则返回304,非必须
  4722. * @param {Function} callback 回调函数,必须
  4723. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4724. * @return {Object} data 为指定 object 的元数据,如果设置了 IfModifiedSince ,且文件未修改,则返回一个对象,NotModified 属性为 true
  4725. * @return {Boolean} data.NotModified 是否在 IfModifiedSince 时间点之后未修改该 object,则为 true
  4726. */
  4727. function headObject(params, callback) {
  4728. submitRequest.call(this, {
  4729. Action: 'name/cos:HeadObject',
  4730. method: 'HEAD',
  4731. Bucket: params.Bucket,
  4732. Region: params.Region,
  4733. Key: params.Key,
  4734. VersionId: params.VersionId,
  4735. headers: params.Headers
  4736. }, function (err, data) {
  4737. if (err) {
  4738. var statusCode = err.statusCode;
  4739. if (params.Headers['If-Modified-Since'] && statusCode && statusCode === 304) {
  4740. return callback(null, {
  4741. NotModified: true,
  4742. statusCode: statusCode
  4743. });
  4744. }
  4745. return callback(err);
  4746. }
  4747. if (data.headers && data.headers.etag) {
  4748. data.ETag = data.headers && data.headers.etag;
  4749. }
  4750. callback(null, data);
  4751. });
  4752. }
  4753. function listObjectVersions(params, callback) {
  4754. var reqParams = {};
  4755. reqParams['prefix'] = params['Prefix'] || '';
  4756. reqParams['delimiter'] = params['Delimiter'];
  4757. reqParams['key-marker'] = params['KeyMarker'];
  4758. reqParams['version-id-marker'] = params['VersionIdMarker'];
  4759. reqParams['max-keys'] = params['MaxKeys'];
  4760. reqParams['encoding-type'] = params['EncodingType'];
  4761. submitRequest.call(this, {
  4762. Action: 'name/cos:GetBucketObjectVersions',
  4763. ResourceKey: reqParams['prefix'],
  4764. method: 'GET',
  4765. Bucket: params.Bucket,
  4766. Region: params.Region,
  4767. headers: params.Headers,
  4768. qs: reqParams,
  4769. action: 'versions'
  4770. }, function (err, data) {
  4771. if (err) {
  4772. return callback(err);
  4773. }
  4774. var ListVersionsResult = data.ListVersionsResult || {};
  4775. var DeleteMarkers = ListVersionsResult.DeleteMarker || [];
  4776. DeleteMarkers = util.isArray(DeleteMarkers) ? DeleteMarkers : [DeleteMarkers];
  4777. var Versions = ListVersionsResult.Version || [];
  4778. Versions = util.isArray(Versions) ? Versions : [Versions];
  4779. var result = util.clone(ListVersionsResult);
  4780. delete result.DeleteMarker;
  4781. delete result.Version;
  4782. util.extend(result, {
  4783. DeleteMarkers: DeleteMarkers,
  4784. Versions: Versions,
  4785. statusCode: data.statusCode,
  4786. headers: data.headers
  4787. });
  4788. callback(null, result);
  4789. });
  4790. }
  4791. /**
  4792. * 下载 object
  4793. * @param {Object} params 参数对象,必须
  4794. * @param {String} params.Bucket Bucket名称,必须
  4795. * @param {String} params.Region 地域名称,必须
  4796. * @param {String} params.Key 文件名称,必须
  4797. * @param {WriteStream} params.Output 文件写入流,非必须
  4798. * @param {String} params.IfModifiedSince 当Object在指定时间后被修改,则返回对应Object元信息,否则返回304,非必须
  4799. * @param {String} params.IfUnmodifiedSince 如果文件修改时间早于或等于指定时间,才返回文件内容。否则返回 412 (precondition failed),非必须
  4800. * @param {String} params.IfMatch 当 ETag 与指定的内容一致,才返回文件。否则返回 412 (precondition failed),非必须
  4801. * @param {String} params.IfNoneMatch 当 ETag 与指定的内容不一致,才返回文件。否则返回304 (not modified),非必须
  4802. * @param {String} params.ResponseContentType 设置返回头部中的 Content-Type 参数,非必须
  4803. * @param {String} params.ResponseContentLanguage 设置返回头部中的 Content-Language 参数,非必须
  4804. * @param {String} params.ResponseExpires 设置返回头部中的 Content-Expires 参数,非必须
  4805. * @param {String} params.ResponseCacheControl 设置返回头部中的 Cache-Control 参数,非必须
  4806. * @param {String} params.ResponseContentDisposition 设置返回头部中的 Content-Disposition 参数,非必须
  4807. * @param {String} params.ResponseContentEncoding 设置返回头部中的 Content-Encoding 参数,非必须
  4808. * @param {Function} callback 回调函数,必须
  4809. * @param {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4810. * @param {Object} data 为对应的 object 数据,包括 body 和 headers
  4811. */
  4812. function getObject(params, callback) {
  4813. var reqParams = {};
  4814. reqParams['response-content-type'] = params['ResponseContentType'];
  4815. reqParams['response-content-language'] = params['ResponseContentLanguage'];
  4816. reqParams['response-expires'] = params['ResponseExpires'];
  4817. reqParams['response-cache-control'] = params['ResponseCacheControl'];
  4818. reqParams['response-content-disposition'] = params['ResponseContentDisposition'];
  4819. reqParams['response-content-encoding'] = params['ResponseContentEncoding'];
  4820. // 如果用户自己传入了 output
  4821. submitRequest.call(this, {
  4822. Action: 'name/cos:GetObject',
  4823. method: 'GET',
  4824. Bucket: params.Bucket,
  4825. Region: params.Region,
  4826. Key: params.Key,
  4827. VersionId: params.VersionId,
  4828. headers: params.Headers,
  4829. qs: reqParams,
  4830. rawBody: true
  4831. }, function (err, data) {
  4832. if (err) {
  4833. var statusCode = err.statusCode;
  4834. if (params.Headers['If-Modified-Since'] && statusCode && statusCode === 304) {
  4835. return callback(null, {
  4836. NotModified: true
  4837. });
  4838. }
  4839. return callback(err);
  4840. }
  4841. var result = {};
  4842. result.Body = data.body;
  4843. if (data.headers && data.headers.etag) {
  4844. result.ETag = data.headers && data.headers.etag;
  4845. }
  4846. util.extend(result, {
  4847. statusCode: data.statusCode,
  4848. headers: data.headers
  4849. });
  4850. callback(null, result);
  4851. });
  4852. }
  4853. /**
  4854. * 上传 object
  4855. * @param {Object} params 参数对象,必须
  4856. * @param {String} params.Bucket Bucket名称,必须
  4857. * @param {String} params.Region 地域名称,必须
  4858. * @param {String} params.Key 文件名称,必须
  4859. * @param {File || Blob || String} params.Body 上传文件对象或字符串,必须
  4860. * @param {String} params.CacheControl RFC 2616 中定义的缓存策略,将作为 Object 元数据保存,非必须
  4861. * @param {String} params.ContentDisposition RFC 2616 中定义的文件名称,将作为 Object 元数据保存,非必须
  4862. * @param {String} params.ContentEncoding RFC 2616 中定义的编码格式,将作为 Object 元数据保存,非必须
  4863. * @param {String} params.ContentLength RFC 2616 中定义的 HTTP 请求内容长度(字节),必须
  4864. * @param {String} params.ContentType RFC 2616 中定义的内容类型(MIME),将作为 Object 元数据保存,非必须
  4865. * @param {String} params.Expect 当使用 Expect: 100-continue 时,在收到服务端确认后,才会发送请求内容,非必须
  4866. * @param {String} params.Expires RFC 2616 中定义的过期时间,将作为 Object 元数据保存,非必须
  4867. * @param {String} params.ACL 允许用户自定义文件权限,有效值:private | public-read,非必须
  4868. * @param {String} params.GrantRead 赋予被授权者读取对象的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
  4869. * @param {String} params.GrantReadAcp 赋予被授权者读取对象的访问控制列表(ACL)的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
  4870. * @param {String} params.GrantWriteAcp 赋予被授权者写入对象的访问控制列表(ACL)的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
  4871. * @param {String} params.GrantFullControl 赋予被授权者操作对象的所有权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
  4872. * @param {String} params.StorageClass 设置对象的存储级别,枚举值:STANDARD、STANDARD_IA、ARCHIVE,默认值:STANDARD,非必须
  4873. * @param {String} params.x-cos-meta-* 允许用户自定义的头部信息,将作为对象的元数据保存。大小限制2KB,非必须
  4874. * @param {String} params.ContentSha1 RFC 3174 中定义的 160-bit 内容 SHA-1 算法校验,非必须
  4875. * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须
  4876. * @param {Function} params.onProgress 上传进度回调函数
  4877. * @param {Function} callback 回调函数,必须
  4878. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4879. * @return {Object} data 为对应的 object 数据
  4880. * @return {String} data.ETag 为对应上传文件的 ETag 值
  4881. */
  4882. function putObject(params, callback) {
  4883. var self = this;
  4884. var FileSize = params.ContentLength;
  4885. var onProgress = util.throttleOnProgress.call(self, FileSize, params.onProgress);
  4886. // 特殊处理 Cache-Control
  4887. var headers = params.Headers;
  4888. !headers['Cache-Control'] && (headers['Cache-Control'] = '');
  4889. // 获取 File 或 Blob 的 type 属性,如果有,作为文件 Content-Type
  4890. var ContentType = headers['Content-Type'] || params.Body && params.Body.type;
  4891. !headers['Content-Type'] && ContentType && (headers['Content-Type'] = ContentType);
  4892. var needCalcMd5 = params.UploadAddMetaMd5 || self.options.UploadAddMetaMd5 || self.options.UploadCheckContentMd5;
  4893. util.getBodyMd5(needCalcMd5, params.Body, function (md5) {
  4894. if (md5) {
  4895. if (self.options.UploadCheckContentMd5) params.Headers['Content-MD5'] = util.binaryBase64(md5);
  4896. if (params.UploadAddMetaMd5 || self.options.UploadAddMetaMd5) params.Headers['x-cos-meta-md5'] = md5;
  4897. }
  4898. if (params.ContentLength !== undefined) {
  4899. params.Headers['Content-Length'] = params.ContentLength;
  4900. }
  4901. onProgress(null, true); // 任务状态开始 uploading
  4902. submitRequest.call(self, {
  4903. Action: 'name/cos:PutObject',
  4904. TaskId: params.TaskId,
  4905. method: 'PUT',
  4906. Bucket: params.Bucket,
  4907. Region: params.Region,
  4908. Key: params.Key,
  4909. headers: params.Headers,
  4910. body: params.Body,
  4911. onProgress: onProgress
  4912. }, function (err, data) {
  4913. if (err) {
  4914. onProgress(null, true);
  4915. return callback(err);
  4916. }
  4917. onProgress({ loaded: FileSize, total: FileSize }, true);
  4918. if (data) {
  4919. var url = getUrl({
  4920. ForcePathStyle: self.options.ForcePathStyle,
  4921. protocol: self.options.Protocol,
  4922. domain: self.options.Domain,
  4923. bucket: params.Bucket,
  4924. region: params.Region,
  4925. object: params.Key
  4926. });
  4927. url = url.substr(url.indexOf('://') + 3);
  4928. var result = {
  4929. Location: url,
  4930. statusCode: data.statusCode,
  4931. headers: data.headers
  4932. };
  4933. if (data.headers && data.headers.etag) {
  4934. result.ETag = data.headers.etag;
  4935. }
  4936. return callback(null, result);
  4937. }
  4938. callback(null, data);
  4939. });
  4940. }, params.onHashProgress);
  4941. }
  4942. /**
  4943. * 删除 object
  4944. * @param {Object} params 参数对象,必须
  4945. * @param {String} params.Bucket Bucket名称,必须
  4946. * @param {String} params.Region 地域名称,必须
  4947. * @param {String} params.Key object名称,必须
  4948. * @param {Function} callback 回调函数,必须
  4949. * @param {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4950. * @param {Object} data 删除操作成功之后返回的数据
  4951. */
  4952. function deleteObject(params, callback) {
  4953. submitRequest.call(this, {
  4954. Action: 'name/cos:DeleteObject',
  4955. method: 'DELETE',
  4956. Bucket: params.Bucket,
  4957. Region: params.Region,
  4958. Key: params.Key,
  4959. headers: params.Headers,
  4960. VersionId: params.VersionId
  4961. }, function (err, data) {
  4962. if (err) {
  4963. var statusCode = err.statusCode;
  4964. if (statusCode && statusCode === 204) {
  4965. return callback(null, { statusCode: statusCode });
  4966. } else if (statusCode && statusCode === 404) {
  4967. return callback(null, { BucketNotFound: true, statusCode: statusCode });
  4968. } else {
  4969. return callback(err);
  4970. }
  4971. }
  4972. callback(null, {
  4973. statusCode: data.statusCode,
  4974. headers: data.headers
  4975. });
  4976. });
  4977. }
  4978. /**
  4979. * 获取 object 的 权限列表
  4980. * @param {Object} params 参数对象,必须
  4981. * @param {String} params.Bucket Bucket名称,必须
  4982. * @param {String} params.Region 地域名称,必须
  4983. * @param {String} params.Key object名称,必须
  4984. * @param {Function} callback 回调函数,必须
  4985. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  4986. * @return {Object} data 返回的数据
  4987. * @return {Object} data.AccessControlPolicy 权限列表
  4988. */
  4989. function getObjectAcl(params, callback) {
  4990. submitRequest.call(this, {
  4991. Action: 'name/cos:GetObjectACL',
  4992. method: 'GET',
  4993. Bucket: params.Bucket,
  4994. Region: params.Region,
  4995. Key: params.Key,
  4996. headers: params.Headers,
  4997. action: 'acl'
  4998. }, function (err, data) {
  4999. if (err) {
  5000. return callback(err);
  5001. }
  5002. var AccessControlPolicy = data.AccessControlPolicy || {};
  5003. var Owner = AccessControlPolicy.Owner || {};
  5004. var Grant = AccessControlPolicy.AccessControlList && AccessControlPolicy.AccessControlList.Grant || [];
  5005. Grant = util.isArray(Grant) ? Grant : [Grant];
  5006. var result = decodeAcl(AccessControlPolicy);
  5007. if (data.headers && data.headers['x-cos-acl']) {
  5008. result.ACL = data.headers['x-cos-acl'];
  5009. }
  5010. result = util.extend(result, {
  5011. Owner: Owner,
  5012. Grants: Grant,
  5013. statusCode: data.statusCode,
  5014. headers: data.headers
  5015. });
  5016. callback(null, result);
  5017. });
  5018. }
  5019. /**
  5020. * 设置 object 的 权限列表
  5021. * @param {Object} params 参数对象,必须
  5022. * @param {String} params.Bucket Bucket名称,必须
  5023. * @param {String} params.Region 地域名称,必须
  5024. * @param {String} params.Key object名称,必须
  5025. * @param {Function} callback 回调函数,必须
  5026. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5027. * @return {Object} data 返回的数据
  5028. */
  5029. function putObjectAcl(params, callback) {
  5030. var headers = params.Headers;
  5031. var xml = '';
  5032. if (params['AccessControlPolicy']) {
  5033. var AccessControlPolicy = util.clone(params['AccessControlPolicy'] || {});
  5034. var Grants = AccessControlPolicy.Grants || AccessControlPolicy.Grant;
  5035. Grants = util.isArray(Grants) ? Grants : [Grants];
  5036. delete AccessControlPolicy.Grant;
  5037. delete AccessControlPolicy.Grants;
  5038. AccessControlPolicy.AccessControlList = { Grant: Grants };
  5039. xml = util.json2xml({ AccessControlPolicy: AccessControlPolicy });
  5040. headers['Content-Type'] = 'application/xml';
  5041. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  5042. }
  5043. // Grant Header 去重
  5044. util.each(headers, function (val, key) {
  5045. if (key.indexOf('x-cos-grant-') === 0) {
  5046. headers[key] = uniqGrant(headers[key]);
  5047. }
  5048. });
  5049. submitRequest.call(this, {
  5050. Action: 'name/cos:PutObjectACL',
  5051. method: 'PUT',
  5052. Bucket: params.Bucket,
  5053. Region: params.Region,
  5054. Key: params.Key,
  5055. action: 'acl',
  5056. headers: headers,
  5057. body: xml
  5058. }, function (err, data) {
  5059. if (err) {
  5060. return callback(err);
  5061. }
  5062. callback(null, {
  5063. statusCode: data.statusCode,
  5064. headers: data.headers
  5065. });
  5066. });
  5067. }
  5068. /**
  5069. * Options Object请求实现跨域访问的预请求。即发出一个 OPTIONS 请求给服务器以确认是否可以进行跨域操作。
  5070. * @param {Object} params 参数对象,必须
  5071. * @param {String} params.Bucket Bucket名称,必须
  5072. * @param {String} params.Region 地域名称,必须
  5073. * @param {String} params.Key object名称,必须
  5074. * @param {Function} callback 回调函数,必须
  5075. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5076. * @return {Object} data 返回的数据
  5077. */
  5078. function optionsObject(params, callback) {
  5079. var headers = params.Headers;
  5080. headers['Origin'] = params['Origin'];
  5081. headers['Access-Control-Request-Method'] = params['AccessControlRequestMethod'];
  5082. headers['Access-Control-Request-Headers'] = params['AccessControlRequestHeaders'];
  5083. submitRequest.call(this, {
  5084. Action: 'name/cos:OptionsObject',
  5085. method: 'OPTIONS',
  5086. Bucket: params.Bucket,
  5087. Region: params.Region,
  5088. Key: params.Key,
  5089. headers: headers
  5090. }, function (err, data) {
  5091. if (err) {
  5092. if (err.statusCode && err.statusCode === 403) {
  5093. return callback(null, {
  5094. OptionsForbidden: true,
  5095. statusCode: err.statusCode
  5096. });
  5097. }
  5098. return callback(err);
  5099. }
  5100. var headers = data.headers || {};
  5101. callback(null, {
  5102. AccessControlAllowOrigin: headers['access-control-allow-origin'],
  5103. AccessControlAllowMethods: headers['access-control-allow-methods'],
  5104. AccessControlAllowHeaders: headers['access-control-allow-headers'],
  5105. AccessControlExposeHeaders: headers['access-control-expose-headers'],
  5106. AccessControlMaxAge: headers['access-control-max-age'],
  5107. statusCode: data.statusCode,
  5108. headers: data.headers
  5109. });
  5110. });
  5111. }
  5112. /**
  5113. * @param {Object} 参数列表
  5114. * @param {String} Bucket Bucket 名称
  5115. * @param {String} Region 地域名称
  5116. * @param {String} Key 文件名称
  5117. * @param {String} CopySource 源文件URL绝对路径,可以通过versionid子资源指定历史版本
  5118. * @param {String} ACL 允许用户自定义文件权限。有效值:private,public-read默认值:private。
  5119. * @param {String} GrantRead 赋予被授权者读的权限,格式 x-cos-grant-read: uin=" ",uin=" ",当需要给子账户授权时,uin="RootAcountID/SubAccountID",当需要给根账户授权时,uin="RootAcountID"。
  5120. * @param {String} GrantWrite 赋予被授权者写的权限,格式 x-cos-grant-write: uin=" ",uin=" ",当需要给子账户授权时,uin="RootAcountID/SubAccountID",当需要给根账户授权时,uin="RootAcountID"。
  5121. * @param {String} GrantFullControl 赋予被授权者读写权限,格式 x-cos-grant-full-control: uin=" ",uin=" ",当需要给子账户授权时,uin="RootAcountID/SubAccountID",当需要给根账户授权时,uin="RootAcountID"。
  5122. * @param {String} MetadataDirective 是否拷贝元数据,枚举值:Copy, Replaced,默认值Copy。假如标记为Copy,忽略Header中的用户元数据信息直接复制;假如标记为Replaced,按Header信息修改元数据。当目标路径和原路径一致,即用户试图修改元数据时,必须为Replaced
  5123. * @param {String} CopySourceIfModifiedSince 当Object在指定时间后被修改,则执行操作,否则返回412。可与x-cos-copy-source-If-None-Match一起使用,与其他条件联合使用返回冲突。
  5124. * @param {String} CopySourceIfUnmodifiedSince 当Object在指定时间后未被修改,则执行操作,否则返回412。可与x-cos-copy-source-If-Match一起使用,与其他条件联合使用返回冲突。
  5125. * @param {String} CopySourceIfMatch 当Object的Etag和给定一致时,则执行操作,否则返回412。可与x-cos-copy-source-If-Unmodified-Since一起使用,与其他条件联合使用返回冲突。
  5126. * @param {String} CopySourceIfNoneMatch 当Object的Etag和给定不一致时,则执行操作,否则返回412。可与x-cos-copy-source-If-Modified-Since一起使用,与其他条件联合使用返回冲突。
  5127. * @param {String} StorageClass 存储级别,枚举值:存储级别,枚举值:Standard, Standard_IA,Archive;默认值:Standard
  5128. * @param {String} CacheControl 指定所有缓存机制在整个请求/响应链中必须服从的指令。
  5129. * @param {String} ContentDisposition MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件
  5130. * @param {String} ContentEncoding HTTP 中用来对「采用何种编码格式传输正文」进行协定的一对头部字段
  5131. * @param {String} ContentLength 设置响应消息的实体内容的大小,单位为字节
  5132. * @param {String} ContentType RFC 2616 中定义的 HTTP 请求内容类型(MIME),例如text/plain
  5133. * @param {String} Expect 请求的特定的服务器行为
  5134. * @param {String} Expires 响应过期的日期和时间
  5135. * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须
  5136. * @param {String} ContentLanguage 指定内容语言
  5137. * @param {String} x-cos-meta-* 允许用户自定义的头部信息,将作为 Object 元数据返回。大小限制2K。
  5138. */
  5139. function putObjectCopy(params, callback) {
  5140. // 特殊处理 Cache-Control
  5141. var headers = params.Headers;
  5142. !headers['Cache-Control'] && (headers['Cache-Control'] = '');
  5143. var CopySource = params.CopySource || '';
  5144. var m = CopySource.match(/^([^.]+-\d+)\.cos(v6)?\.([^.]+)\.[^/]+\/(.+)$/);
  5145. if (!m) {
  5146. callback({ error: 'CopySource format error' });
  5147. return;
  5148. }
  5149. var SourceBucket = m[1];
  5150. var SourceRegion = m[3];
  5151. var SourceKey = decodeURIComponent(m[4]);
  5152. submitRequest.call(this, {
  5153. Scope: [{
  5154. action: 'name/cos:GetObject',
  5155. bucket: SourceBucket,
  5156. region: SourceRegion,
  5157. prefix: SourceKey
  5158. }, {
  5159. action: 'name/cos:PutObject',
  5160. bucket: params.Bucket,
  5161. region: params.Region,
  5162. prefix: params.Key
  5163. }],
  5164. method: 'PUT',
  5165. Bucket: params.Bucket,
  5166. Region: params.Region,
  5167. Key: params.Key,
  5168. VersionId: params.VersionId,
  5169. headers: params.Headers
  5170. }, function (err, data) {
  5171. if (err) {
  5172. return callback(err);
  5173. }
  5174. var result = util.clone(data.CopyObjectResult || {});
  5175. util.extend(result, {
  5176. statusCode: data.statusCode,
  5177. headers: data.headers
  5178. });
  5179. callback(null, result);
  5180. });
  5181. }
  5182. function uploadPartCopy(params, callback) {
  5183. var CopySource = params.CopySource || '';
  5184. var m = CopySource.match(/^([^.]+-\d+)\.cos(v6)?\.([^.]+)\.[^/]+\/(.+)$/);
  5185. if (!m) {
  5186. callback({ error: 'CopySource format error' });
  5187. return;
  5188. }
  5189. var SourceBucket = m[1];
  5190. var SourceRegion = m[3];
  5191. var SourceKey = decodeURIComponent(m[4]);
  5192. submitRequest.call(this, {
  5193. Scope: [{
  5194. action: 'name/cos:GetObject',
  5195. bucket: SourceBucket,
  5196. region: SourceRegion,
  5197. prefix: SourceKey
  5198. }, {
  5199. action: 'name/cos:PutObject',
  5200. bucket: params.Bucket,
  5201. region: params.Region,
  5202. prefix: params.Key
  5203. }],
  5204. method: 'PUT',
  5205. Bucket: params.Bucket,
  5206. Region: params.Region,
  5207. Key: params.Key,
  5208. VersionId: params.VersionId,
  5209. qs: {
  5210. partNumber: params['PartNumber'],
  5211. uploadId: params['UploadId']
  5212. },
  5213. headers: params.Headers
  5214. }, function (err, data) {
  5215. if (err) {
  5216. return callback(err);
  5217. }
  5218. var result = util.clone(data.CopyPartResult || {});
  5219. util.extend(result, {
  5220. statusCode: data.statusCode,
  5221. headers: data.headers
  5222. });
  5223. callback(null, result);
  5224. });
  5225. }
  5226. function deleteMultipleObject(params, callback) {
  5227. var Objects = params.Objects || [];
  5228. var Quiet = params.Quiet;
  5229. Objects = util.isArray(Objects) ? Objects : [Objects];
  5230. var xml = util.json2xml({ Delete: { Object: Objects, Quiet: Quiet || false } });
  5231. var headers = params.Headers;
  5232. headers['Content-Type'] = 'application/xml';
  5233. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  5234. var Scope = util.map(Objects, function (v) {
  5235. return {
  5236. action: 'name/cos:DeleteObject',
  5237. bucket: params.Bucket,
  5238. region: params.Region,
  5239. prefix: v.Key
  5240. };
  5241. });
  5242. submitRequest.call(this, {
  5243. Scope: Scope,
  5244. method: 'POST',
  5245. Bucket: params.Bucket,
  5246. Region: params.Region,
  5247. body: xml,
  5248. action: 'delete',
  5249. headers: headers
  5250. }, function (err, data) {
  5251. if (err) {
  5252. return callback(err);
  5253. }
  5254. var DeleteResult = data.DeleteResult || {};
  5255. var Deleted = DeleteResult.Deleted || [];
  5256. var Errors = DeleteResult.Error || [];
  5257. Deleted = util.isArray(Deleted) ? Deleted : [Deleted];
  5258. Errors = util.isArray(Errors) ? Errors : [Errors];
  5259. var result = util.clone(DeleteResult);
  5260. util.extend(result, {
  5261. Error: Errors,
  5262. Deleted: Deleted,
  5263. statusCode: data.statusCode,
  5264. headers: data.headers
  5265. });
  5266. callback(null, result);
  5267. });
  5268. }
  5269. function restoreObject(params, callback) {
  5270. var headers = params.Headers;
  5271. if (!params['RestoreRequest']) {
  5272. callback({ error: 'missing param RestoreRequest' });
  5273. return;
  5274. }
  5275. var RestoreRequest = params.RestoreRequest || {};
  5276. var xml = util.json2xml({ RestoreRequest: RestoreRequest });
  5277. headers['Content-Type'] = 'application/xml';
  5278. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  5279. submitRequest.call(this, {
  5280. Action: 'name/cos:RestoreObject',
  5281. method: 'POST',
  5282. Bucket: params.Bucket,
  5283. Region: params.Region,
  5284. Key: params.Key,
  5285. VersionId: params.VersionId,
  5286. body: xml,
  5287. action: 'restore',
  5288. headers: headers
  5289. }, function (err, data) {
  5290. callback(err, data);
  5291. });
  5292. }
  5293. // 分块上传
  5294. /**
  5295. * 初始化分块上传
  5296. * @param {Object} params 参数对象,必须
  5297. * @param {String} params.Bucket Bucket名称,必须
  5298. * @param {String} params.Region 地域名称,必须
  5299. * @param {String} params.Key object名称,必须
  5300. * @param {String} params.UploadId object名称,必须
  5301. * @param {String} params.CacheControl RFC 2616 中定义的缓存策略,将作为 Object 元数据保存,非必须
  5302. * @param {String} params.ContentDisposition RFC 2616 中定义的文件名称,将作为 Object 元数据保存 ,非必须
  5303. * @param {String} params.ContentEncoding RFC 2616 中定义的编码格式,将作为 Object 元数据保存,非必须
  5304. * @param {String} params.ContentType RFC 2616 中定义的内容类型(MIME),将作为 Object 元数据保存,非必须
  5305. * @param {String} params.Expires RFC 2616 中定义的过期时间,将作为 Object 元数据保存,非必须
  5306. * @param {String} params.ACL 允许用户自定义文件权限,非必须
  5307. * @param {String} params.GrantRead 赋予被授权者读的权限 ,非必须
  5308. * @param {String} params.GrantWrite 赋予被授权者写的权限 ,非必须
  5309. * @param {String} params.GrantFullControl 赋予被授权者读写权限 ,非必须
  5310. * @param {String} params.StorageClass 设置Object的存储级别,枚举值:Standard,Standard_IA,Archive,非必须
  5311. * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须
  5312. * @param {Function} callback 回调函数,必须
  5313. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5314. * @return {Object} data 返回的数据
  5315. */
  5316. function multipartInit(params, callback) {
  5317. var self = this;
  5318. // 特殊处理 Cache-Control
  5319. var headers = params.Headers;
  5320. !headers['Cache-Control'] && (headers['Cache-Control'] = '');
  5321. util.getBodyMd5(params.Body && (params.UploadAddMetaMd5 || self.options.UploadAddMetaMd5), params.Body, function (md5) {
  5322. if (md5) params.Headers['x-cos-meta-md5'] = md5;
  5323. submitRequest.call(self, {
  5324. Action: 'name/cos:InitiateMultipartUpload',
  5325. method: 'POST',
  5326. Bucket: params.Bucket,
  5327. Region: params.Region,
  5328. Key: params.Key,
  5329. action: 'uploads',
  5330. headers: params.Headers
  5331. }, function (err, data) {
  5332. if (err) {
  5333. return callback(err);
  5334. }
  5335. data = util.clone(data || {});
  5336. if (data && data.InitiateMultipartUploadResult) {
  5337. return callback(null, util.extend(data.InitiateMultipartUploadResult, {
  5338. statusCode: data.statusCode,
  5339. headers: data.headers
  5340. }));
  5341. }
  5342. callback(null, data);
  5343. });
  5344. }, params.onHashProgress);
  5345. }
  5346. /**
  5347. * 分块上传
  5348. * @param {Object} params 参数对象,必须
  5349. * @param {String} params.Bucket Bucket名称,必须
  5350. * @param {String} params.Region 地域名称,必须
  5351. * @param {String} params.Key object名称,必须
  5352. * @param {File || Blob || String} params.Body 上传文件对象或字符串
  5353. * @param {String} params.ContentLength RFC 2616 中定义的 HTTP 请求内容长度(字节),非必须
  5354. * @param {String} params.Expect 当使用 Expect: 100-continue 时,在收到服务端确认后,才会发送请求内容,非必须
  5355. * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须
  5356. * @param {String} params.ContentSha1 RFC 3174 中定义的 160-bit 内容 SHA-1 算法校验值,非必须
  5357. * @param {Function} callback 回调函数,必须
  5358. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5359. * @return {Object} data 返回的数据
  5360. * @return {Object} data.ETag 返回的文件分块 sha1 值
  5361. */
  5362. function multipartUpload(params, callback) {
  5363. var self = this;
  5364. util.getFileSize('multipartUpload', params, function () {
  5365. util.getBodyMd5(self.options.UploadCheckContentMd5, params.Body, function (md5) {
  5366. if (md5) params.Headers['Content-MD5'] = util.binaryBase64(md5);
  5367. submitRequest.call(self, {
  5368. Action: 'name/cos:UploadPart',
  5369. TaskId: params.TaskId,
  5370. method: 'PUT',
  5371. Bucket: params.Bucket,
  5372. Region: params.Region,
  5373. Key: params.Key,
  5374. qs: {
  5375. partNumber: params['PartNumber'],
  5376. uploadId: params['UploadId']
  5377. },
  5378. headers: params.Headers,
  5379. onProgress: params.onProgress,
  5380. body: params.Body || null
  5381. }, function (err, data) {
  5382. if (err) {
  5383. return callback(err);
  5384. }
  5385. data['headers'] = data['headers'] || {};
  5386. callback(null, {
  5387. ETag: data['headers']['etag'] || '',
  5388. statusCode: data.statusCode,
  5389. headers: data.headers
  5390. });
  5391. });
  5392. });
  5393. });
  5394. }
  5395. /**
  5396. * 完成分块上传
  5397. * @param {Object} params 参数对象,必须
  5398. * @param {String} params.Bucket Bucket名称,必须
  5399. * @param {String} params.Region 地域名称,必须
  5400. * @param {String} params.Key object名称,必须
  5401. * @param {Array} params.Parts 分块信息列表,必须
  5402. * @param {String} params.Parts[i].PartNumber 块编号,必须
  5403. * @param {String} params.Parts[i].ETag 分块的 sha1 校验值
  5404. * @param {Function} callback 回调函数,必须
  5405. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5406. * @return {Object} data 返回的数据
  5407. * @return {Object} data.CompleteMultipartUpload 完成分块上传后的文件信息,包括Location, Bucket, Key 和 ETag
  5408. */
  5409. function multipartComplete(params, callback) {
  5410. var self = this;
  5411. var UploadId = params.UploadId;
  5412. var Parts = params['Parts'];
  5413. for (var i = 0, len = Parts.length; i < len; i++) {
  5414. if (Parts[i]['ETag'].indexOf('"') === 0) {
  5415. continue;
  5416. }
  5417. Parts[i]['ETag'] = '"' + Parts[i]['ETag'] + '"';
  5418. }
  5419. var xml = util.json2xml({ CompleteMultipartUpload: { Part: Parts } });
  5420. var headers = params.Headers;
  5421. headers['Content-Type'] = 'application/xml';
  5422. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  5423. submitRequest.call(this, {
  5424. Action: 'name/cos:CompleteMultipartUpload',
  5425. method: 'POST',
  5426. Bucket: params.Bucket,
  5427. Region: params.Region,
  5428. Key: params.Key,
  5429. qs: {
  5430. uploadId: UploadId
  5431. },
  5432. body: xml,
  5433. headers: headers
  5434. }, function (err, data) {
  5435. if (err) {
  5436. return callback(err);
  5437. }
  5438. var url = getUrl({
  5439. ForcePathStyle: self.options.ForcePathStyle,
  5440. protocol: self.options.Protocol,
  5441. domain: self.options.Domain,
  5442. bucket: params.Bucket,
  5443. region: params.Region,
  5444. object: params.Key,
  5445. isLocation: true
  5446. });
  5447. var CompleteMultipartUploadResult = data.CompleteMultipartUploadResult || {};
  5448. var result = util.extend(CompleteMultipartUploadResult, {
  5449. Location: url,
  5450. statusCode: data.statusCode,
  5451. headers: data.headers
  5452. });
  5453. callback(null, result);
  5454. });
  5455. }
  5456. /**
  5457. * 分块上传任务列表查询
  5458. * @param {Object} params 参数对象,必须
  5459. * @param {String} params.Bucket Bucket名称,必须
  5460. * @param {String} params.Region 地域名称,必须
  5461. * @param {String} params.Delimiter 定界符为一个符号,如果有Prefix,则将Prefix到delimiter之间的相同路径归为一类,定义为Common Prefix,然后列出所有Common Prefix。如果没有Prefix,则从路径起点开始,非必须
  5462. * @param {String} params.EncodingType 规定返回值的编码方式,非必须
  5463. * @param {String} params.Prefix 前缀匹配,用来规定返回的文件前缀地址,非必须
  5464. * @param {String} params.MaxUploads 单次返回最大的条目数量,默认1000,非必须
  5465. * @param {String} params.KeyMarker 与upload-id-marker一起使用 </Br>当upload-id-marker未被指定时,ObjectName字母顺序大于key-marker的条目将被列出 </Br>当upload-id-marker被指定时,ObjectName字母顺序大于key-marker的条目被列出,ObjectName字母顺序等于key-marker同时UploadId大于upload-id-marker的条目将被列出,非必须
  5466. * @param {String} params.UploadIdMarker 与key-marker一起使用 </Br>当key-marker未被指定时,upload-id-marker将被忽略 </Br>当key-marker被指定时,ObjectName字母顺序大于key-marker的条目被列出,ObjectName字母顺序等于key-marker同时UploadId大于upload-id-marker的条目将被列出,非必须
  5467. * @param {Function} callback 回调函数,必须
  5468. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5469. * @return {Object} data 返回的数据
  5470. * @return {Object} data.ListMultipartUploadsResult 分块上传任务信息
  5471. */
  5472. function multipartList(params, callback) {
  5473. var reqParams = {};
  5474. reqParams['delimiter'] = params['Delimiter'];
  5475. reqParams['encoding-type'] = params['EncodingType'];
  5476. reqParams['prefix'] = params['Prefix'] || '';
  5477. reqParams['max-uploads'] = params['MaxUploads'];
  5478. reqParams['key-marker'] = params['KeyMarker'];
  5479. reqParams['upload-id-marker'] = params['UploadIdMarker'];
  5480. reqParams = util.clearKey(reqParams);
  5481. submitRequest.call(this, {
  5482. Action: 'name/cos:ListMultipartUploads',
  5483. ResourceKey: reqParams['prefix'],
  5484. method: 'GET',
  5485. Bucket: params.Bucket,
  5486. Region: params.Region,
  5487. headers: params.Headers,
  5488. qs: reqParams,
  5489. action: 'uploads'
  5490. }, function (err, data) {
  5491. if (err) {
  5492. return callback(err);
  5493. }
  5494. if (data && data.ListMultipartUploadsResult) {
  5495. var Upload = data.ListMultipartUploadsResult.Upload || [];
  5496. var CommonPrefixes = data.ListMultipartUploadsResult.CommonPrefixes || [];
  5497. CommonPrefixes = util.isArray(CommonPrefixes) ? CommonPrefixes : [CommonPrefixes];
  5498. Upload = util.isArray(Upload) ? Upload : [Upload];
  5499. data.ListMultipartUploadsResult.Upload = Upload;
  5500. data.ListMultipartUploadsResult.CommonPrefixes = CommonPrefixes;
  5501. }
  5502. var result = util.clone(data.ListMultipartUploadsResult || {});
  5503. util.extend(result, {
  5504. statusCode: data.statusCode,
  5505. headers: data.headers
  5506. });
  5507. callback(null, result);
  5508. });
  5509. }
  5510. /**
  5511. * 上传的分块列表查询
  5512. * @param {Object} params 参数对象,必须
  5513. * @param {String} params.Bucket Bucket名称,必须
  5514. * @param {String} params.Region 地域名称,必须
  5515. * @param {String} params.Key object名称,必须
  5516. * @param {String} params.UploadId 标示本次分块上传的ID,必须
  5517. * @param {String} params.EncodingType 规定返回值的编码方式,非必须
  5518. * @param {String} params.MaxParts 单次返回最大的条目数量,默认1000,非必须
  5519. * @param {String} params.PartNumberMarker 默认以UTF-8二进制顺序列出条目,所有列出条目从marker开始,非必须
  5520. * @param {Function} callback 回调函数,必须
  5521. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5522. * @return {Object} data 返回的数据
  5523. * @return {Object} data.ListMultipartUploadsResult 分块信息
  5524. */
  5525. function multipartListPart(params, callback) {
  5526. var reqParams = {};
  5527. reqParams['uploadId'] = params['UploadId'];
  5528. reqParams['encoding-type'] = params['EncodingType'];
  5529. reqParams['max-parts'] = params['MaxParts'];
  5530. reqParams['part-number-marker'] = params['PartNumberMarker'];
  5531. submitRequest.call(this, {
  5532. Action: 'name/cos:ListParts',
  5533. method: 'GET',
  5534. Bucket: params.Bucket,
  5535. Region: params.Region,
  5536. Key: params.Key,
  5537. headers: params.Headers,
  5538. qs: reqParams
  5539. }, function (err, data) {
  5540. if (err) {
  5541. return callback(err);
  5542. }
  5543. var ListPartsResult = data.ListPartsResult || {};
  5544. var Part = ListPartsResult.Part || [];
  5545. Part = util.isArray(Part) ? Part : [Part];
  5546. ListPartsResult.Part = Part;
  5547. var result = util.clone(ListPartsResult);
  5548. util.extend(result, {
  5549. statusCode: data.statusCode,
  5550. headers: data.headers
  5551. });
  5552. callback(null, result);
  5553. });
  5554. }
  5555. /**
  5556. * 抛弃分块上传
  5557. * @param {Object} params 参数对象,必须
  5558. * @param {String} params.Bucket Bucket名称,必须
  5559. * @param {String} params.Region 地域名称,必须
  5560. * @param {String} params.Key object名称,必须
  5561. * @param {String} params.UploadId 标示本次分块上传的ID,必须
  5562. * @param {Function} callback 回调函数,必须
  5563. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5564. * @return {Object} data 返回的数据
  5565. */
  5566. function multipartAbort(params, callback) {
  5567. var reqParams = {};
  5568. reqParams['uploadId'] = params['UploadId'];
  5569. submitRequest.call(this, {
  5570. Action: 'name/cos:AbortMultipartUpload',
  5571. method: 'DELETE',
  5572. Bucket: params.Bucket,
  5573. Region: params.Region,
  5574. Key: params.Key,
  5575. headers: params.Headers,
  5576. qs: reqParams
  5577. }, function (err, data) {
  5578. if (err) {
  5579. return callback(err);
  5580. }
  5581. callback(null, {
  5582. statusCode: data.statusCode,
  5583. headers: data.headers
  5584. });
  5585. });
  5586. }
  5587. /**
  5588. * 获取签名
  5589. * @param {Object} params 参数对象,必须
  5590. * @param {String} params.Method 请求方法,必须
  5591. * @param {String} params.Key object名称,必须
  5592. * @param {String} params.Expires 名超时时间,单位秒,可选
  5593. * @return {String} data 返回签名字符串
  5594. */
  5595. function getAuth(params) {
  5596. var self = this;
  5597. return util.getAuth({
  5598. SecretId: params.SecretId || this.options.SecretId || '',
  5599. SecretKey: params.SecretKey || this.options.SecretKey || '',
  5600. Method: params.Method,
  5601. Key: params.Key,
  5602. Query: params.Query,
  5603. Headers: params.Headers,
  5604. Expires: params.Expires,
  5605. UseRawKey: self.options.UseRawKey,
  5606. SystemClockOffset: self.options.SystemClockOffset
  5607. });
  5608. }
  5609. /**
  5610. * 获取文件下载链接
  5611. * @param {Object} params 参数对象,必须
  5612. * @param {String} params.Bucket Bucket名称,必须
  5613. * @param {String} params.Region 地域名称,必须
  5614. * @param {String} params.Key object名称,必须
  5615. * @param {String} params.Method 请求的方法,可选
  5616. * @param {String} params.Expires 签名超时时间,单位秒,可选
  5617. * @param {Function} callback 回调函数,必须
  5618. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5619. * @return {Object} data 返回的数据
  5620. */
  5621. function getObjectUrl(params, callback) {
  5622. var self = this;
  5623. var url = getUrl({
  5624. ForcePathStyle: self.options.ForcePathStyle,
  5625. protocol: params.Protocol || self.options.Protocol,
  5626. domain: self.options.Domain,
  5627. bucket: params.Bucket,
  5628. region: params.Region,
  5629. object: params.Key
  5630. });
  5631. if (params.Sign !== undefined && !params.Sign) {
  5632. callback(null, { Url: url });
  5633. return url;
  5634. }
  5635. var AuthData = getAuthorizationAsync.call(this, {
  5636. Action: (params.Method || '').toUpperCase() === 'PUT' ? 'name/cos:PutObject' : 'name/cos:GetObject',
  5637. Bucket: params.Bucket || '',
  5638. Region: params.Region || '',
  5639. Method: params.Method || 'get',
  5640. Key: params.Key,
  5641. Expires: params.Expires
  5642. }, function (err, AuthData) {
  5643. if (!callback) return;
  5644. if (err) {
  5645. callback(err);
  5646. return;
  5647. }
  5648. var signUrl = url;
  5649. signUrl += '?' + (AuthData.Authorization.indexOf('q-signature') > -1 ? AuthData.Authorization : 'sign=' + encodeURIComponent(AuthData.Authorization));
  5650. AuthData.XCosSecurityToken && (signUrl += '&x-cos-security-token=' + AuthData.XCosSecurityToken);
  5651. AuthData.ClientIP && (signUrl += '&clientIP=' + AuthData.ClientIP);
  5652. AuthData.ClientUA && (signUrl += '&clientUA=' + AuthData.ClientUA);
  5653. AuthData.Token && (signUrl += '&token=' + AuthData.Token);
  5654. setTimeout(function () {
  5655. callback(null, { Url: signUrl });
  5656. });
  5657. });
  5658. if (AuthData) {
  5659. return url + '?' + AuthData.Authorization + (AuthData.XCosSecurityToken ? '&x-cos-security-token=' + AuthData.XCosSecurityToken : '');
  5660. } else {
  5661. return url;
  5662. }
  5663. }
  5664. /**
  5665. * 私有方法
  5666. */
  5667. function decodeAcl(AccessControlPolicy) {
  5668. var result = {
  5669. GrantFullControl: [],
  5670. GrantWrite: [],
  5671. GrantRead: [],
  5672. GrantReadAcp: [],
  5673. GrantWriteAcp: [],
  5674. ACL: ''
  5675. };
  5676. var GrantMap = {
  5677. 'FULL_CONTROL': 'GrantFullControl',
  5678. 'WRITE': 'GrantWrite',
  5679. 'READ': 'GrantRead',
  5680. 'READ_ACP': 'GrantReadAcp',
  5681. 'WRITE_ACP': 'GrantWriteAcp'
  5682. };
  5683. var AccessControlList = AccessControlPolicy && AccessControlPolicy.AccessControlList || {};
  5684. var Grant = AccessControlList.Grant;
  5685. if (Grant) {
  5686. Grant = util.isArray(Grant) ? Grant : [Grant];
  5687. }
  5688. var PublicAcl = { READ: 0, WRITE: 0, FULL_CONTROL: 0 };
  5689. Grant && Grant.length && util.each(Grant, function (item) {
  5690. if (item.Grantee.ID === 'qcs::cam::anyone:anyone' || item.Grantee.URI === 'http://cam.qcloud.com/groups/global/AllUsers') {
  5691. PublicAcl[item.Permission] = 1;
  5692. } else if (item.Grantee.ID !== AccessControlPolicy.Owner.ID) {
  5693. result[GrantMap[item.Permission]].push('id="' + item.Grantee.ID + '"');
  5694. }
  5695. });
  5696. if (PublicAcl.FULL_CONTROL || PublicAcl.WRITE && PublicAcl.READ) {
  5697. result.ACL = 'public-read-write';
  5698. } else if (PublicAcl.READ) {
  5699. result.ACL = 'public-read';
  5700. } else {
  5701. result.ACL = 'private';
  5702. }
  5703. util.each(GrantMap, function (item) {
  5704. result[item] = uniqGrant(result[item].join(','));
  5705. });
  5706. return result;
  5707. }
  5708. // Grant 去重
  5709. function uniqGrant(str) {
  5710. var arr = str.split(',');
  5711. var exist = {};
  5712. var i, item;
  5713. for (i = 0; i < arr.length;) {
  5714. item = arr[i].trim();
  5715. if (exist[item]) {
  5716. arr.splice(i, 1);
  5717. } else {
  5718. exist[item] = true;
  5719. arr[i] = item;
  5720. i++;
  5721. }
  5722. }
  5723. return arr.join(',');
  5724. }
  5725. // 生成操作 url
  5726. function getUrl(params) {
  5727. var longBucket = params.bucket;
  5728. var shortBucket = longBucket.substr(0, longBucket.lastIndexOf('-'));
  5729. var appId = longBucket.substr(longBucket.lastIndexOf('-') + 1);
  5730. var domain = params.domain;
  5731. var region = params.region;
  5732. var object = params.object;
  5733. var protocol = params.protocol || (util.isBrowser && location.protocol === 'http:' ? 'http:' : 'https:');
  5734. if (!domain) {
  5735. if (['cn-south', 'cn-south-2', 'cn-north', 'cn-east', 'cn-southwest', 'sg'].indexOf(region) > -1) {
  5736. domain = '{Region}.myqcloud.com';
  5737. } else {
  5738. domain = 'cos.{Region}.myqcloud.com';
  5739. }
  5740. if (!params.ForcePathStyle) {
  5741. domain = '{Bucket}.' + domain;
  5742. }
  5743. }
  5744. domain = domain.replace(/\{\{AppId\}\}/ig, appId).replace(/\{\{Bucket\}\}/ig, shortBucket).replace(/\{\{Region\}\}/ig, region).replace(/\{\{.*?\}\}/ig, '');
  5745. domain = domain.replace(/\{AppId\}/ig, appId).replace(/\{BucketName\}/ig, shortBucket).replace(/\{Bucket\}/ig, longBucket).replace(/\{Region\}/ig, region).replace(/\{.*?\}/ig, '');
  5746. if (!/^[a-zA-Z]+:\/\//.test(domain)) {
  5747. domain = protocol + '//' + domain;
  5748. }
  5749. // 去掉域名最后的斜杆
  5750. if (domain.slice(-1) === '/') {
  5751. domain = domain.slice(0, -1);
  5752. }
  5753. var url = domain;
  5754. if (params.ForcePathStyle) {
  5755. url += '/' + longBucket;
  5756. }
  5757. url += '/';
  5758. if (object) {
  5759. url += util.camSafeUrlEncode(object).replace(/%2F/g, '/');
  5760. }
  5761. if (params.isLocation) {
  5762. url = url.replace(/^https?:\/\//, '');
  5763. }
  5764. return url;
  5765. }
  5766. // 异步获取签名
  5767. function getAuthorizationAsync(params, callback) {
  5768. var headers = util.clone(params.Headers);
  5769. delete headers['Content-Type'];
  5770. delete headers['Cache-Control'];
  5771. util.each(headers, function (v, k) {
  5772. v === '' && delete headers[k];
  5773. });
  5774. var cb = function (AuthData) {
  5775. // 检查签名格式
  5776. var formatAllow = false;
  5777. var auth = AuthData.Authorization;
  5778. if (auth) {
  5779. if (auth.indexOf(' ') > -1) {
  5780. formatAllow = false;
  5781. } else if (auth.indexOf('q-sign-algorithm=') > -1 && auth.indexOf('q-ak=') > -1 && auth.indexOf('q-sign-time=') > -1 && auth.indexOf('q-key-time=') > -1 && auth.indexOf('q-url-param-list=') > -1) {
  5782. formatAllow = true;
  5783. } else {
  5784. try {
  5785. auth = atob(auth);
  5786. if (auth.indexOf('a=') > -1 && auth.indexOf('k=') > -1 && auth.indexOf('t=') > -1 && auth.indexOf('r=') > -1 && auth.indexOf('b=') > -1) {
  5787. formatAllow = true;
  5788. }
  5789. } catch (e) {}
  5790. }
  5791. }
  5792. if (formatAllow) {
  5793. callback && callback(null, AuthData);
  5794. } else {
  5795. callback && callback('authorization error');
  5796. }
  5797. };
  5798. var self = this;
  5799. var Bucket = params.Bucket || '';
  5800. var Region = params.Region || '';
  5801. // PathName
  5802. var KeyName = params.Key || '';
  5803. if (self.options.ForcePathStyle && Bucket) {
  5804. KeyName = Bucket + '/' + KeyName;
  5805. }
  5806. var Pathname = '/' + KeyName;
  5807. // Action、ResourceKey
  5808. var StsData = {};
  5809. var Scope = params.Scope;
  5810. if (!Scope) {
  5811. var Action = params.Action || '';
  5812. var ResourceKey = params.ResourceKey || params.Key || '';
  5813. Scope = params.Scope || [{
  5814. action: Action,
  5815. bucket: Bucket,
  5816. region: Region,
  5817. prefix: ResourceKey
  5818. }];
  5819. }
  5820. var ScopeKey = util.md5(JSON.stringify(Scope));
  5821. // STS
  5822. self._StsCache = self._StsCache || [];
  5823. (function () {
  5824. var i, AuthData;
  5825. for (i = self._StsCache.length - 1; i >= 0; i--) {
  5826. AuthData = self._StsCache[i];
  5827. var compareTime = Math.round(util.getSkewTime(self.options.SystemClockOffset) / 1000) + 30;
  5828. if (AuthData.StartTime && compareTime < AuthData.StartTime || compareTime >= AuthData.ExpiredTime) {
  5829. self._StsCache.splice(i, 1);
  5830. continue;
  5831. }
  5832. if (!AuthData.ScopeLimit || AuthData.ScopeLimit && AuthData.ScopeKey === ScopeKey) {
  5833. StsData = AuthData;
  5834. break;
  5835. }
  5836. }
  5837. })();
  5838. var calcAuthByTmpKey = function () {
  5839. var KeyTime = StsData.StartTime && StsData.ExpiredTime ? StsData.StartTime + ';' + StsData.ExpiredTime : '';
  5840. var Authorization = util.getAuth({
  5841. SecretId: StsData.TmpSecretId,
  5842. SecretKey: StsData.TmpSecretKey,
  5843. Method: params.Method,
  5844. Pathname: Pathname,
  5845. Query: params.Query,
  5846. Headers: headers,
  5847. Expires: params.Expires,
  5848. UseRawKey: self.options.UseRawKey,
  5849. SystemClockOffset: self.options.SystemClockOffset,
  5850. KeyTime: KeyTime
  5851. });
  5852. var AuthData = {
  5853. Authorization: Authorization,
  5854. XCosSecurityToken: StsData.XCosSecurityToken || '',
  5855. Token: StsData.Token || '',
  5856. ClientIP: StsData.ClientIP || '',
  5857. ClientUA: StsData.ClientUA || ''
  5858. };
  5859. cb(AuthData);
  5860. };
  5861. // 先判断是否有临时密钥
  5862. if (StsData.ExpiredTime && StsData.ExpiredTime - util.getSkewTime(self.options.SystemClockOffset) / 1000 > 60) {
  5863. // 如果缓存的临时密钥有效,并还有超过60秒有效期就直接使用
  5864. calcAuthByTmpKey();
  5865. } else if (self.options.getAuthorization) {
  5866. // 外部计算签名或获取临时密钥
  5867. self.options.getAuthorization.call(self, {
  5868. Bucket: Bucket,
  5869. Region: Region,
  5870. Method: params.Method,
  5871. Key: KeyName,
  5872. Pathname: Pathname,
  5873. Query: params.Query,
  5874. Headers: headers,
  5875. Scope: Scope
  5876. }, function (AuthData) {
  5877. if (typeof AuthData === 'string') {
  5878. AuthData = { Authorization: AuthData };
  5879. }
  5880. if (AuthData.TmpSecretId && AuthData.TmpSecretKey && AuthData.XCosSecurityToken && AuthData.ExpiredTime) {
  5881. StsData = AuthData || {};
  5882. StsData.Scope = Scope;
  5883. StsData.ScopeKey = ScopeKey;
  5884. self._StsCache.push(StsData);
  5885. calcAuthByTmpKey();
  5886. } else {
  5887. cb(AuthData);
  5888. }
  5889. });
  5890. } else if (self.options.getSTS) {
  5891. // 外部获取临时密钥
  5892. self.options.getSTS.call(self, {
  5893. Bucket: Bucket,
  5894. Region: Region
  5895. }, function (data) {
  5896. StsData = data || {};
  5897. StsData.Scope = Scope;
  5898. StsData.ScopeKey = ScopeKey;
  5899. StsData.TmpSecretId = StsData.SecretId;
  5900. StsData.TmpSecretKey = StsData.SecretKey;
  5901. self._StsCache.push(StsData);
  5902. calcAuthByTmpKey();
  5903. });
  5904. } else {
  5905. // 内部计算获取签名
  5906. return function () {
  5907. var Authorization = util.getAuth({
  5908. SecretId: params.SecretId || self.options.SecretId,
  5909. SecretKey: params.SecretKey || self.options.SecretKey,
  5910. Method: params.Method,
  5911. Pathname: Pathname,
  5912. Query: params.Query,
  5913. Headers: headers,
  5914. Expires: params.Expires,
  5915. UseRawKey: self.options.UseRawKey,
  5916. SystemClockOffset: self.options.SystemClockOffset
  5917. });
  5918. var AuthData = {
  5919. Authorization: Authorization,
  5920. XCosSecurityToken: self.options.XCosSecurityToken
  5921. };
  5922. cb(AuthData);
  5923. return AuthData;
  5924. }();
  5925. }
  5926. return '';
  5927. }
  5928. // 调整时间偏差
  5929. function allowRetry(err) {
  5930. var allowRetry = false;
  5931. var isTimeError = false;
  5932. var serverDate = err.headers && (err.headers.date || err.headers.Date) || err.error && err.error.ServerTime;
  5933. try {
  5934. var errorCode = err.error.Code;
  5935. var errorMessage = err.error.Message;
  5936. if (errorCode === 'RequestTimeTooSkewed' || errorCode === 'AccessDenied' && errorMessage === 'Request has expired') {
  5937. isTimeError = true;
  5938. }
  5939. } catch (e) {}
  5940. if (err) {
  5941. if (isTimeError && serverDate) {
  5942. var serverTime = Date.parse(serverDate);
  5943. if (this.options.CorrectClockSkew && Math.abs(util.getSkewTime(this.options.SystemClockOffset) - serverTime) >= 30000) {
  5944. console.error('error: Local time is too skewed.');
  5945. this.options.SystemClockOffset = serverTime - Date.now();
  5946. allowRetry = true;
  5947. }
  5948. } else if (Math.round(err.statusCode / 100) === 5) {
  5949. allowRetry = true;
  5950. }
  5951. }
  5952. return allowRetry;
  5953. }
  5954. // 获取签名并发起请求
  5955. function submitRequest(params, callback) {
  5956. var self = this;
  5957. // 处理 headers
  5958. !params.headers && (params.headers = {});
  5959. // 处理 query
  5960. !params.qs && (params.qs = {});
  5961. params.VersionId && (params.qs.versionId = params.VersionId);
  5962. params.qs = util.clearKey(params.qs);
  5963. // 清理 undefined 和 null 字段
  5964. params.headers && (params.headers = util.clearKey(params.headers));
  5965. params.qs && (params.qs = util.clearKey(params.qs));
  5966. var Query = util.clone(params.qs);
  5967. params.action && (Query[params.action] = '');
  5968. var next = function (tryTimes) {
  5969. var oldClockOffset = self.options.SystemClockOffset;
  5970. getAuthorizationAsync.call(self, {
  5971. Bucket: params.Bucket || '',
  5972. Region: params.Region || '',
  5973. Method: params.method,
  5974. Key: params.Key,
  5975. Query: Query,
  5976. Headers: params.headers,
  5977. Action: params.Action,
  5978. ResourceKey: params.ResourceKey,
  5979. Scope: params.Scope
  5980. }, function (err, AuthData) {
  5981. if (err) {
  5982. callback(err);
  5983. return;
  5984. }
  5985. params.AuthData = AuthData;
  5986. _submitRequest.call(self, params, function (err, data) {
  5987. if (err && tryTimes < 2 && (oldClockOffset !== self.options.SystemClockOffset || allowRetry.call(self, err))) {
  5988. if (params.headers) {
  5989. delete params.headers.Authorization;
  5990. delete params.headers['token'];
  5991. delete params.headers['clientIP'];
  5992. delete params.headers['clientUA'];
  5993. delete params.headers['x-cos-security-token'];
  5994. }
  5995. next(tryTimes + 1);
  5996. } else {
  5997. callback(err, data);
  5998. }
  5999. });
  6000. });
  6001. };
  6002. next(1);
  6003. }
  6004. // 发起请求
  6005. function _submitRequest(params, callback) {
  6006. var self = this;
  6007. var TaskId = params.TaskId;
  6008. if (TaskId && !self._isRunningTask(TaskId)) return;
  6009. var bucket = params.Bucket;
  6010. var region = params.Region;
  6011. var object = params.Key;
  6012. var method = params.method || 'GET';
  6013. var url = params.url;
  6014. var body = params.body;
  6015. var json = params.json;
  6016. var rawBody = params.rawBody;
  6017. // url
  6018. url = url || getUrl({
  6019. ForcePathStyle: self.options.ForcePathStyle,
  6020. protocol: self.options.Protocol,
  6021. domain: self.options.Domain,
  6022. bucket: bucket,
  6023. region: region,
  6024. object: object
  6025. });
  6026. if (params.action) {
  6027. url = url + '?' + params.action;
  6028. }
  6029. var opt = {
  6030. method: method,
  6031. url: url,
  6032. headers: params.headers,
  6033. qs: params.qs,
  6034. body: body,
  6035. json: json
  6036. };
  6037. // 获取签名
  6038. opt.headers.Authorization = params.AuthData.Authorization;
  6039. params.AuthData.Token && (opt.headers['token'] = params.AuthData.Token);
  6040. params.AuthData.ClientIP && (opt.headers['clientIP'] = params.AuthData.ClientIP);
  6041. params.AuthData.ClientUA && (opt.headers['clientUA'] = params.AuthData.ClientUA);
  6042. params.AuthData.XCosSecurityToken && (opt.headers['x-cos-security-token'] = params.AuthData.XCosSecurityToken);
  6043. // 清理 undefined 和 null 字段
  6044. opt.headers && (opt.headers = util.clearKey(opt.headers));
  6045. opt = util.clearKey(opt);
  6046. // progress
  6047. if (params.onProgress && typeof params.onProgress === 'function') {
  6048. var contentLength = body && (body.size || body.length) || 0;
  6049. opt.onProgress = function (e) {
  6050. if (TaskId && !self._isRunningTask(TaskId)) return;
  6051. var loaded = e ? e.loaded : 0;
  6052. params.onProgress({ loaded: loaded, total: contentLength });
  6053. };
  6054. }
  6055. if (this.options.Timeout) {
  6056. opt.timeout = this.options.Timeout;
  6057. }
  6058. self.emit('before-send', opt);
  6059. var sender = REQUEST(opt, function (err, response, body) {
  6060. if (err === 'abort') return;
  6061. // 返回内容添加 状态码 和 headers
  6062. var hasReturned;
  6063. var cb = function (err, data) {
  6064. TaskId && self.off('inner-kill-task', killTask);
  6065. if (hasReturned) return;
  6066. hasReturned = true;
  6067. var attrs = {};
  6068. response && response.statusCode && (attrs.statusCode = response.statusCode);
  6069. response && response.headers && (attrs.headers = response.headers);
  6070. if (err) {
  6071. err = util.extend(err || {}, attrs);
  6072. callback(err, null);
  6073. } else {
  6074. data = util.extend(data || {}, attrs);
  6075. callback(null, data);
  6076. }
  6077. sender = null;
  6078. };
  6079. // 请求错误,发生网络错误
  6080. if (err) {
  6081. cb({ error: err });
  6082. return;
  6083. }
  6084. var jsonRes;
  6085. // 不对 body 进行转换,body 直接挂载返回
  6086. if (rawBody) {
  6087. jsonRes = {};
  6088. jsonRes.body = body;
  6089. } else {
  6090. try {
  6091. jsonRes = body && body.indexOf('<') > -1 && body.indexOf('>') > -1 && util.xml2json(body) || {};
  6092. } catch (e) {
  6093. jsonRes = body || {};
  6094. }
  6095. }
  6096. // 请求返回码不为 200
  6097. var statusCode = response.statusCode;
  6098. var statusSuccess = Math.floor(statusCode / 100) === 2; // 200 202 204 206
  6099. if (!statusSuccess) {
  6100. cb({ error: jsonRes.Error || jsonRes });
  6101. return;
  6102. }
  6103. if (jsonRes.Error) {
  6104. cb({ error: jsonRes.Error });
  6105. return;
  6106. }
  6107. cb(null, jsonRes);
  6108. });
  6109. // kill task
  6110. var killTask = function (data) {
  6111. if (data.TaskId === TaskId) {
  6112. sender && sender.abort && sender.abort();
  6113. self.off('inner-kill-task', killTask);
  6114. }
  6115. };
  6116. TaskId && self.on('inner-kill-task', killTask);
  6117. }
  6118. var API_MAP = {
  6119. // Bucket 相关方法
  6120. getService: getService, // Bucket
  6121. putBucket: putBucket,
  6122. headBucket: headBucket, // Bucket
  6123. getBucket: getBucket,
  6124. deleteBucket: deleteBucket,
  6125. putBucketAcl: putBucketAcl, // BucketACL
  6126. getBucketAcl: getBucketAcl,
  6127. putBucketCors: putBucketCors, // BucketCors
  6128. getBucketCors: getBucketCors,
  6129. deleteBucketCors: deleteBucketCors,
  6130. getBucketLocation: getBucketLocation, // BucketLocation
  6131. getBucketPolicy: getBucketPolicy, // BucketPolicy
  6132. putBucketPolicy: putBucketPolicy,
  6133. deleteBucketPolicy: deleteBucketPolicy,
  6134. putBucketTagging: putBucketTagging, // BucketTagging
  6135. getBucketTagging: getBucketTagging,
  6136. deleteBucketTagging: deleteBucketTagging,
  6137. putBucketLifecycle: putBucketLifecycle, // BucketLifecycle
  6138. getBucketLifecycle: getBucketLifecycle,
  6139. deleteBucketLifecycle: deleteBucketLifecycle,
  6140. putBucketVersioning: putBucketVersioning, // BucketVersioning
  6141. getBucketVersioning: getBucketVersioning,
  6142. putBucketReplication: putBucketReplication, // BucketReplication
  6143. getBucketReplication: getBucketReplication,
  6144. deleteBucketReplication: deleteBucketReplication,
  6145. putBucketWebsite: putBucketWebsite, // BucketWebsite
  6146. getBucketWebsite: getBucketWebsite,
  6147. deleteBucketWebsite: deleteBucketWebsite,
  6148. // Object 相关方法
  6149. getObject: getObject,
  6150. headObject: headObject,
  6151. listObjectVersions: listObjectVersions,
  6152. putObject: putObject,
  6153. deleteObject: deleteObject,
  6154. getObjectAcl: getObjectAcl,
  6155. putObjectAcl: putObjectAcl,
  6156. optionsObject: optionsObject,
  6157. putObjectCopy: putObjectCopy,
  6158. deleteMultipleObject: deleteMultipleObject,
  6159. restoreObject: restoreObject,
  6160. // 分块上传相关方法
  6161. uploadPartCopy: uploadPartCopy,
  6162. multipartInit: multipartInit,
  6163. multipartUpload: multipartUpload,
  6164. multipartComplete: multipartComplete,
  6165. multipartList: multipartList,
  6166. multipartListPart: multipartListPart,
  6167. multipartAbort: multipartAbort,
  6168. // 工具方法
  6169. getObjectUrl: getObjectUrl,
  6170. getAuth: getAuth
  6171. };
  6172. function warnOldApi(apiName, fn, proto) {
  6173. util.each(['Cors', 'Acl'], function (suffix) {
  6174. if (apiName.slice(-suffix.length) === suffix) {
  6175. var oldName = apiName.slice(0, -suffix.length) + suffix.toUpperCase();
  6176. var apiFn = util.apiWrapper(apiName, fn);
  6177. var warned = false;
  6178. proto[oldName] = function () {
  6179. !warned && console.warn('warning: cos.' + oldName + ' has been deprecated. Please Use cos.' + apiName + ' instead.');
  6180. warned = true;
  6181. apiFn.apply(this, arguments);
  6182. };
  6183. }
  6184. });
  6185. }
  6186. module.exports.init = function (COS, task) {
  6187. task.transferToTaskMethod(API_MAP, 'putObject');
  6188. util.each(API_MAP, function (fn, apiName) {
  6189. COS.prototype[apiName] = util.apiWrapper(apiName, fn);
  6190. warnOldApi(apiName, fn, COS.prototype);
  6191. });
  6192. };
  6193. /***/ }),
  6194. /* 14 */
  6195. /***/ (function(module, exports) {
  6196. var $ = function () {
  6197. var deletedIds = [];
  6198. var slice = deletedIds.slice;
  6199. var concat = deletedIds.concat;
  6200. var push = deletedIds.push;
  6201. var indexOf = deletedIds.indexOf;
  6202. var class2type = {};
  6203. var toString = class2type.toString;
  6204. var hasOwn = class2type.hasOwnProperty;
  6205. var support = {};
  6206. var version = "1.11.1 -css,-css/addGetHookIf,-css/curCSS,-css/defaultDisplay,-css/hiddenVisibleSelectors,-css/support,-css/swap,-css/var/cssExpand,-css/var/isHidden,-css/var/rmargin,-css/var/rnumnonpx,-effects,-effects/Tween,-effects/animatedSelector,-effects/support,-dimensions,-offset,-deprecated,-event-alias,-wrap",
  6207. // Define a local copy of jQuery
  6208. jQuery = function (selector, context) {
  6209. // The jQuery object is actually just the init constructor 'enhanced'
  6210. // Need init if jQuery is called (just allow error to be thrown if not included)
  6211. return new jQuery.fn.init(selector, context);
  6212. },
  6213. // Support: Android<4.1, IE<9
  6214. // Make sure we trim BOM and NBSP
  6215. rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
  6216. // Matches dashed string for camelizing
  6217. rmsPrefix = /^-ms-/,
  6218. rdashAlpha = /-([\da-z])/gi,
  6219. // Used by jQuery.camelCase as callback to replace()
  6220. fcamelCase = function (all, letter) {
  6221. return letter.toUpperCase();
  6222. };
  6223. jQuery.fn = jQuery.prototype = {
  6224. // The current version of jQuery being used
  6225. jquery: version,
  6226. constructor: jQuery,
  6227. // Start with an empty selector
  6228. selector: "",
  6229. // The default length of a jQuery object is 0
  6230. length: 0,
  6231. toArray: function () {
  6232. return slice.call(this);
  6233. },
  6234. // Get the Nth element in the matched element set OR
  6235. // Get the whole matched element set as a clean array
  6236. get: function (num) {
  6237. return num != null ?
  6238. // Return just the one element from the set
  6239. num < 0 ? this[num + this.length] : this[num] :
  6240. // Return all the elements in a clean array
  6241. slice.call(this);
  6242. },
  6243. // Take an array of elements and push it onto the stack
  6244. // (returning the new matched element set)
  6245. pushStack: function (elems) {
  6246. // Build a new jQuery matched element set
  6247. var ret = jQuery.merge(this.constructor(), elems);
  6248. // Add the old object onto the stack (as a reference)
  6249. ret.prevObject = this;
  6250. ret.context = this.context;
  6251. // Return the newly-formed element set
  6252. return ret;
  6253. },
  6254. // Execute a callback for every element in the matched set.
  6255. // (You can seed the arguments with an array of args, but this is
  6256. // only used internally.)
  6257. each: function (callback, args) {
  6258. return jQuery.each(this, callback, args);
  6259. },
  6260. map: function (callback) {
  6261. return this.pushStack(jQuery.map(this, function (elem, i) {
  6262. return callback.call(elem, i, elem);
  6263. }));
  6264. },
  6265. slice: function () {
  6266. return this.pushStack(slice.apply(this, arguments));
  6267. },
  6268. first: function () {
  6269. return this.eq(0);
  6270. },
  6271. last: function () {
  6272. return this.eq(-1);
  6273. },
  6274. eq: function (i) {
  6275. var len = this.length,
  6276. j = +i + (i < 0 ? len : 0);
  6277. return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
  6278. },
  6279. end: function () {
  6280. return this.prevObject || this.constructor(null);
  6281. },
  6282. // For internal use only.
  6283. // Behaves like an Array's method, not like a jQuery method.
  6284. push: push,
  6285. sort: deletedIds.sort,
  6286. splice: deletedIds.splice
  6287. };
  6288. jQuery.extend = jQuery.fn.extend = function () {
  6289. var src,
  6290. copyIsArray,
  6291. copy,
  6292. name,
  6293. options,
  6294. clone,
  6295. target = arguments[0] || {},
  6296. i = 1,
  6297. length = arguments.length,
  6298. deep = false;
  6299. // Handle a deep copy situation
  6300. if (typeof target === "boolean") {
  6301. deep = target;
  6302. // skip the boolean and the target
  6303. target = arguments[i] || {};
  6304. i++;
  6305. }
  6306. // Handle case when target is a string or something (possible in deep copy)
  6307. if (typeof target !== "object" && !jQuery.isFunction(target)) {
  6308. target = {};
  6309. }
  6310. // extend jQuery itself if only one argument is passed
  6311. if (i === length) {
  6312. target = this;
  6313. i--;
  6314. }
  6315. for (; i < length; i++) {
  6316. // Only deal with non-null/undefined values
  6317. if ((options = arguments[i]) != null) {
  6318. // Extend the base object
  6319. for (name in options) {
  6320. src = target[name];
  6321. copy = options[name];
  6322. // Prevent never-ending loop
  6323. if (target === copy) {
  6324. continue;
  6325. }
  6326. // Recurse if we're merging plain objects or arrays
  6327. if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {
  6328. if (copyIsArray) {
  6329. copyIsArray = false;
  6330. clone = src && jQuery.isArray(src) ? src : [];
  6331. } else {
  6332. clone = src && jQuery.isPlainObject(src) ? src : {};
  6333. }
  6334. // Never move original objects, clone them
  6335. target[name] = jQuery.extend(deep, clone, copy);
  6336. // Don't bring in undefined values
  6337. } else if (copy !== undefined) {
  6338. target[name] = copy;
  6339. }
  6340. }
  6341. }
  6342. }
  6343. // Return the modified object
  6344. return target;
  6345. };
  6346. jQuery.extend({
  6347. // Unique for each copy of jQuery on the page
  6348. expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""),
  6349. // Assume jQuery is ready without the ready module
  6350. isReady: true,
  6351. error: function (msg) {
  6352. throw new Error(msg);
  6353. },
  6354. noop: function () {},
  6355. // See test/unit/core.js for details concerning isFunction.
  6356. // Since version 1.3, DOM methods and functions like alert
  6357. // aren't supported. They return false on IE (#2968).
  6358. isFunction: function (obj) {
  6359. return jQuery.type(obj) === "function";
  6360. },
  6361. isArray: Array.isArray || function (obj) {
  6362. return jQuery.type(obj) === "array";
  6363. },
  6364. isWindow: function (obj) {
  6365. /* jshint eqeqeq: false */
  6366. return obj != null && obj == obj.window;
  6367. },
  6368. isNumeric: function (obj) {
  6369. // parseFloat NaNs numeric-cast false positives (null|true|false|"")
  6370. // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
  6371. // subtraction forces infinities to NaN
  6372. return !jQuery.isArray(obj) && obj - parseFloat(obj) >= 0;
  6373. },
  6374. isEmptyObject: function (obj) {
  6375. var name;
  6376. for (name in obj) {
  6377. return false;
  6378. }
  6379. return true;
  6380. },
  6381. isPlainObject: function (obj) {
  6382. var key;
  6383. // Must be an Object.
  6384. // Because of IE, we also have to check the presence of the constructor property.
  6385. // Make sure that DOM nodes and window objects don't pass through, as well
  6386. if (!obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow(obj)) {
  6387. return false;
  6388. }
  6389. try {
  6390. // Not own constructor property must be Object
  6391. if (obj.constructor && !hasOwn.call(obj, "constructor") && !hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
  6392. return false;
  6393. }
  6394. } catch (e) {
  6395. // IE8,9 Will throw exceptions on certain host objects #9897
  6396. return false;
  6397. }
  6398. // Support: IE<9
  6399. // Handle iteration over inherited properties before own properties.
  6400. if (support.ownLast) {
  6401. for (key in obj) {
  6402. return hasOwn.call(obj, key);
  6403. }
  6404. }
  6405. // Own properties are enumerated firstly, so to speed up,
  6406. // if last one is own, then all properties are own.
  6407. for (key in obj) {}
  6408. return key === undefined || hasOwn.call(obj, key);
  6409. },
  6410. type: function (obj) {
  6411. if (obj == null) {
  6412. return obj + "";
  6413. }
  6414. return typeof obj === "object" || typeof obj === "function" ? class2type[toString.call(obj)] || "object" : typeof obj;
  6415. },
  6416. // Evaluates a script in a global context
  6417. // Workarounds based on findings by Jim Driscoll
  6418. // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
  6419. globalEval: function (data) {
  6420. if (data && jQuery.trim(data)) {
  6421. // We use execScript on Internet Explorer
  6422. // We use an anonymous function so that context is window
  6423. // rather than jQuery in Firefox
  6424. (window.execScript || function (data) {
  6425. window["eval"].call(window, data);
  6426. })(data);
  6427. }
  6428. },
  6429. // Convert dashed to camelCase; used by the css and data modules
  6430. // Microsoft forgot to hump their vendor prefix (#9572)
  6431. camelCase: function (string) {
  6432. return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase);
  6433. },
  6434. nodeName: function (elem, name) {
  6435. return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
  6436. },
  6437. // args is for internal usage only
  6438. each: function (obj, callback, args) {
  6439. var value,
  6440. i = 0,
  6441. length = obj.length,
  6442. isArray = isArraylike(obj);
  6443. if (args) {
  6444. if (isArray) {
  6445. for (; i < length; i++) {
  6446. value = callback.apply(obj[i], args);
  6447. if (value === false) {
  6448. break;
  6449. }
  6450. }
  6451. } else {
  6452. for (i in obj) {
  6453. value = callback.apply(obj[i], args);
  6454. if (value === false) {
  6455. break;
  6456. }
  6457. }
  6458. }
  6459. // A special, fast, case for the most common use of each
  6460. } else {
  6461. if (isArray) {
  6462. for (; i < length; i++) {
  6463. value = callback.call(obj[i], i, obj[i]);
  6464. if (value === false) {
  6465. break;
  6466. }
  6467. }
  6468. } else {
  6469. for (i in obj) {
  6470. value = callback.call(obj[i], i, obj[i]);
  6471. if (value === false) {
  6472. break;
  6473. }
  6474. }
  6475. }
  6476. }
  6477. return obj;
  6478. },
  6479. // Support: Android<4.1, IE<9
  6480. trim: function (text) {
  6481. return text == null ? "" : (text + "").replace(rtrim, "");
  6482. },
  6483. // results is for internal usage only
  6484. makeArray: function (arr, results) {
  6485. var ret = results || [];
  6486. if (arr != null) {
  6487. if (isArraylike(Object(arr))) {
  6488. jQuery.merge(ret, typeof arr === "string" ? [arr] : arr);
  6489. } else {
  6490. push.call(ret, arr);
  6491. }
  6492. }
  6493. return ret;
  6494. },
  6495. inArray: function (elem, arr, i) {
  6496. var len;
  6497. if (arr) {
  6498. if (indexOf) {
  6499. return indexOf.call(arr, elem, i);
  6500. }
  6501. len = arr.length;
  6502. i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
  6503. for (; i < len; i++) {
  6504. // Skip accessing in sparse arrays
  6505. if (i in arr && arr[i] === elem) {
  6506. return i;
  6507. }
  6508. }
  6509. }
  6510. return -1;
  6511. },
  6512. merge: function (first, second) {
  6513. var len = +second.length,
  6514. j = 0,
  6515. i = first.length;
  6516. while (j < len) {
  6517. first[i++] = second[j++];
  6518. }
  6519. // Support: IE<9
  6520. // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
  6521. if (len !== len) {
  6522. while (second[j] !== undefined) {
  6523. first[i++] = second[j++];
  6524. }
  6525. }
  6526. first.length = i;
  6527. return first;
  6528. },
  6529. grep: function (elems, callback, invert) {
  6530. var callbackInverse,
  6531. matches = [],
  6532. i = 0,
  6533. length = elems.length,
  6534. callbackExpect = !invert;
  6535. // Go through the array, only saving the items
  6536. // that pass the validator function
  6537. for (; i < length; i++) {
  6538. callbackInverse = !callback(elems[i], i);
  6539. if (callbackInverse !== callbackExpect) {
  6540. matches.push(elems[i]);
  6541. }
  6542. }
  6543. return matches;
  6544. },
  6545. // arg is for internal usage only
  6546. map: function (elems, callback, arg) {
  6547. var value,
  6548. i = 0,
  6549. length = elems.length,
  6550. isArray = isArraylike(elems),
  6551. ret = [];
  6552. // Go through the array, translating each of the items to their new values
  6553. if (isArray) {
  6554. for (; i < length; i++) {
  6555. value = callback(elems[i], i, arg);
  6556. if (value != null) {
  6557. ret.push(value);
  6558. }
  6559. }
  6560. // Go through every key on the object,
  6561. } else {
  6562. for (i in elems) {
  6563. value = callback(elems[i], i, arg);
  6564. if (value != null) {
  6565. ret.push(value);
  6566. }
  6567. }
  6568. }
  6569. // Flatten any nested arrays
  6570. return concat.apply([], ret);
  6571. },
  6572. // A global GUID counter for objects
  6573. guid: 1,
  6574. // Bind a function to a context, optionally partially applying any
  6575. // arguments.
  6576. proxy: function (fn, context) {
  6577. var args, proxy, tmp;
  6578. if (typeof context === "string") {
  6579. tmp = fn[context];
  6580. context = fn;
  6581. fn = tmp;
  6582. }
  6583. // Quick check to determine if target is callable, in the spec
  6584. // this throws a TypeError, but we will just return undefined.
  6585. if (!jQuery.isFunction(fn)) {
  6586. return undefined;
  6587. }
  6588. // Simulated bind
  6589. args = slice.call(arguments, 2);
  6590. proxy = function () {
  6591. return fn.apply(context || this, args.concat(slice.call(arguments)));
  6592. };
  6593. // Set the guid of unique handler to the same of original handler, so it can be removed
  6594. proxy.guid = fn.guid = fn.guid || jQuery.guid++;
  6595. return proxy;
  6596. },
  6597. now: function () {
  6598. return +new Date();
  6599. },
  6600. // jQuery.support is not used in Core but other projects attach their
  6601. // properties to it so it needs to exist.
  6602. support: support
  6603. });
  6604. // Populate the class2type map
  6605. jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function (i, name) {
  6606. class2type["[object " + name + "]"] = name.toLowerCase();
  6607. });
  6608. function isArraylike(obj) {
  6609. var length = obj.length,
  6610. type = jQuery.type(obj);
  6611. if (type === "function" || jQuery.isWindow(obj)) {
  6612. return false;
  6613. }
  6614. if (obj.nodeType === 1 && length) {
  6615. return true;
  6616. }
  6617. return type === "array" || length === 0 || typeof length === "number" && length > 0 && length - 1 in obj;
  6618. }
  6619. // Initialize a jQuery object
  6620. // A central reference to the root jQuery(document)
  6621. var rootjQuery,
  6622. // Use the correct document accordingly with window argument (sandbox)
  6623. document = window.document,
  6624. // A simple way to check for HTML strings
  6625. // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
  6626. // Strict HTML recognition (#11290: must start with <)
  6627. rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
  6628. init = jQuery.fn.init = function (selector, context) {
  6629. var match, elem;
  6630. // HANDLE: $(""), $(null), $(undefined), $(false)
  6631. if (!selector) {
  6632. return this;
  6633. }
  6634. // Handle HTML strings
  6635. if (typeof selector === "string") {
  6636. if (selector.charAt(0) === "<" && selector.charAt(selector.length - 1) === ">" && selector.length >= 3) {
  6637. // Assume that strings that start and end with <> are HTML and skip the regex check
  6638. match = [null, selector, null];
  6639. } else {
  6640. match = rquickExpr.exec(selector);
  6641. }
  6642. // Match html or make sure no context is specified for #id
  6643. if (match && (match[1] || !context)) {
  6644. // HANDLE: $(html) -> $(array)
  6645. if (match[1]) {
  6646. context = context instanceof jQuery ? context[0] : context;
  6647. // scripts is true for back-compat
  6648. // Intentionally let the error be thrown if parseHTML is not present
  6649. jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, true));
  6650. // HANDLE: $(html, props)
  6651. if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
  6652. for (match in context) {
  6653. // Properties of context are called as methods if possible
  6654. if (jQuery.isFunction(this[match])) {
  6655. this[match](context[match]);
  6656. // ...and otherwise set as attributes
  6657. } else {
  6658. this.attr(match, context[match]);
  6659. }
  6660. }
  6661. }
  6662. return this;
  6663. // HANDLE: $(#id)
  6664. } else {
  6665. elem = document.getElementById(match[2]);
  6666. // Check parentNode to catch when Blackberry 4.6 returns
  6667. // nodes that are no longer in the document #6963
  6668. if (elem && elem.parentNode) {
  6669. // Handle the case where IE and Opera return items
  6670. // by name instead of ID
  6671. if (elem.id !== match[2]) {
  6672. return rootjQuery.find(selector);
  6673. }
  6674. // Otherwise, we inject the element directly into the jQuery object
  6675. this.length = 1;
  6676. this[0] = elem;
  6677. }
  6678. this.context = document;
  6679. this.selector = selector;
  6680. return this;
  6681. }
  6682. // HANDLE: $(expr, $(...))
  6683. } else if (!context || context.jquery) {
  6684. return (context || rootjQuery).find(selector);
  6685. // HANDLE: $(expr, context)
  6686. // (which is just equivalent to: $(context).find(expr)
  6687. } else {
  6688. return this.constructor(context).find(selector);
  6689. }
  6690. // HANDLE: $(DOMElement)
  6691. } else if (selector.nodeType) {
  6692. this.context = this[0] = selector;
  6693. this.length = 1;
  6694. return this;
  6695. // HANDLE: $(function)
  6696. // Shortcut for document ready
  6697. } else if (jQuery.isFunction(selector)) {
  6698. return typeof rootjQuery.ready !== "undefined" ? rootjQuery.ready(selector) :
  6699. // Execute immediately if ready is not present
  6700. selector(jQuery);
  6701. }
  6702. if (selector.selector !== undefined) {
  6703. this.selector = selector.selector;
  6704. this.context = selector.context;
  6705. }
  6706. return jQuery.makeArray(selector, this);
  6707. };
  6708. // Give the init function the jQuery prototype for later instantiation
  6709. init.prototype = jQuery.fn;
  6710. // Initialize central reference
  6711. rootjQuery = jQuery(document);
  6712. var rnotwhite = /\S+/g;
  6713. // String to Object options format cache
  6714. var optionsCache = {};
  6715. // Convert String-formatted options into Object-formatted ones and store in cache
  6716. function createOptions(options) {
  6717. var object = optionsCache[options] = {};
  6718. jQuery.each(options.match(rnotwhite) || [], function (_, flag) {
  6719. object[flag] = true;
  6720. });
  6721. return object;
  6722. }
  6723. /*
  6724. * Create a callback list using the following parameters:
  6725. *
  6726. * options: an optional list of space-separated options that will change how
  6727. * the callback list behaves or a more traditional option object
  6728. *
  6729. * By default a callback list will act like an event callback list and can be
  6730. * "fired" multiple times.
  6731. *
  6732. * Possible options:
  6733. *
  6734. * once: will ensure the callback list can only be fired once (like a Deferred)
  6735. *
  6736. * memory: will keep track of previous values and will call any callback added
  6737. * after the list has been fired right away with the latest "memorized"
  6738. * values (like a Deferred)
  6739. *
  6740. * unique: will ensure a callback can only be added once (no duplicate in the list)
  6741. *
  6742. * stopOnFalse: interrupt callings when a callback returns false
  6743. *
  6744. */
  6745. jQuery.Callbacks = function (options) {
  6746. // Convert options from String-formatted to Object-formatted if needed
  6747. // (we check in cache first)
  6748. options = typeof options === "string" ? optionsCache[options] || createOptions(options) : jQuery.extend({}, options);
  6749. var // Flag to know if list is currently firing
  6750. firing,
  6751. // Last fire value (for non-forgettable lists)
  6752. memory,
  6753. // Flag to know if list was already fired
  6754. fired,
  6755. // End of the loop when firing
  6756. firingLength,
  6757. // Index of currently firing callback (modified by remove if needed)
  6758. firingIndex,
  6759. // First callback to fire (used internally by add and fireWith)
  6760. firingStart,
  6761. // Actual callback list
  6762. list = [],
  6763. // Stack of fire calls for repeatable lists
  6764. stack = !options.once && [],
  6765. // Fire callbacks
  6766. fire = function (data) {
  6767. memory = options.memory && data;
  6768. fired = true;
  6769. firingIndex = firingStart || 0;
  6770. firingStart = 0;
  6771. firingLength = list.length;
  6772. firing = true;
  6773. for (; list && firingIndex < firingLength; firingIndex++) {
  6774. if (list[firingIndex].apply(data[0], data[1]) === false && options.stopOnFalse) {
  6775. memory = false; // To prevent further calls using add
  6776. break;
  6777. }
  6778. }
  6779. firing = false;
  6780. if (list) {
  6781. if (stack) {
  6782. if (stack.length) {
  6783. fire(stack.shift());
  6784. }
  6785. } else if (memory) {
  6786. list = [];
  6787. } else {
  6788. self.disable();
  6789. }
  6790. }
  6791. },
  6792. // Actual Callbacks object
  6793. self = {
  6794. // Add a callback or a collection of callbacks to the list
  6795. add: function () {
  6796. if (list) {
  6797. // First, we save the current length
  6798. var start = list.length;
  6799. (function add(args) {
  6800. jQuery.each(args, function (_, arg) {
  6801. var type = jQuery.type(arg);
  6802. if (type === "function") {
  6803. if (!options.unique || !self.has(arg)) {
  6804. list.push(arg);
  6805. }
  6806. } else if (arg && arg.length && type !== "string") {
  6807. // Inspect recursively
  6808. add(arg);
  6809. }
  6810. });
  6811. })(arguments);
  6812. // Do we need to add the callbacks to the
  6813. // current firing batch?
  6814. if (firing) {
  6815. firingLength = list.length;
  6816. // With memory, if we're not firing then
  6817. // we should call right away
  6818. } else if (memory) {
  6819. firingStart = start;
  6820. fire(memory);
  6821. }
  6822. }
  6823. return this;
  6824. },
  6825. // Remove a callback from the list
  6826. remove: function () {
  6827. if (list) {
  6828. jQuery.each(arguments, function (_, arg) {
  6829. var index;
  6830. while ((index = jQuery.inArray(arg, list, index)) > -1) {
  6831. list.splice(index, 1);
  6832. // Handle firing indexes
  6833. if (firing) {
  6834. if (index <= firingLength) {
  6835. firingLength--;
  6836. }
  6837. if (index <= firingIndex) {
  6838. firingIndex--;
  6839. }
  6840. }
  6841. }
  6842. });
  6843. }
  6844. return this;
  6845. },
  6846. // Check if a given callback is in the list.
  6847. // If no argument is given, return whether or not list has callbacks attached.
  6848. has: function (fn) {
  6849. return fn ? jQuery.inArray(fn, list) > -1 : !!(list && list.length);
  6850. },
  6851. // Remove all callbacks from the list
  6852. empty: function () {
  6853. list = [];
  6854. firingLength = 0;
  6855. return this;
  6856. },
  6857. // Have the list do nothing anymore
  6858. disable: function () {
  6859. list = stack = memory = undefined;
  6860. return this;
  6861. },
  6862. // Is it disabled?
  6863. disabled: function () {
  6864. return !list;
  6865. },
  6866. // Lock the list in its current state
  6867. lock: function () {
  6868. stack = undefined;
  6869. if (!memory) {
  6870. self.disable();
  6871. }
  6872. return this;
  6873. },
  6874. // Is it locked?
  6875. locked: function () {
  6876. return !stack;
  6877. },
  6878. // Call all callbacks with the given context and arguments
  6879. fireWith: function (context, args) {
  6880. if (list && (!fired || stack)) {
  6881. args = args || [];
  6882. args = [context, args.slice ? args.slice() : args];
  6883. if (firing) {
  6884. stack.push(args);
  6885. } else {
  6886. fire(args);
  6887. }
  6888. }
  6889. return this;
  6890. },
  6891. // Call all the callbacks with the given arguments
  6892. fire: function () {
  6893. self.fireWith(this, arguments);
  6894. return this;
  6895. },
  6896. // To know if the callbacks have already been called at least once
  6897. fired: function () {
  6898. return !!fired;
  6899. }
  6900. };
  6901. return self;
  6902. };
  6903. jQuery.extend({
  6904. Deferred: function (func) {
  6905. var tuples = [
  6906. // action, add listener, listener list, final state
  6907. ["resolve", "done", jQuery.Callbacks("once memory"), "resolved"], ["reject", "fail", jQuery.Callbacks("once memory"), "rejected"], ["notify", "progress", jQuery.Callbacks("memory")]],
  6908. state = "pending",
  6909. promise = {
  6910. state: function () {
  6911. return state;
  6912. },
  6913. always: function () {
  6914. deferred.done(arguments).fail(arguments);
  6915. return this;
  6916. },
  6917. then: function () /* fnDone, fnFail, fnProgress */{
  6918. var fns = arguments;
  6919. return jQuery.Deferred(function (newDefer) {
  6920. jQuery.each(tuples, function (i, tuple) {
  6921. var fn = jQuery.isFunction(fns[i]) && fns[i];
  6922. // deferred[ done | fail | progress ] for forwarding actions to newDefer
  6923. deferred[tuple[1]](function () {
  6924. var returned = fn && fn.apply(this, arguments);
  6925. if (returned && jQuery.isFunction(returned.promise)) {
  6926. returned.promise().done(newDefer.resolve).fail(newDefer.reject).progress(newDefer.notify);
  6927. } else {
  6928. newDefer[tuple[0] + "With"](this === promise ? newDefer.promise() : this, fn ? [returned] : arguments);
  6929. }
  6930. });
  6931. });
  6932. fns = null;
  6933. }).promise();
  6934. },
  6935. // Get a promise for this deferred
  6936. // If obj is provided, the promise aspect is added to the object
  6937. promise: function (obj) {
  6938. return obj != null ? jQuery.extend(obj, promise) : promise;
  6939. }
  6940. },
  6941. deferred = {};
  6942. // Keep pipe for back-compat
  6943. promise.pipe = promise.then;
  6944. // Add list-specific methods
  6945. jQuery.each(tuples, function (i, tuple) {
  6946. var list = tuple[2],
  6947. stateString = tuple[3];
  6948. // promise[ done | fail | progress ] = list.add
  6949. promise[tuple[1]] = list.add;
  6950. // Handle state
  6951. if (stateString) {
  6952. list.add(function () {
  6953. // state = [ resolved | rejected ]
  6954. state = stateString;
  6955. // [ reject_list | resolve_list ].disable; progress_list.lock
  6956. }, tuples[i ^ 1][2].disable, tuples[2][2].lock);
  6957. }
  6958. // deferred[ resolve | reject | notify ]
  6959. deferred[tuple[0]] = function () {
  6960. deferred[tuple[0] + "With"](this === deferred ? promise : this, arguments);
  6961. return this;
  6962. };
  6963. deferred[tuple[0] + "With"] = list.fireWith;
  6964. });
  6965. // Make the deferred a promise
  6966. promise.promise(deferred);
  6967. // Call given func if any
  6968. if (func) {
  6969. func.call(deferred, deferred);
  6970. }
  6971. // All done!
  6972. return deferred;
  6973. },
  6974. // Deferred helper
  6975. when: function (subordinate /* , ..., subordinateN */) {
  6976. var i = 0,
  6977. resolveValues = slice.call(arguments),
  6978. length = resolveValues.length,
  6979. // the count of uncompleted subordinates
  6980. remaining = length !== 1 || subordinate && jQuery.isFunction(subordinate.promise) ? length : 0,
  6981. // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
  6982. deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
  6983. // Update function for both resolve and progress values
  6984. updateFunc = function (i, contexts, values) {
  6985. return function (value) {
  6986. contexts[i] = this;
  6987. values[i] = arguments.length > 1 ? slice.call(arguments) : value;
  6988. if (values === progressValues) {
  6989. deferred.notifyWith(contexts, values);
  6990. } else if (! --remaining) {
  6991. deferred.resolveWith(contexts, values);
  6992. }
  6993. };
  6994. },
  6995. progressValues,
  6996. progressContexts,
  6997. resolveContexts;
  6998. // add listeners to Deferred subordinates; treat others as resolved
  6999. if (length > 1) {
  7000. progressValues = new Array(length);
  7001. progressContexts = new Array(length);
  7002. resolveContexts = new Array(length);
  7003. for (; i < length; i++) {
  7004. if (resolveValues[i] && jQuery.isFunction(resolveValues[i].promise)) {
  7005. resolveValues[i].promise().done(updateFunc(i, resolveContexts, resolveValues)).fail(deferred.reject).progress(updateFunc(i, progressContexts, progressValues));
  7006. } else {
  7007. --remaining;
  7008. }
  7009. }
  7010. }
  7011. // if we're not waiting on anything, resolve the master
  7012. if (!remaining) {
  7013. deferred.resolveWith(resolveContexts, resolveValues);
  7014. }
  7015. return deferred.promise();
  7016. }
  7017. });
  7018. // The deferred used on DOM ready
  7019. var readyList;
  7020. jQuery.fn.ready = function (fn) {
  7021. // Add the callback
  7022. jQuery.ready.promise().done(fn);
  7023. return this;
  7024. };
  7025. jQuery.extend({
  7026. // Is the DOM ready to be used? Set to true once it occurs.
  7027. isReady: false,
  7028. // A counter to track how many items to wait for before
  7029. // the ready event fires. See #6781
  7030. readyWait: 1,
  7031. // Hold (or release) the ready event
  7032. holdReady: function (hold) {
  7033. if (hold) {
  7034. jQuery.readyWait++;
  7035. } else {
  7036. jQuery.ready(true);
  7037. }
  7038. },
  7039. // Handle when the DOM is ready
  7040. ready: function (wait) {
  7041. // Abort if there are pending holds or we're already ready
  7042. if (wait === true ? --jQuery.readyWait : jQuery.isReady) {
  7043. return;
  7044. }
  7045. // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
  7046. if (!document.body) {
  7047. return setTimeout(jQuery.ready);
  7048. }
  7049. // Remember that the DOM is ready
  7050. jQuery.isReady = true;
  7051. // If a normal DOM Ready event fired, decrement, and wait if need be
  7052. if (wait !== true && --jQuery.readyWait > 0) {
  7053. return;
  7054. }
  7055. // If there are functions bound, to execute
  7056. readyList.resolveWith(document, [jQuery]);
  7057. // Trigger any bound ready events
  7058. if (jQuery.fn.triggerHandler) {
  7059. jQuery(document).triggerHandler("ready");
  7060. jQuery(document).off("ready");
  7061. }
  7062. }
  7063. });
  7064. /**
  7065. * Clean-up method for dom ready events
  7066. */
  7067. function detach() {
  7068. if (document.addEventListener) {
  7069. document.removeEventListener("DOMContentLoaded", completed, false);
  7070. window.removeEventListener("load", completed, false);
  7071. } else {
  7072. document.detachEvent("onreadystatechange", completed);
  7073. window.detachEvent("onload", completed);
  7074. }
  7075. }
  7076. /**
  7077. * The ready event handler and self cleanup method
  7078. */
  7079. function completed() {
  7080. // readyState === "complete" is good enough for us to call the dom ready in oldIE
  7081. if (document.addEventListener || event.type === "load" || document.readyState === "complete") {
  7082. detach();
  7083. jQuery.ready();
  7084. }
  7085. }
  7086. jQuery.ready.promise = function (obj) {
  7087. if (!readyList) {
  7088. readyList = jQuery.Deferred();
  7089. // Catch cases where $(document).ready() is called after the browser event has already occurred.
  7090. // we once tried to use readyState "interactive" here, but it caused issues like the one
  7091. // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
  7092. if (document.readyState === "complete") {
  7093. // Handle it asynchronously to allow scripts the opportunity to delay ready
  7094. setTimeout(jQuery.ready);
  7095. // Standards-based browsers support DOMContentLoaded
  7096. } else if (document.addEventListener) {
  7097. // Use the handy event callback
  7098. document.addEventListener("DOMContentLoaded", completed, false);
  7099. // A fallback to window.onload, that will always work
  7100. window.addEventListener("load", completed, false);
  7101. // If IE event model is used
  7102. } else {
  7103. // Ensure firing before onload, maybe late but safe also for iframes
  7104. document.attachEvent("onreadystatechange", completed);
  7105. // A fallback to window.onload, that will always work
  7106. window.attachEvent("onload", completed);
  7107. // If IE and not a frame
  7108. // continually check to see if the document is ready
  7109. var top = false;
  7110. try {
  7111. top = window.frameElement == null && document.documentElement;
  7112. } catch (e) {}
  7113. if (top && top.doScroll) {
  7114. (function doScrollCheck() {
  7115. if (!jQuery.isReady) {
  7116. try {
  7117. // Use the trick by Diego Perini
  7118. // http://javascript.nwbox.com/IEContentLoaded/
  7119. top.doScroll("left");
  7120. } catch (e) {
  7121. return setTimeout(doScrollCheck, 50);
  7122. }
  7123. // detach all dom ready events
  7124. detach();
  7125. // and execute any waiting functions
  7126. jQuery.ready();
  7127. }
  7128. })();
  7129. }
  7130. }
  7131. }
  7132. return readyList.promise(obj);
  7133. };
  7134. var strundefined = typeof undefined;
  7135. // Support: IE<9
  7136. // Iteration over object's inherited properties before its own
  7137. var i;
  7138. for (i in jQuery(support)) {
  7139. break;
  7140. }
  7141. support.ownLast = i !== "0";
  7142. // Note: most support tests are defined in their respective modules.
  7143. // false until the test is run
  7144. support.inlineBlockNeedsLayout = false;
  7145. // Execute ASAP in case we need to set body.style.zoom
  7146. jQuery(function () {
  7147. // Minified: var a,b,c,d
  7148. var val, div, body, container;
  7149. body = document.getElementsByTagName("body")[0];
  7150. if (!body || !body.style) {
  7151. // Return for frameset docs that don't have a body
  7152. return;
  7153. }
  7154. // Setup
  7155. div = document.createElement("div");
  7156. container = document.createElement("div");
  7157. container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
  7158. body.appendChild(container).appendChild(div);
  7159. if (typeof div.style.zoom !== strundefined) {
  7160. // Support: IE<8
  7161. // Check if natively block-level elements act like inline-block
  7162. // elements when setting their display to 'inline' and giving
  7163. // them layout
  7164. div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
  7165. support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
  7166. if (val) {
  7167. // Prevent IE 6 from affecting layout for positioned elements #11048
  7168. // Prevent IE from shrinking the body in IE 7 mode #12869
  7169. // Support: IE<8
  7170. body.style.zoom = 1;
  7171. }
  7172. }
  7173. body.removeChild(container);
  7174. });
  7175. (function () {
  7176. var div = document.createElement("div");
  7177. // Execute the test only if not already executed in another module.
  7178. if (support.deleteExpando == null) {
  7179. // Support: IE<9
  7180. support.deleteExpando = true;
  7181. try {
  7182. delete div.test;
  7183. } catch (e) {
  7184. support.deleteExpando = false;
  7185. }
  7186. }
  7187. // Null elements to avoid leaks in IE.
  7188. div = null;
  7189. })();
  7190. /**
  7191. * Determines whether an object can have data
  7192. */
  7193. jQuery.acceptData = function (elem) {
  7194. var noData = jQuery.noData[(elem.nodeName + " ").toLowerCase()],
  7195. nodeType = +elem.nodeType || 1;
  7196. // Do not set data on non-element DOM nodes because it will not be cleared (#8335).
  7197. return nodeType !== 1 && nodeType !== 9 ? false :
  7198. // Nodes accept data unless otherwise specified; rejection can be conditional
  7199. !noData || noData !== true && elem.getAttribute("classid") === noData;
  7200. };
  7201. var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
  7202. rmultiDash = /([A-Z])/g;
  7203. function dataAttr(elem, key, data) {
  7204. // If nothing was found internally, try to fetch any
  7205. // data from the HTML5 data-* attribute
  7206. if (data === undefined && elem.nodeType === 1) {
  7207. var name = "data-" + key.replace(rmultiDash, "-$1").toLowerCase();
  7208. data = elem.getAttribute(name);
  7209. if (typeof data === "string") {
  7210. try {
  7211. data = data === "true" ? true : data === "false" ? false : data === "null" ? null :
  7212. // Only convert to a number if it doesn't change the string
  7213. +data + "" === data ? +data : rbrace.test(data) ? jQuery.parseJSON(data) : data;
  7214. } catch (e) {}
  7215. // Make sure we set the data so it isn't changed later
  7216. jQuery.data(elem, key, data);
  7217. } else {
  7218. data = undefined;
  7219. }
  7220. }
  7221. return data;
  7222. }
  7223. // checks a cache object for emptiness
  7224. function isEmptyDataObject(obj) {
  7225. var name;
  7226. for (name in obj) {
  7227. // if the public data object is empty, the private is still empty
  7228. if (name === "data" && jQuery.isEmptyObject(obj[name])) {
  7229. continue;
  7230. }
  7231. if (name !== "toJSON") {
  7232. return false;
  7233. }
  7234. }
  7235. return true;
  7236. }
  7237. function internalData(elem, name, data, pvt /* Internal Use Only */) {
  7238. if (!jQuery.acceptData(elem)) {
  7239. return;
  7240. }
  7241. var ret,
  7242. thisCache,
  7243. internalKey = jQuery.expando,
  7244. // We have to handle DOM nodes and JS objects differently because IE6-7
  7245. // can't GC object references properly across the DOM-JS boundary
  7246. isNode = elem.nodeType,
  7247. // Only DOM nodes need the global jQuery cache; JS object data is
  7248. // attached directly to the object so GC can occur automatically
  7249. cache = isNode ? jQuery.cache : elem,
  7250. // Only defining an ID for JS objects if its cache already exists allows
  7251. // the code to shortcut on the same path as a DOM node with no cache
  7252. id = isNode ? elem[internalKey] : elem[internalKey] && internalKey;
  7253. // Avoid doing any more work than we need to when trying to get data on an
  7254. // object that has no data at all
  7255. if ((!id || !cache[id] || !pvt && !cache[id].data) && data === undefined && typeof name === "string") {
  7256. return;
  7257. }
  7258. if (!id) {
  7259. // Only DOM nodes need a new unique ID for each element since their data
  7260. // ends up in the global cache
  7261. if (isNode) {
  7262. id = elem[internalKey] = deletedIds.pop() || jQuery.guid++;
  7263. } else {
  7264. id = internalKey;
  7265. }
  7266. }
  7267. if (!cache[id]) {
  7268. // Avoid exposing jQuery metadata on plain JS objects when the object
  7269. // is serialized using JSON.stringify
  7270. cache[id] = isNode ? {} : { toJSON: jQuery.noop };
  7271. }
  7272. // An object can be passed to jQuery.data instead of a key/value pair; this gets
  7273. // shallow copied over onto the existing cache
  7274. if (typeof name === "object" || typeof name === "function") {
  7275. if (pvt) {
  7276. cache[id] = jQuery.extend(cache[id], name);
  7277. } else {
  7278. cache[id].data = jQuery.extend(cache[id].data, name);
  7279. }
  7280. }
  7281. thisCache = cache[id];
  7282. // jQuery data() is stored in a separate object inside the object's internal data
  7283. // cache in order to avoid key collisions between internal data and user-defined
  7284. // data.
  7285. if (!pvt) {
  7286. if (!thisCache.data) {
  7287. thisCache.data = {};
  7288. }
  7289. thisCache = thisCache.data;
  7290. }
  7291. if (data !== undefined) {
  7292. thisCache[jQuery.camelCase(name)] = data;
  7293. }
  7294. // Check for both converted-to-camel and non-converted data property names
  7295. // If a data property was specified
  7296. if (typeof name === "string") {
  7297. // First Try to find as-is property data
  7298. ret = thisCache[name];
  7299. // Test for null|undefined property data
  7300. if (ret == null) {
  7301. // Try to find the camelCased property
  7302. ret = thisCache[jQuery.camelCase(name)];
  7303. }
  7304. } else {
  7305. ret = thisCache;
  7306. }
  7307. return ret;
  7308. }
  7309. function internalRemoveData(elem, name, pvt) {
  7310. if (!jQuery.acceptData(elem)) {
  7311. return;
  7312. }
  7313. var thisCache,
  7314. i,
  7315. isNode = elem.nodeType,
  7316. // See jQuery.data for more information
  7317. cache = isNode ? jQuery.cache : elem,
  7318. id = isNode ? elem[jQuery.expando] : jQuery.expando;
  7319. // If there is already no cache entry for this object, there is no
  7320. // purpose in continuing
  7321. if (!cache[id]) {
  7322. return;
  7323. }
  7324. if (name) {
  7325. thisCache = pvt ? cache[id] : cache[id].data;
  7326. if (thisCache) {
  7327. // Support array or space separated string names for data keys
  7328. if (!jQuery.isArray(name)) {
  7329. // try the string as a key before any manipulation
  7330. if (name in thisCache) {
  7331. name = [name];
  7332. } else {
  7333. // split the camel cased version by spaces unless a key with the spaces exists
  7334. name = jQuery.camelCase(name);
  7335. if (name in thisCache) {
  7336. name = [name];
  7337. } else {
  7338. name = name.split(" ");
  7339. }
  7340. }
  7341. } else {
  7342. // If "name" is an array of keys...
  7343. // When data is initially created, via ("key", "val") signature,
  7344. // keys will be converted to camelCase.
  7345. // Since there is no way to tell _how_ a key was added, remove
  7346. // both plain key and camelCase key. #12786
  7347. // This will only penalize the array argument path.
  7348. name = name.concat(jQuery.map(name, jQuery.camelCase));
  7349. }
  7350. i = name.length;
  7351. while (i--) {
  7352. delete thisCache[name[i]];
  7353. }
  7354. // If there is no data left in the cache, we want to continue
  7355. // and let the cache object itself get destroyed
  7356. if (pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache)) {
  7357. return;
  7358. }
  7359. }
  7360. }
  7361. // See jQuery.data for more information
  7362. if (!pvt) {
  7363. delete cache[id].data;
  7364. // Don't destroy the parent cache unless the internal data object
  7365. // had been the only thing left in it
  7366. if (!isEmptyDataObject(cache[id])) {
  7367. return;
  7368. }
  7369. }
  7370. // Destroy the cache
  7371. if (isNode) {
  7372. jQuery.cleanData([elem], true);
  7373. // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
  7374. /* jshint eqeqeq: false */
  7375. } else if (support.deleteExpando || cache != cache.window) {
  7376. /* jshint eqeqeq: true */
  7377. delete cache[id];
  7378. // When all else fails, null
  7379. } else {
  7380. cache[id] = null;
  7381. }
  7382. }
  7383. jQuery.extend({
  7384. cache: {},
  7385. // The following elements (space-suffixed to avoid Object.prototype collisions)
  7386. // throw uncatchable exceptions if you attempt to set expando properties
  7387. noData: {
  7388. "applet ": true,
  7389. "embed ": true,
  7390. // ...but Flash objects (which have this classid) *can* handle expandos
  7391. "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
  7392. },
  7393. hasData: function (elem) {
  7394. elem = elem.nodeType ? jQuery.cache[elem[jQuery.expando]] : elem[jQuery.expando];
  7395. return !!elem && !isEmptyDataObject(elem);
  7396. },
  7397. data: function (elem, name, data) {
  7398. return internalData(elem, name, data);
  7399. },
  7400. removeData: function (elem, name) {
  7401. return internalRemoveData(elem, name);
  7402. },
  7403. // For internal use only.
  7404. _data: function (elem, name, data) {
  7405. return internalData(elem, name, data, true);
  7406. },
  7407. _removeData: function (elem, name) {
  7408. return internalRemoveData(elem, name, true);
  7409. }
  7410. });
  7411. jQuery.fn.extend({
  7412. data: function (key, value) {
  7413. var i,
  7414. name,
  7415. data,
  7416. elem = this[0],
  7417. attrs = elem && elem.attributes;
  7418. // Special expections of .data basically thwart jQuery.access,
  7419. // so implement the relevant behavior ourselves
  7420. // Gets all values
  7421. if (key === undefined) {
  7422. if (this.length) {
  7423. data = jQuery.data(elem);
  7424. if (elem.nodeType === 1 && !jQuery._data(elem, "parsedAttrs")) {
  7425. i = attrs.length;
  7426. while (i--) {
  7427. // Support: IE11+
  7428. // The attrs elements can be null (#14894)
  7429. if (attrs[i]) {
  7430. name = attrs[i].name;
  7431. if (name.indexOf("data-") === 0) {
  7432. name = jQuery.camelCase(name.slice(5));
  7433. dataAttr(elem, name, data[name]);
  7434. }
  7435. }
  7436. }
  7437. jQuery._data(elem, "parsedAttrs", true);
  7438. }
  7439. }
  7440. return data;
  7441. }
  7442. // Sets multiple values
  7443. if (typeof key === "object") {
  7444. return this.each(function () {
  7445. jQuery.data(this, key);
  7446. });
  7447. }
  7448. return arguments.length > 1 ?
  7449. // Sets one value
  7450. this.each(function () {
  7451. jQuery.data(this, key, value);
  7452. }) :
  7453. // Gets one value
  7454. // Try to fetch any internally stored data first
  7455. elem ? dataAttr(elem, key, jQuery.data(elem, key)) : undefined;
  7456. },
  7457. removeData: function (key) {
  7458. return this.each(function () {
  7459. jQuery.removeData(this, key);
  7460. });
  7461. }
  7462. });
  7463. jQuery.extend({
  7464. queue: function (elem, type, data) {
  7465. var queue;
  7466. if (elem) {
  7467. type = (type || "fx") + "queue";
  7468. queue = jQuery._data(elem, type);
  7469. // Speed up dequeue by getting out quickly if this is just a lookup
  7470. if (data) {
  7471. if (!queue || jQuery.isArray(data)) {
  7472. queue = jQuery._data(elem, type, jQuery.makeArray(data));
  7473. } else {
  7474. queue.push(data);
  7475. }
  7476. }
  7477. return queue || [];
  7478. }
  7479. },
  7480. dequeue: function (elem, type) {
  7481. type = type || "fx";
  7482. var queue = jQuery.queue(elem, type),
  7483. startLength = queue.length,
  7484. fn = queue.shift(),
  7485. hooks = jQuery._queueHooks(elem, type),
  7486. next = function () {
  7487. jQuery.dequeue(elem, type);
  7488. };
  7489. // If the fx queue is dequeued, always remove the progress sentinel
  7490. if (fn === "inprogress") {
  7491. fn = queue.shift();
  7492. startLength--;
  7493. }
  7494. if (fn) {
  7495. // Add a progress sentinel to prevent the fx queue from being
  7496. // automatically dequeued
  7497. if (type === "fx") {
  7498. queue.unshift("inprogress");
  7499. }
  7500. // clear up the last queue stop function
  7501. delete hooks.stop;
  7502. fn.call(elem, next, hooks);
  7503. }
  7504. if (!startLength && hooks) {
  7505. hooks.empty.fire();
  7506. }
  7507. },
  7508. // not intended for public consumption - generates a queueHooks object, or returns the current one
  7509. _queueHooks: function (elem, type) {
  7510. var key = type + "queueHooks";
  7511. return jQuery._data(elem, key) || jQuery._data(elem, key, {
  7512. empty: jQuery.Callbacks("once memory").add(function () {
  7513. jQuery._removeData(elem, type + "queue");
  7514. jQuery._removeData(elem, key);
  7515. })
  7516. });
  7517. }
  7518. });
  7519. jQuery.fn.extend({
  7520. queue: function (type, data) {
  7521. var setter = 2;
  7522. if (typeof type !== "string") {
  7523. data = type;
  7524. type = "fx";
  7525. setter--;
  7526. }
  7527. if (arguments.length < setter) {
  7528. return jQuery.queue(this[0], type);
  7529. }
  7530. return data === undefined ? this : this.each(function () {
  7531. var queue = jQuery.queue(this, type, data);
  7532. // ensure a hooks for this queue
  7533. jQuery._queueHooks(this, type);
  7534. if (type === "fx" && queue[0] !== "inprogress") {
  7535. jQuery.dequeue(this, type);
  7536. }
  7537. });
  7538. },
  7539. dequeue: function (type) {
  7540. return this.each(function () {
  7541. jQuery.dequeue(this, type);
  7542. });
  7543. },
  7544. clearQueue: function (type) {
  7545. return this.queue(type || "fx", []);
  7546. },
  7547. // Get a promise resolved when queues of a certain type
  7548. // are emptied (fx is the type by default)
  7549. promise: function (type, obj) {
  7550. var tmp,
  7551. count = 1,
  7552. defer = jQuery.Deferred(),
  7553. elements = this,
  7554. i = this.length,
  7555. resolve = function () {
  7556. if (! --count) {
  7557. defer.resolveWith(elements, [elements]);
  7558. }
  7559. };
  7560. if (typeof type !== "string") {
  7561. obj = type;
  7562. type = undefined;
  7563. }
  7564. type = type || "fx";
  7565. while (i--) {
  7566. tmp = jQuery._data(elements[i], type + "queueHooks");
  7567. if (tmp && tmp.empty) {
  7568. count++;
  7569. tmp.empty.add(resolve);
  7570. }
  7571. }
  7572. resolve();
  7573. return defer.promise(obj);
  7574. }
  7575. });
  7576. /*
  7577. * Helper functions for managing events -- not part of the public interface.
  7578. * Props to Dean Edwards' addEvent library for many of the ideas.
  7579. */
  7580. jQuery.event = {
  7581. global: {},
  7582. add: function (elem, types, handler, data, selector) {
  7583. var tmp,
  7584. events,
  7585. t,
  7586. handleObjIn,
  7587. special,
  7588. eventHandle,
  7589. handleObj,
  7590. handlers,
  7591. type,
  7592. namespaces,
  7593. origType,
  7594. elemData = jQuery._data(elem);
  7595. // Don't attach events to noData or text/comment nodes (but allow plain objects)
  7596. if (!elemData) {
  7597. return;
  7598. }
  7599. // Caller can pass in an object of custom data in lieu of the handler
  7600. if (handler.handler) {
  7601. handleObjIn = handler;
  7602. handler = handleObjIn.handler;
  7603. selector = handleObjIn.selector;
  7604. }
  7605. // Make sure that the handler has a unique ID, used to find/remove it later
  7606. if (!handler.guid) {
  7607. handler.guid = jQuery.guid++;
  7608. }
  7609. // Init the element's event structure and main handler, if this is the first
  7610. if (!(events = elemData.events)) {
  7611. events = elemData.events = {};
  7612. }
  7613. if (!(eventHandle = elemData.handle)) {
  7614. eventHandle = elemData.handle = function (e) {
  7615. // Discard the second event of a jQuery.event.trigger() and
  7616. // when an event is called after a page has unloaded
  7617. return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch.apply(eventHandle.elem, arguments) : undefined;
  7618. };
  7619. // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
  7620. eventHandle.elem = elem;
  7621. }
  7622. // Handle multiple events separated by a space
  7623. types = (types || "").match(rnotwhite) || [""];
  7624. t = types.length;
  7625. while (t--) {
  7626. tmp = rtypenamespace.exec(types[t]) || [];
  7627. type = origType = tmp[1];
  7628. namespaces = (tmp[2] || "").split(".").sort();
  7629. // There *must* be a type, no attaching namespace-only handlers
  7630. if (!type) {
  7631. continue;
  7632. }
  7633. // If event changes its type, use the special event handlers for the changed type
  7634. special = jQuery.event.special[type] || {};
  7635. // If selector defined, determine special event api type, otherwise given type
  7636. type = (selector ? special.delegateType : special.bindType) || type;
  7637. // Update special based on newly reset type
  7638. special = jQuery.event.special[type] || {};
  7639. // handleObj is passed to all event handlers
  7640. handleObj = jQuery.extend({
  7641. type: type,
  7642. origType: origType,
  7643. data: data,
  7644. handler: handler,
  7645. guid: handler.guid,
  7646. selector: selector,
  7647. needsContext: selector && jQuery.expr.match.needsContext.test(selector),
  7648. namespace: namespaces.join(".")
  7649. }, handleObjIn);
  7650. // Init the event handler queue if we're the first
  7651. if (!(handlers = events[type])) {
  7652. handlers = events[type] = [];
  7653. handlers.delegateCount = 0;
  7654. // Only use addEventListener/attachEvent if the special events handler returns false
  7655. if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {
  7656. // Bind the global event handler to the element
  7657. if (elem.addEventListener) {
  7658. elem.addEventListener(type, eventHandle, false);
  7659. } else if (elem.attachEvent) {
  7660. elem.attachEvent("on" + type, eventHandle);
  7661. }
  7662. }
  7663. }
  7664. if (special.add) {
  7665. special.add.call(elem, handleObj);
  7666. if (!handleObj.handler.guid) {
  7667. handleObj.handler.guid = handler.guid;
  7668. }
  7669. }
  7670. // Add to the element's handler list, delegates in front
  7671. if (selector) {
  7672. handlers.splice(handlers.delegateCount++, 0, handleObj);
  7673. } else {
  7674. handlers.push(handleObj);
  7675. }
  7676. // Keep track of which events have ever been used, for event optimization
  7677. jQuery.event.global[type] = true;
  7678. }
  7679. // Nullify elem to prevent memory leaks in IE
  7680. elem = null;
  7681. },
  7682. // Detach an event or set of events from an element
  7683. remove: function (elem, types, handler, selector, mappedTypes) {
  7684. var j,
  7685. handleObj,
  7686. tmp,
  7687. origCount,
  7688. t,
  7689. events,
  7690. special,
  7691. handlers,
  7692. type,
  7693. namespaces,
  7694. origType,
  7695. elemData = jQuery.hasData(elem) && jQuery._data(elem);
  7696. if (!elemData || !(events = elemData.events)) {
  7697. return;
  7698. }
  7699. // Once for each type.namespace in types; type may be omitted
  7700. types = (types || "").match(rnotwhite) || [""];
  7701. t = types.length;
  7702. while (t--) {
  7703. tmp = rtypenamespace.exec(types[t]) || [];
  7704. type = origType = tmp[1];
  7705. namespaces = (tmp[2] || "").split(".").sort();
  7706. // Unbind all events (on this namespace, if provided) for the element
  7707. if (!type) {
  7708. for (type in events) {
  7709. jQuery.event.remove(elem, type + types[t], handler, selector, true);
  7710. }
  7711. continue;
  7712. }
  7713. special = jQuery.event.special[type] || {};
  7714. type = (selector ? special.delegateType : special.bindType) || type;
  7715. handlers = events[type] || [];
  7716. tmp = tmp[2] && new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)");
  7717. // Remove matching events
  7718. origCount = j = handlers.length;
  7719. while (j--) {
  7720. handleObj = handlers[j];
  7721. if ((mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || selector === "**" && handleObj.selector)) {
  7722. handlers.splice(j, 1);
  7723. if (handleObj.selector) {
  7724. handlers.delegateCount--;
  7725. }
  7726. if (special.remove) {
  7727. special.remove.call(elem, handleObj);
  7728. }
  7729. }
  7730. }
  7731. // Remove generic event handler if we removed something and no more handlers exist
  7732. // (avoids potential for endless recursion during removal of special event handlers)
  7733. if (origCount && !handlers.length) {
  7734. if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) {
  7735. jQuery.removeEvent(elem, type, elemData.handle);
  7736. }
  7737. delete events[type];
  7738. }
  7739. }
  7740. // Remove the expando if it's no longer used
  7741. if (jQuery.isEmptyObject(events)) {
  7742. delete elemData.handle;
  7743. // removeData also checks for emptiness and clears the expando if empty
  7744. // so use it instead of delete
  7745. jQuery._removeData(elem, "events");
  7746. }
  7747. },
  7748. trigger: function (event, data, elem, onlyHandlers) {
  7749. var handle,
  7750. ontype,
  7751. cur,
  7752. bubbleType,
  7753. special,
  7754. tmp,
  7755. i,
  7756. eventPath = [elem || document],
  7757. type = hasOwn.call(event, "type") ? event.type : event,
  7758. namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : [];
  7759. cur = tmp = elem = elem || document;
  7760. // Don't do events on text and comment nodes
  7761. if (elem.nodeType === 3 || elem.nodeType === 8) {
  7762. return;
  7763. }
  7764. // focus/blur morphs to focusin/out; ensure we're not firing them right now
  7765. if (rfocusMorph.test(type + jQuery.event.triggered)) {
  7766. return;
  7767. }
  7768. if (type.indexOf(".") >= 0) {
  7769. // Namespaced trigger; create a regexp to match event type in handle()
  7770. namespaces = type.split(".");
  7771. type = namespaces.shift();
  7772. namespaces.sort();
  7773. }
  7774. ontype = type.indexOf(":") < 0 && "on" + type;
  7775. // Caller can pass in a jQuery.Event object, Object, or just an event type string
  7776. event = event[jQuery.expando] ? event : new jQuery.Event(type, typeof event === "object" && event);
  7777. // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
  7778. event.isTrigger = onlyHandlers ? 2 : 3;
  7779. event.namespace = namespaces.join(".");
  7780. event.namespace_re = event.namespace ? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null;
  7781. // Clean up the event in case it is being reused
  7782. event.result = undefined;
  7783. if (!event.target) {
  7784. event.target = elem;
  7785. }
  7786. // Clone any incoming data and prepend the event, creating the handler arg list
  7787. data = data == null ? [event] : jQuery.makeArray(data, [event]);
  7788. // Allow special events to draw outside the lines
  7789. special = jQuery.event.special[type] || {};
  7790. if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {
  7791. return;
  7792. }
  7793. // Determine event propagation path in advance, per W3C events spec (#9951)
  7794. // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
  7795. if (!onlyHandlers && !special.noBubble && !jQuery.isWindow(elem)) {
  7796. bubbleType = special.delegateType || type;
  7797. if (!rfocusMorph.test(bubbleType + type)) {
  7798. cur = cur.parentNode;
  7799. }
  7800. for (; cur; cur = cur.parentNode) {
  7801. eventPath.push(cur);
  7802. tmp = cur;
  7803. }
  7804. // Only add window if we got to document (e.g., not plain obj or detached DOM)
  7805. if (tmp === (elem.ownerDocument || document)) {
  7806. eventPath.push(tmp.defaultView || tmp.parentWindow || window);
  7807. }
  7808. }
  7809. // Fire handlers on the event path
  7810. i = 0;
  7811. while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {
  7812. event.type = i > 1 ? bubbleType : special.bindType || type;
  7813. // jQuery handler
  7814. handle = (jQuery._data(cur, "events") || {})[event.type] && jQuery._data(cur, "handle");
  7815. if (handle) {
  7816. handle.apply(cur, data);
  7817. }
  7818. // Native handler
  7819. handle = ontype && cur[ontype];
  7820. if (handle && handle.apply && jQuery.acceptData(cur)) {
  7821. event.result = handle.apply(cur, data);
  7822. if (event.result === false) {
  7823. event.preventDefault();
  7824. }
  7825. }
  7826. }
  7827. event.type = type;
  7828. // If nobody prevented the default action, do it now
  7829. if (!onlyHandlers && !event.isDefaultPrevented()) {
  7830. if ((!special._default || special._default.apply(eventPath.pop(), data) === false) && jQuery.acceptData(elem)) {
  7831. // Call a native DOM method on the target with the same name name as the event.
  7832. // Can't use an .isFunction() check here because IE6/7 fails that test.
  7833. // Don't do default actions on window, that's where global variables be (#6170)
  7834. if (ontype && elem[type] && !jQuery.isWindow(elem)) {
  7835. // Don't re-trigger an onFOO event when we call its FOO() method
  7836. tmp = elem[ontype];
  7837. if (tmp) {
  7838. elem[ontype] = null;
  7839. }
  7840. // Prevent re-triggering of the same event, since we already bubbled it above
  7841. jQuery.event.triggered = type;
  7842. try {
  7843. elem[type]();
  7844. } catch (e) {
  7845. // IE<9 dies on focus/blur to hidden element (#1486,#12518)
  7846. // only reproducible on winXP IE8 native, not IE9 in IE8 mode
  7847. }
  7848. jQuery.event.triggered = undefined;
  7849. if (tmp) {
  7850. elem[ontype] = tmp;
  7851. }
  7852. }
  7853. }
  7854. }
  7855. return event.result;
  7856. },
  7857. dispatch: function (event) {
  7858. // Make a writable jQuery.Event from the native event object
  7859. event = jQuery.event.fix(event);
  7860. var i,
  7861. ret,
  7862. handleObj,
  7863. matched,
  7864. j,
  7865. handlerQueue = [],
  7866. args = slice.call(arguments),
  7867. handlers = (jQuery._data(this, "events") || {})[event.type] || [],
  7868. special = jQuery.event.special[event.type] || {};
  7869. // Use the fix-ed jQuery.Event rather than the (read-only) native event
  7870. args[0] = event;
  7871. event.delegateTarget = this;
  7872. // Call the preDispatch hook for the mapped type, and let it bail if desired
  7873. if (special.preDispatch && special.preDispatch.call(this, event) === false) {
  7874. return;
  7875. }
  7876. // Determine handlers
  7877. handlerQueue = jQuery.event.handlers.call(this, event, handlers);
  7878. // Run delegates first; they may want to stop propagation beneath us
  7879. i = 0;
  7880. while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {
  7881. event.currentTarget = matched.elem;
  7882. j = 0;
  7883. while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) {
  7884. // Triggered event must either 1) have no namespace, or
  7885. // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
  7886. if (!event.namespace_re || event.namespace_re.test(handleObj.namespace)) {
  7887. event.handleObj = handleObj;
  7888. event.data = handleObj.data;
  7889. ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply(matched.elem, args);
  7890. if (ret !== undefined) {
  7891. if ((event.result = ret) === false) {
  7892. event.preventDefault();
  7893. event.stopPropagation();
  7894. }
  7895. }
  7896. }
  7897. }
  7898. }
  7899. // Call the postDispatch hook for the mapped type
  7900. if (special.postDispatch) {
  7901. special.postDispatch.call(this, event);
  7902. }
  7903. return event.result;
  7904. },
  7905. handlers: function (event, handlers) {
  7906. var sel,
  7907. handleObj,
  7908. matches,
  7909. i,
  7910. handlerQueue = [],
  7911. delegateCount = handlers.delegateCount,
  7912. cur = event.target;
  7913. // Find delegate handlers
  7914. // Black-hole SVG <use> instance trees (#13180)
  7915. // Avoid non-left-click bubbling in Firefox (#3861)
  7916. if (delegateCount && cur.nodeType && (!event.button || event.type !== "click")) {
  7917. /* jshint eqeqeq: false */
  7918. for (; cur != this; cur = cur.parentNode || this) {
  7919. /* jshint eqeqeq: true */
  7920. // Don't check non-elements (#13208)
  7921. // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
  7922. if (cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click")) {
  7923. matches = [];
  7924. for (i = 0; i < delegateCount; i++) {
  7925. handleObj = handlers[i];
  7926. // Don't conflict with Object.prototype properties (#13203)
  7927. sel = handleObj.selector + " ";
  7928. if (matches[sel] === undefined) {
  7929. matches[sel] = handleObj.needsContext ? jQuery(sel, this).index(cur) >= 0 : jQuery.find(sel, this, null, [cur]).length;
  7930. }
  7931. if (matches[sel]) {
  7932. matches.push(handleObj);
  7933. }
  7934. }
  7935. if (matches.length) {
  7936. handlerQueue.push({ elem: cur, handlers: matches });
  7937. }
  7938. }
  7939. }
  7940. }
  7941. // Add the remaining (directly-bound) handlers
  7942. if (delegateCount < handlers.length) {
  7943. handlerQueue.push({ elem: this, handlers: handlers.slice(delegateCount) });
  7944. }
  7945. return handlerQueue;
  7946. },
  7947. fix: function (event) {
  7948. if (event[jQuery.expando]) {
  7949. return event;
  7950. }
  7951. // Create a writable copy of the event object and normalize some properties
  7952. var i,
  7953. prop,
  7954. copy,
  7955. type = event.type,
  7956. originalEvent = event,
  7957. fixHook = this.fixHooks[type];
  7958. if (!fixHook) {
  7959. this.fixHooks[type] = fixHook = rmouseEvent.test(type) ? this.mouseHooks : rkeyEvent.test(type) ? this.keyHooks : {};
  7960. }
  7961. copy = fixHook.props ? this.props.concat(fixHook.props) : this.props;
  7962. event = new jQuery.Event(originalEvent);
  7963. i = copy.length;
  7964. while (i--) {
  7965. prop = copy[i];
  7966. event[prop] = originalEvent[prop];
  7967. }
  7968. // Support: IE<9
  7969. // Fix target property (#1925)
  7970. if (!event.target) {
  7971. event.target = originalEvent.srcElement || document;
  7972. }
  7973. // Support: Chrome 23+, Safari?
  7974. // Target should not be a text node (#504, #13143)
  7975. if (event.target.nodeType === 3) {
  7976. event.target = event.target.parentNode;
  7977. }
  7978. // Support: IE<9
  7979. // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
  7980. event.metaKey = !!event.metaKey;
  7981. return fixHook.filter ? fixHook.filter(event, originalEvent) : event;
  7982. },
  7983. // Includes some event props shared by KeyEvent and MouseEvent
  7984. props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
  7985. fixHooks: {},
  7986. keyHooks: {
  7987. props: "char charCode key keyCode".split(" "),
  7988. filter: function (event, original) {
  7989. // Add which for key events
  7990. if (event.which == null) {
  7991. event.which = original.charCode != null ? original.charCode : original.keyCode;
  7992. }
  7993. return event;
  7994. }
  7995. },
  7996. mouseHooks: {
  7997. props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
  7998. filter: function (event, original) {
  7999. var body,
  8000. eventDoc,
  8001. doc,
  8002. button = original.button,
  8003. fromElement = original.fromElement;
  8004. // Calculate pageX/Y if missing and clientX/Y available
  8005. if (event.pageX == null && original.clientX != null) {
  8006. eventDoc = event.target.ownerDocument || document;
  8007. doc = eventDoc.documentElement;
  8008. body = eventDoc.body;
  8009. event.pageX = original.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
  8010. event.pageY = original.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
  8011. }
  8012. // Add relatedTarget, if necessary
  8013. if (!event.relatedTarget && fromElement) {
  8014. event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
  8015. }
  8016. // Add which for click: 1 === left; 2 === middle; 3 === right
  8017. // Note: button is not normalized, so don't use it
  8018. if (!event.which && button !== undefined) {
  8019. event.which = button & 1 ? 1 : button & 2 ? 3 : button & 4 ? 2 : 0;
  8020. }
  8021. return event;
  8022. }
  8023. },
  8024. special: {
  8025. load: {
  8026. // Prevent triggered image.load events from bubbling to window.load
  8027. noBubble: true
  8028. },
  8029. focus: {
  8030. // Fire native event if possible so blur/focus sequence is correct
  8031. trigger: function () {
  8032. if (this !== safeActiveElement() && this.focus) {
  8033. try {
  8034. this.focus();
  8035. return false;
  8036. } catch (e) {
  8037. // Support: IE<9
  8038. // If we error on focus to hidden element (#1486, #12518),
  8039. // let .trigger() run the handlers
  8040. }
  8041. }
  8042. },
  8043. delegateType: "focusin"
  8044. },
  8045. blur: {
  8046. trigger: function () {
  8047. if (this === safeActiveElement() && this.blur) {
  8048. this.blur();
  8049. return false;
  8050. }
  8051. },
  8052. delegateType: "focusout"
  8053. },
  8054. click: {
  8055. // For checkbox, fire native event so checked state will be right
  8056. trigger: function () {
  8057. if (jQuery.nodeName(this, "input") && this.type === "checkbox" && this.click) {
  8058. this.click();
  8059. return false;
  8060. }
  8061. },
  8062. // For cross-browser consistency, don't fire native .click() on links
  8063. _default: function (event) {
  8064. return jQuery.nodeName(event.target, "a");
  8065. }
  8066. },
  8067. beforeunload: {
  8068. postDispatch: function (event) {
  8069. // Support: Firefox 20+
  8070. // Firefox doesn't alert if the returnValue field is not set.
  8071. if (event.result !== undefined && event.originalEvent) {
  8072. event.originalEvent.returnValue = event.result;
  8073. }
  8074. }
  8075. }
  8076. },
  8077. simulate: function (type, elem, event, bubble) {
  8078. // Piggyback on a donor event to simulate a different one.
  8079. // Fake originalEvent to avoid donor's stopPropagation, but if the
  8080. // simulated event prevents default then we do the same on the donor.
  8081. var e = jQuery.extend(new jQuery.Event(), event, {
  8082. type: type,
  8083. isSimulated: true,
  8084. originalEvent: {}
  8085. });
  8086. if (bubble) {
  8087. jQuery.event.trigger(e, null, elem);
  8088. } else {
  8089. jQuery.event.dispatch.call(elem, e);
  8090. }
  8091. if (e.isDefaultPrevented()) {
  8092. event.preventDefault();
  8093. }
  8094. }
  8095. };
  8096. jQuery.removeEvent = document.removeEventListener ? function (elem, type, handle) {
  8097. if (elem.removeEventListener) {
  8098. elem.removeEventListener(type, handle, false);
  8099. }
  8100. } : function (elem, type, handle) {
  8101. var name = "on" + type;
  8102. if (elem.detachEvent) {
  8103. // #8545, #7054, preventing memory leaks for custom events in IE6-8
  8104. // detachEvent needed property on element, by name of that event, to properly expose it to GC
  8105. if (typeof elem[name] === strundefined) {
  8106. elem[name] = null;
  8107. }
  8108. elem.detachEvent(name, handle);
  8109. }
  8110. };
  8111. jQuery.Event = function (src, props) {
  8112. // Allow instantiation without the 'new' keyword
  8113. if (!(this instanceof jQuery.Event)) {
  8114. return new jQuery.Event(src, props);
  8115. }
  8116. // Event object
  8117. if (src && src.type) {
  8118. this.originalEvent = src;
  8119. this.type = src.type;
  8120. // Events bubbling up the document may have been marked as prevented
  8121. // by a handler lower down the tree; reflect the correct value.
  8122. this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined &&
  8123. // Support: IE < 9, Android < 4.0
  8124. src.returnValue === false ? returnTrue : returnFalse;
  8125. // Event type
  8126. } else {
  8127. this.type = src;
  8128. }
  8129. // Put explicitly provided properties onto the event object
  8130. if (props) {
  8131. jQuery.extend(this, props);
  8132. }
  8133. // Create a timestamp if incoming event doesn't have one
  8134. this.timeStamp = src && src.timeStamp || jQuery.now();
  8135. // Mark it as fixed
  8136. this[jQuery.expando] = true;
  8137. };
  8138. var rformElems = /^(?:input|select|textarea)$/i,
  8139. rkeyEvent = /^key/,
  8140. rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
  8141. rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
  8142. rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
  8143. function returnTrue() {
  8144. return true;
  8145. }
  8146. function returnFalse() {
  8147. return false;
  8148. }
  8149. // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
  8150. // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
  8151. jQuery.Event.prototype = {
  8152. isDefaultPrevented: returnFalse,
  8153. isPropagationStopped: returnFalse,
  8154. isImmediatePropagationStopped: returnFalse,
  8155. preventDefault: function () {
  8156. var e = this.originalEvent;
  8157. this.isDefaultPrevented = returnTrue;
  8158. if (!e) {
  8159. return;
  8160. }
  8161. // If preventDefault exists, run it on the original event
  8162. if (e.preventDefault) {
  8163. e.preventDefault();
  8164. // Support: IE
  8165. // Otherwise set the returnValue property of the original event to false
  8166. } else {
  8167. e.returnValue = false;
  8168. }
  8169. },
  8170. stopPropagation: function () {
  8171. var e = this.originalEvent;
  8172. this.isPropagationStopped = returnTrue;
  8173. if (!e) {
  8174. return;
  8175. }
  8176. // If stopPropagation exists, run it on the original event
  8177. if (e.stopPropagation) {
  8178. e.stopPropagation();
  8179. }
  8180. // Support: IE
  8181. // Set the cancelBubble property of the original event to true
  8182. e.cancelBubble = true;
  8183. },
  8184. stopImmediatePropagation: function () {
  8185. var e = this.originalEvent;
  8186. this.isImmediatePropagationStopped = returnTrue;
  8187. if (e && e.stopImmediatePropagation) {
  8188. e.stopImmediatePropagation();
  8189. }
  8190. this.stopPropagation();
  8191. }
  8192. };
  8193. // IE submit delegation
  8194. if (!support.submitBubbles) {
  8195. jQuery.event.special.submit = {
  8196. setup: function () {
  8197. // Only need this for delegated form submit events
  8198. if (jQuery.nodeName(this, "form")) {
  8199. return false;
  8200. }
  8201. // Lazy-add a submit handler when a descendant form may potentially be submitted
  8202. jQuery.event.add(this, "click._submit keypress._submit", function (e) {
  8203. // Node name check avoids a VML-related crash in IE (#9807)
  8204. var elem = e.target,
  8205. form = jQuery.nodeName(elem, "input") || jQuery.nodeName(elem, "button") ? elem.form : undefined;
  8206. if (form && !jQuery._data(form, "submitBubbles")) {
  8207. jQuery.event.add(form, "submit._submit", function (event) {
  8208. event._submit_bubble = true;
  8209. });
  8210. jQuery._data(form, "submitBubbles", true);
  8211. }
  8212. });
  8213. // return undefined since we don't need an event listener
  8214. },
  8215. postDispatch: function (event) {
  8216. // If form was submitted by the user, bubble the event up the tree
  8217. if (event._submit_bubble) {
  8218. delete event._submit_bubble;
  8219. if (this.parentNode && !event.isTrigger) {
  8220. jQuery.event.simulate("submit", this.parentNode, event, true);
  8221. }
  8222. }
  8223. },
  8224. teardown: function () {
  8225. // Only need this for delegated form submit events
  8226. if (jQuery.nodeName(this, "form")) {
  8227. return false;
  8228. }
  8229. // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
  8230. jQuery.event.remove(this, "._submit");
  8231. }
  8232. };
  8233. }
  8234. // IE change delegation and checkbox/radio fix
  8235. if (!support.changeBubbles) {
  8236. jQuery.event.special.change = {
  8237. setup: function () {
  8238. if (rformElems.test(this.nodeName)) {
  8239. // IE doesn't fire change on a check/radio until blur; trigger it on click
  8240. // after a propertychange. Eat the blur-change in special.change.handle.
  8241. // This still fires onchange a second time for check/radio after blur.
  8242. if (this.type === "checkbox" || this.type === "radio") {
  8243. jQuery.event.add(this, "propertychange._change", function (event) {
  8244. if (event.originalEvent.propertyName === "checked") {
  8245. this._just_changed = true;
  8246. }
  8247. });
  8248. jQuery.event.add(this, "click._change", function (event) {
  8249. if (this._just_changed && !event.isTrigger) {
  8250. this._just_changed = false;
  8251. }
  8252. // Allow triggered, simulated change events (#11500)
  8253. jQuery.event.simulate("change", this, event, true);
  8254. });
  8255. }
  8256. return false;
  8257. }
  8258. // Delegated event; lazy-add a change handler on descendant inputs
  8259. jQuery.event.add(this, "beforeactivate._change", function (e) {
  8260. var elem = e.target;
  8261. if (rformElems.test(elem.nodeName) && !jQuery._data(elem, "changeBubbles")) {
  8262. jQuery.event.add(elem, "change._change", function (event) {
  8263. if (this.parentNode && !event.isSimulated && !event.isTrigger) {
  8264. jQuery.event.simulate("change", this.parentNode, event, true);
  8265. }
  8266. });
  8267. jQuery._data(elem, "changeBubbles", true);
  8268. }
  8269. });
  8270. },
  8271. handle: function (event) {
  8272. var elem = event.target;
  8273. // Swallow native change events from checkbox/radio, we already triggered them above
  8274. if (this !== elem || event.isSimulated || event.isTrigger || elem.type !== "radio" && elem.type !== "checkbox") {
  8275. return event.handleObj.handler.apply(this, arguments);
  8276. }
  8277. },
  8278. teardown: function () {
  8279. jQuery.event.remove(this, "._change");
  8280. return !rformElems.test(this.nodeName);
  8281. }
  8282. };
  8283. }
  8284. // Create "bubbling" focus and blur events
  8285. if (!support.focusinBubbles) {
  8286. jQuery.each({ focus: "focusin", blur: "focusout" }, function (orig, fix) {
  8287. // Attach a single capturing handler on the document while someone wants focusin/focusout
  8288. var handler = function (event) {
  8289. jQuery.event.simulate(fix, event.target, jQuery.event.fix(event), true);
  8290. };
  8291. jQuery.event.special[fix] = {
  8292. setup: function () {
  8293. var doc = this.ownerDocument || this,
  8294. attaches = jQuery._data(doc, fix);
  8295. if (!attaches) {
  8296. doc.addEventListener(orig, handler, true);
  8297. }
  8298. jQuery._data(doc, fix, (attaches || 0) + 1);
  8299. },
  8300. teardown: function () {
  8301. var doc = this.ownerDocument || this,
  8302. attaches = jQuery._data(doc, fix) - 1;
  8303. if (!attaches) {
  8304. doc.removeEventListener(orig, handler, true);
  8305. jQuery._removeData(doc, fix);
  8306. } else {
  8307. jQuery._data(doc, fix, attaches);
  8308. }
  8309. }
  8310. };
  8311. });
  8312. }
  8313. jQuery.fn.extend({
  8314. on: function (types, selector, data, fn, /*INTERNAL*/one) {
  8315. var type, origFn;
  8316. // Types can be a map of types/handlers
  8317. if (typeof types === "object") {
  8318. // ( types-Object, selector, data )
  8319. if (typeof selector !== "string") {
  8320. // ( types-Object, data )
  8321. data = data || selector;
  8322. selector = undefined;
  8323. }
  8324. for (type in types) {
  8325. this.on(type, selector, data, types[type], one);
  8326. }
  8327. return this;
  8328. }
  8329. if (data == null && fn == null) {
  8330. // ( types, fn )
  8331. fn = selector;
  8332. data = selector = undefined;
  8333. } else if (fn == null) {
  8334. if (typeof selector === "string") {
  8335. // ( types, selector, fn )
  8336. fn = data;
  8337. data = undefined;
  8338. } else {
  8339. // ( types, data, fn )
  8340. fn = data;
  8341. data = selector;
  8342. selector = undefined;
  8343. }
  8344. }
  8345. if (fn === false) {
  8346. fn = returnFalse;
  8347. } else if (!fn) {
  8348. return this;
  8349. }
  8350. if (one === 1) {
  8351. origFn = fn;
  8352. fn = function (event) {
  8353. // Can use an empty set, since event contains the info
  8354. jQuery().off(event);
  8355. return origFn.apply(this, arguments);
  8356. };
  8357. // Use same guid so caller can remove using origFn
  8358. fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
  8359. }
  8360. return this.each(function () {
  8361. jQuery.event.add(this, types, fn, data, selector);
  8362. });
  8363. },
  8364. one: function (types, selector, data, fn) {
  8365. return this.on(types, selector, data, fn, 1);
  8366. },
  8367. off: function (types, selector, fn) {
  8368. var handleObj, type;
  8369. if (types && types.preventDefault && types.handleObj) {
  8370. // ( event ) dispatched jQuery.Event
  8371. handleObj = types.handleObj;
  8372. jQuery(types.delegateTarget).off(handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler);
  8373. return this;
  8374. }
  8375. if (typeof types === "object") {
  8376. // ( types-object [, selector] )
  8377. for (type in types) {
  8378. this.off(type, selector, types[type]);
  8379. }
  8380. return this;
  8381. }
  8382. if (selector === false || typeof selector === "function") {
  8383. // ( types [, fn] )
  8384. fn = selector;
  8385. selector = undefined;
  8386. }
  8387. if (fn === false) {
  8388. fn = returnFalse;
  8389. }
  8390. return this.each(function () {
  8391. jQuery.event.remove(this, types, fn, selector);
  8392. });
  8393. },
  8394. trigger: function (type, data) {
  8395. return this.each(function () {
  8396. jQuery.event.trigger(type, data, this);
  8397. });
  8398. },
  8399. triggerHandler: function (type, data) {
  8400. var elem = this[0];
  8401. if (elem) {
  8402. return jQuery.event.trigger(type, data, elem, true);
  8403. }
  8404. }
  8405. });
  8406. // Based off of the plugin by Clint Helfers, with permission.
  8407. // http://blindsignals.com/index.php/2009/07/jquery-delay/
  8408. jQuery.fn.delay = function (time, type) {
  8409. time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
  8410. type = type || "fx";
  8411. return this.queue(type, function (next, hooks) {
  8412. var timeout = setTimeout(next, time);
  8413. hooks.stop = function () {
  8414. clearTimeout(timeout);
  8415. };
  8416. });
  8417. };
  8418. var nonce = jQuery.now();
  8419. var rquery = /\?/;
  8420. var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
  8421. jQuery.parseJSON = function (data) {
  8422. // Attempt to parse using the native JSON parser first
  8423. if (window.JSON && window.JSON.parse) {
  8424. // Support: Android 2.3
  8425. // Workaround failure to string-cast null input
  8426. return window.JSON.parse(data + "");
  8427. }
  8428. var requireNonComma,
  8429. depth = null,
  8430. str = jQuery.trim(data + "");
  8431. // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
  8432. // after removing valid tokens
  8433. return str && !jQuery.trim(str.replace(rvalidtokens, function (token, comma, open, close) {
  8434. // Force termination if we see a misplaced comma
  8435. if (requireNonComma && comma) {
  8436. depth = 0;
  8437. }
  8438. // Perform no more replacements after returning to outermost depth
  8439. if (depth === 0) {
  8440. return token;
  8441. }
  8442. // Commas must not follow "[", "{", or ","
  8443. requireNonComma = open || comma;
  8444. // Determine new depth
  8445. // array/object open ("[" or "{"): depth += true - false (increment)
  8446. // array/object close ("]" or "}"): depth += false - true (decrement)
  8447. // other cases ("," or primitive): depth += true - true (numeric cast)
  8448. depth += !close - !open;
  8449. // Remove this token
  8450. return "";
  8451. })) ? Function("return " + str)() : jQuery.error("Invalid JSON: " + data);
  8452. };
  8453. // Cross-browser xml parsing
  8454. jQuery.parseXML = function (data) {
  8455. var xml, tmp;
  8456. if (!data || typeof data !== "string") {
  8457. return null;
  8458. }
  8459. try {
  8460. if (window.DOMParser) {
  8461. // Standard
  8462. tmp = new DOMParser();
  8463. xml = tmp.parseFromString(data, "text/xml");
  8464. } else {
  8465. // IE
  8466. xml = new ActiveXObject("Microsoft.XMLDOM");
  8467. xml.async = "false";
  8468. xml.loadXML(data);
  8469. }
  8470. } catch (e) {
  8471. xml = undefined;
  8472. }
  8473. if (!xml || !xml.documentElement || xml.getElementsByTagName("parsererror").length) {
  8474. jQuery.error("Invalid XML: " + data);
  8475. }
  8476. return xml;
  8477. };
  8478. var
  8479. // Document location
  8480. ajaxLocParts,
  8481. ajaxLocation,
  8482. rhash = /#.*$/,
  8483. rts = /([?&])_=[^&]*/,
  8484. rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg,
  8485. // IE leaves an \r character at EOL
  8486. // #7653, #8125, #8152: local protocol detection
  8487. rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
  8488. rnoContent = /^(?:GET|HEAD)$/,
  8489. rprotocol = /^\/\//,
  8490. rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
  8491. /* Prefilters
  8492. * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
  8493. * 2) These are called:
  8494. * - BEFORE asking for a transport
  8495. * - AFTER param serialization (s.data is a string if s.processData is true)
  8496. * 3) key is the dataType
  8497. * 4) the catchall symbol "*" can be used
  8498. * 5) execution will start with transport dataType and THEN continue down to "*" if needed
  8499. */
  8500. prefilters = {},
  8501. /* Transports bindings
  8502. * 1) key is the dataType
  8503. * 2) the catchall symbol "*" can be used
  8504. * 3) selection will start with transport dataType and THEN go to "*" if needed
  8505. */
  8506. transports = {},
  8507. // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
  8508. allTypes = "*/".concat("*");
  8509. // #8138, IE may throw an exception when accessing
  8510. // a field from window.location if document.domain has been set
  8511. try {
  8512. ajaxLocation = location.href;
  8513. } catch (e) {
  8514. // Use the href attribute of an A element
  8515. // since IE will modify it given document.location
  8516. ajaxLocation = document.createElement("a");
  8517. ajaxLocation.href = "";
  8518. ajaxLocation = ajaxLocation.href;
  8519. }
  8520. // Segment location into parts
  8521. ajaxLocParts = rurl.exec(ajaxLocation.toLowerCase()) || [];
  8522. // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
  8523. function addToPrefiltersOrTransports(structure) {
  8524. // dataTypeExpression is optional and defaults to "*"
  8525. return function (dataTypeExpression, func) {
  8526. if (typeof dataTypeExpression !== "string") {
  8527. func = dataTypeExpression;
  8528. dataTypeExpression = "*";
  8529. }
  8530. var dataType,
  8531. i = 0,
  8532. dataTypes = dataTypeExpression.toLowerCase().match(rnotwhite) || [];
  8533. if (jQuery.isFunction(func)) {
  8534. // For each dataType in the dataTypeExpression
  8535. while (dataType = dataTypes[i++]) {
  8536. // Prepend if requested
  8537. if (dataType.charAt(0) === "+") {
  8538. dataType = dataType.slice(1) || "*";
  8539. (structure[dataType] = structure[dataType] || []).unshift(func);
  8540. // Otherwise append
  8541. } else {
  8542. (structure[dataType] = structure[dataType] || []).push(func);
  8543. }
  8544. }
  8545. }
  8546. };
  8547. }
  8548. // Base inspection function for prefilters and transports
  8549. function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) {
  8550. var inspected = {},
  8551. seekingTransport = structure === transports;
  8552. function inspect(dataType) {
  8553. var selected;
  8554. inspected[dataType] = true;
  8555. jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) {
  8556. var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR);
  8557. if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) {
  8558. options.dataTypes.unshift(dataTypeOrTransport);
  8559. inspect(dataTypeOrTransport);
  8560. return false;
  8561. } else if (seekingTransport) {
  8562. return !(selected = dataTypeOrTransport);
  8563. }
  8564. });
  8565. return selected;
  8566. }
  8567. return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*");
  8568. }
  8569. // A special extend for ajax options
  8570. // that takes "flat" options (not to be deep extended)
  8571. // Fixes #9887
  8572. function ajaxExtend(target, src) {
  8573. var deep,
  8574. key,
  8575. flatOptions = jQuery.ajaxSettings.flatOptions || {};
  8576. for (key in src) {
  8577. if (src[key] !== undefined) {
  8578. (flatOptions[key] ? target : deep || (deep = {}))[key] = src[key];
  8579. }
  8580. }
  8581. if (deep) {
  8582. jQuery.extend(true, target, deep);
  8583. }
  8584. return target;
  8585. }
  8586. /* Handles responses to an ajax request:
  8587. * - finds the right dataType (mediates between content-type and expected dataType)
  8588. * - returns the corresponding response
  8589. */
  8590. function ajaxHandleResponses(s, jqXHR, responses) {
  8591. var firstDataType,
  8592. ct,
  8593. finalDataType,
  8594. type,
  8595. contents = s.contents,
  8596. dataTypes = s.dataTypes;
  8597. // Remove auto dataType and get content-type in the process
  8598. while (dataTypes[0] === "*") {
  8599. dataTypes.shift();
  8600. if (ct === undefined) {
  8601. ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
  8602. }
  8603. }
  8604. // Check if we're dealing with a known content-type
  8605. if (ct) {
  8606. for (type in contents) {
  8607. if (contents[type] && contents[type].test(ct)) {
  8608. dataTypes.unshift(type);
  8609. break;
  8610. }
  8611. }
  8612. }
  8613. // Check to see if we have a response for the expected dataType
  8614. if (dataTypes[0] in responses) {
  8615. finalDataType = dataTypes[0];
  8616. } else {
  8617. // Try convertible dataTypes
  8618. for (type in responses) {
  8619. if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) {
  8620. finalDataType = type;
  8621. break;
  8622. }
  8623. if (!firstDataType) {
  8624. firstDataType = type;
  8625. }
  8626. }
  8627. // Or just use first one
  8628. finalDataType = finalDataType || firstDataType;
  8629. }
  8630. // If we found a dataType
  8631. // We add the dataType to the list if needed
  8632. // and return the corresponding response
  8633. if (finalDataType) {
  8634. if (finalDataType !== dataTypes[0]) {
  8635. dataTypes.unshift(finalDataType);
  8636. }
  8637. return responses[finalDataType];
  8638. }
  8639. }
  8640. /* Chain conversions given the request and the original response
  8641. * Also sets the responseXXX fields on the jqXHR instance
  8642. */
  8643. function ajaxConvert(s, response, jqXHR, isSuccess) {
  8644. var conv2,
  8645. current,
  8646. conv,
  8647. tmp,
  8648. prev,
  8649. converters = {},
  8650. // Work with a copy of dataTypes in case we need to modify it for conversion
  8651. dataTypes = s.dataTypes.slice();
  8652. // Create converters map with lowercased keys
  8653. if (dataTypes[1]) {
  8654. for (conv in s.converters) {
  8655. converters[conv.toLowerCase()] = s.converters[conv];
  8656. }
  8657. }
  8658. current = dataTypes.shift();
  8659. // Convert to each sequential dataType
  8660. while (current) {
  8661. if (s.responseFields[current]) {
  8662. jqXHR[s.responseFields[current]] = response;
  8663. }
  8664. // Apply the dataFilter if provided
  8665. if (!prev && isSuccess && s.dataFilter) {
  8666. response = s.dataFilter(response, s.dataType);
  8667. }
  8668. prev = current;
  8669. current = dataTypes.shift();
  8670. if (current) {
  8671. // There's only work to do if current dataType is non-auto
  8672. if (current === "*") {
  8673. current = prev;
  8674. // Convert response if prev dataType is non-auto and differs from current
  8675. } else if (prev !== "*" && prev !== current) {
  8676. // Seek a direct converter
  8677. conv = converters[prev + " " + current] || converters["* " + current];
  8678. // If none found, seek a pair
  8679. if (!conv) {
  8680. for (conv2 in converters) {
  8681. // If conv2 outputs current
  8682. tmp = conv2.split(" ");
  8683. if (tmp[1] === current) {
  8684. // If prev can be converted to accepted input
  8685. conv = converters[prev + " " + tmp[0]] || converters["* " + tmp[0]];
  8686. if (conv) {
  8687. // Condense equivalence converters
  8688. if (conv === true) {
  8689. conv = converters[conv2];
  8690. // Otherwise, insert the intermediate dataType
  8691. } else if (converters[conv2] !== true) {
  8692. current = tmp[0];
  8693. dataTypes.unshift(tmp[1]);
  8694. }
  8695. break;
  8696. }
  8697. }
  8698. }
  8699. }
  8700. // Apply converter (if not an equivalence)
  8701. if (conv !== true) {
  8702. // Unless errors are allowed to bubble, catch and return them
  8703. if (conv && s["throws"]) {
  8704. response = conv(response);
  8705. } else {
  8706. try {
  8707. response = conv(response);
  8708. } catch (e) {
  8709. return {
  8710. state: "parsererror",
  8711. error: conv ? e : "No conversion from " + prev + " to " + current
  8712. };
  8713. }
  8714. }
  8715. }
  8716. }
  8717. }
  8718. }
  8719. return { state: "success", data: response };
  8720. }
  8721. jQuery.extend({
  8722. // Counter for holding the number of active queries
  8723. active: 0,
  8724. // Last-Modified header cache for next request
  8725. lastModified: {},
  8726. etag: {},
  8727. ajaxSettings: {
  8728. url: ajaxLocation,
  8729. type: "GET",
  8730. isLocal: rlocalProtocol.test(ajaxLocParts[1]),
  8731. global: true,
  8732. processData: true,
  8733. async: true,
  8734. contentType: "application/x-www-form-urlencoded; charset=UTF-8",
  8735. /*
  8736. timeout: 0,
  8737. data: null,
  8738. dataType: null,
  8739. username: null,
  8740. password: null,
  8741. cache: null,
  8742. throws: false,
  8743. traditional: false,
  8744. headers: {},
  8745. */
  8746. accepts: {
  8747. "*": allTypes,
  8748. text: "text/plain",
  8749. html: "text/html",
  8750. xml: "application/xml, text/xml",
  8751. json: "application/json, text/javascript"
  8752. },
  8753. contents: {
  8754. xml: /xml/,
  8755. html: /html/,
  8756. json: /json/
  8757. },
  8758. responseFields: {
  8759. xml: "responseXML",
  8760. text: "responseText",
  8761. json: "responseJSON"
  8762. },
  8763. // Data converters
  8764. // Keys separate source (or catchall "*") and destination types with a single space
  8765. converters: {
  8766. // Convert anything to text
  8767. "* text": String,
  8768. // Text to html (true = no transformation)
  8769. "text html": true,
  8770. // Evaluate text as a json expression
  8771. "text json": jQuery.parseJSON,
  8772. // Parse text as xml
  8773. "text xml": jQuery.parseXML
  8774. },
  8775. // For options that shouldn't be deep extended:
  8776. // you can add your own custom options here if
  8777. // and when you create one that shouldn't be
  8778. // deep extended (see ajaxExtend)
  8779. flatOptions: {
  8780. url: true,
  8781. context: true
  8782. }
  8783. },
  8784. // Creates a full fledged settings object into target
  8785. // with both ajaxSettings and settings fields.
  8786. // If target is omitted, writes into ajaxSettings.
  8787. ajaxSetup: function (target, settings) {
  8788. return settings ?
  8789. // Building a settings object
  8790. ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) :
  8791. // Extending ajaxSettings
  8792. ajaxExtend(jQuery.ajaxSettings, target);
  8793. },
  8794. ajaxPrefilter: addToPrefiltersOrTransports(prefilters),
  8795. ajaxTransport: addToPrefiltersOrTransports(transports),
  8796. // Main method
  8797. ajax: function (url, options) {
  8798. // If url is an object, simulate pre-1.5 signature
  8799. if (typeof url === "object") {
  8800. options = url;
  8801. url = undefined;
  8802. }
  8803. // Force options to be an object
  8804. options = options || {};
  8805. var // Cross-domain detection vars
  8806. parts,
  8807. // Loop variable
  8808. i,
  8809. // URL without anti-cache param
  8810. cacheURL,
  8811. // Response headers as string
  8812. responseHeadersString,
  8813. // timeout handle
  8814. timeoutTimer,
  8815. // To know if global events are to be dispatched
  8816. fireGlobals,
  8817. transport,
  8818. // Response headers
  8819. responseHeaders,
  8820. // Create the final options object
  8821. s = jQuery.ajaxSetup({}, options),
  8822. // Callbacks context
  8823. callbackContext = s.context || s,
  8824. // Context for global events is callbackContext if it is a DOM node or jQuery collection
  8825. globalEventContext = s.context && (callbackContext.nodeType || callbackContext.jquery) ? jQuery(callbackContext) : jQuery.event,
  8826. // Deferreds
  8827. deferred = jQuery.Deferred(),
  8828. completeDeferred = jQuery.Callbacks("once memory"),
  8829. // Status-dependent callbacks
  8830. statusCode = s.statusCode || {},
  8831. // Headers (they are sent all at once)
  8832. requestHeaders = {},
  8833. requestHeadersNames = {},
  8834. // The jqXHR state
  8835. state = 0,
  8836. // Default abort message
  8837. strAbort = "canceled",
  8838. // Fake xhr
  8839. jqXHR = {
  8840. readyState: 0,
  8841. // Builds headers hashtable if needed
  8842. getResponseHeader: function (key) {
  8843. var match;
  8844. if (state === 2) {
  8845. if (!responseHeaders) {
  8846. responseHeaders = {};
  8847. while (match = rheaders.exec(responseHeadersString)) {
  8848. responseHeaders[match[1].toLowerCase()] = match[2];
  8849. }
  8850. }
  8851. match = responseHeaders[key.toLowerCase()];
  8852. }
  8853. return match == null ? null : match;
  8854. },
  8855. // Raw string
  8856. getAllResponseHeaders: function () {
  8857. return state === 2 ? responseHeadersString : null;
  8858. },
  8859. // Caches the header
  8860. setRequestHeader: function (name, value) {
  8861. var lname = name.toLowerCase();
  8862. if (!state) {
  8863. name = requestHeadersNames[lname] = requestHeadersNames[lname] || name;
  8864. requestHeaders[name] = value;
  8865. }
  8866. return this;
  8867. },
  8868. // Overrides response content-type header
  8869. overrideMimeType: function (type) {
  8870. if (!state) {
  8871. s.mimeType = type;
  8872. }
  8873. return this;
  8874. },
  8875. // Status-dependent callbacks
  8876. statusCode: function (map) {
  8877. var code;
  8878. if (map) {
  8879. if (state < 2) {
  8880. for (code in map) {
  8881. // Lazy-add the new callback in a way that preserves old ones
  8882. statusCode[code] = [statusCode[code], map[code]];
  8883. }
  8884. } else {
  8885. // Execute the appropriate callbacks
  8886. jqXHR.always(map[jqXHR.status]);
  8887. }
  8888. }
  8889. return this;
  8890. },
  8891. // Cancel the request
  8892. abort: function (statusText) {
  8893. var finalText = statusText || strAbort;
  8894. if (transport) {
  8895. transport.abort(finalText);
  8896. }
  8897. done(0, finalText);
  8898. return this;
  8899. }
  8900. };
  8901. // Attach deferreds
  8902. deferred.promise(jqXHR).complete = completeDeferred.add;
  8903. jqXHR.success = jqXHR.done;
  8904. jqXHR.error = jqXHR.fail;
  8905. // Remove hash character (#7531: and string promotion)
  8906. // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
  8907. // Handle falsy url in the settings object (#10093: consistency with old signature)
  8908. // We also use the url parameter if available
  8909. s.url = ((url || s.url || ajaxLocation) + "").replace(rhash, "").replace(rprotocol, ajaxLocParts[1] + "//");
  8910. // Alias method option to type as per ticket #12004
  8911. s.type = options.method || options.type || s.method || s.type;
  8912. // Extract dataTypes list
  8913. s.dataTypes = jQuery.trim(s.dataType || "*").toLowerCase().match(rnotwhite) || [""];
  8914. // A cross-domain request is in order when we have a protocol:host:port mismatch
  8915. if (s.crossDomain == null) {
  8916. parts = rurl.exec(s.url.toLowerCase());
  8917. s.crossDomain = !!(parts && (parts[1] !== ajaxLocParts[1] || parts[2] !== ajaxLocParts[2] || (parts[3] || (parts[1] === "http:" ? "80" : "443")) !== (ajaxLocParts[3] || (ajaxLocParts[1] === "http:" ? "80" : "443"))));
  8918. }
  8919. // Convert data if not already a string
  8920. if (s.data && s.processData && typeof s.data !== "string") {
  8921. s.data = jQuery.param(s.data, s.traditional);
  8922. }
  8923. // Apply prefilters
  8924. inspectPrefiltersOrTransports(prefilters, s, options, jqXHR);
  8925. // If request was aborted inside a prefilter, stop there
  8926. if (state === 2) {
  8927. return jqXHR;
  8928. }
  8929. // We can fire global events as of now if asked to
  8930. fireGlobals = s.global;
  8931. // Watch for a new set of requests
  8932. if (fireGlobals && jQuery.active++ === 0) {
  8933. jQuery.event.trigger("ajaxStart");
  8934. }
  8935. // Uppercase the type
  8936. s.type = s.type.toUpperCase();
  8937. // Determine if request has content
  8938. s.hasContent = !rnoContent.test(s.type);
  8939. // Save the URL in case we're toying with the If-Modified-Since
  8940. // and/or If-None-Match header later on
  8941. cacheURL = s.url;
  8942. // More options handling for requests with no content
  8943. if (!s.hasContent) {
  8944. // If data is available, append data to url
  8945. if (s.data) {
  8946. cacheURL = s.url += (rquery.test(cacheURL) ? "&" : "?") + s.data;
  8947. // #9682: remove data so that it's not used in an eventual retry
  8948. delete s.data;
  8949. }
  8950. // Add anti-cache in url if needed
  8951. if (s.cache === false) {
  8952. s.url = rts.test(cacheURL) ?
  8953. // If there is already a '_' parameter, set its value
  8954. cacheURL.replace(rts, "$1_=" + nonce++) :
  8955. // Otherwise add one to the end
  8956. cacheURL + (rquery.test(cacheURL) ? "&" : "?") + "_=" + nonce++;
  8957. }
  8958. }
  8959. // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  8960. if (s.ifModified) {
  8961. if (jQuery.lastModified[cacheURL]) {
  8962. jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL]);
  8963. }
  8964. if (jQuery.etag[cacheURL]) {
  8965. jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL]);
  8966. }
  8967. }
  8968. // Set the correct header, if data is being sent
  8969. if (s.data && s.hasContent && s.contentType !== false || options.contentType) {
  8970. jqXHR.setRequestHeader("Content-Type", s.contentType);
  8971. }
  8972. // Set the Accepts header for the server, depending on the dataType
  8973. // jqXHR.setRequestHeader(
  8974. // "Accept",
  8975. // s.dataTypes[0] && s.accepts[s.dataTypes[0]] ?
  8976. // s.accepts[s.dataTypes[0]] + ( s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
  8977. // s.accepts["*"]
  8978. // );
  8979. // Check for headers option
  8980. for (i in s.headers) {
  8981. jqXHR.setRequestHeader(i, s.headers[i]);
  8982. }
  8983. // Allow custom headers/mimetypes and early abort
  8984. if (s.beforeSend && (s.beforeSend.call(callbackContext, jqXHR, s) === false || state === 2)) {
  8985. // Abort if not done already and return
  8986. return jqXHR.abort();
  8987. }
  8988. // aborting is no longer a cancellation
  8989. strAbort = "abort";
  8990. // Install callbacks on deferreds
  8991. for (i in { success: 1, error: 1, complete: 1 }) {
  8992. jqXHR[i](s[i]);
  8993. }
  8994. // Get transport
  8995. transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR);
  8996. // If no transport, we auto-abort
  8997. if (!transport) {
  8998. done(-1, "No Transport");
  8999. } else {
  9000. jqXHR.readyState = 1;
  9001. // Send global event
  9002. if (fireGlobals) {
  9003. globalEventContext.trigger("ajaxSend", [jqXHR, s]);
  9004. }
  9005. // Timeout
  9006. if (s.async && s.timeout > 0) {
  9007. timeoutTimer = setTimeout(function () {
  9008. jqXHR.abort("timeout");
  9009. }, s.timeout);
  9010. }
  9011. try {
  9012. state = 1;
  9013. transport.send(requestHeaders, done);
  9014. } catch (e) {
  9015. // Propagate exception as error if not done
  9016. if (state < 2) {
  9017. done(-1, e);
  9018. // Simply rethrow otherwise
  9019. } else {
  9020. throw e;
  9021. }
  9022. }
  9023. }
  9024. // Callback for when everything is done
  9025. function done(status, nativeStatusText, responses, headers) {
  9026. var isSuccess,
  9027. success,
  9028. error,
  9029. response,
  9030. modified,
  9031. statusText = nativeStatusText;
  9032. // Called once
  9033. if (state === 2) {
  9034. return;
  9035. }
  9036. // State is "done" now
  9037. state = 2;
  9038. // Clear timeout if it exists
  9039. if (timeoutTimer) {
  9040. clearTimeout(timeoutTimer);
  9041. }
  9042. // Dereference transport for early garbage collection
  9043. // (no matter how long the jqXHR object will be used)
  9044. transport = undefined;
  9045. // Cache response headers
  9046. responseHeadersString = headers || "";
  9047. // Set readyState
  9048. jqXHR.readyState = status > 0 ? 4 : 0;
  9049. // Determine if successful
  9050. isSuccess = status >= 200 && status < 300 || status === 304;
  9051. // Get response data
  9052. if (responses) {
  9053. response = ajaxHandleResponses(s, jqXHR, responses);
  9054. }
  9055. // Convert no matter what (that way responseXXX fields are always set)
  9056. response = ajaxConvert(s, response, jqXHR, isSuccess);
  9057. // If successful, handle type chaining
  9058. if (isSuccess) {
  9059. // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  9060. if (s.ifModified) {
  9061. modified = jqXHR.getResponseHeader("Last-Modified");
  9062. if (modified) {
  9063. jQuery.lastModified[cacheURL] = modified;
  9064. }
  9065. modified = jqXHR.getResponseHeader("etag");
  9066. if (modified) {
  9067. jQuery.etag[cacheURL] = modified;
  9068. }
  9069. }
  9070. // if no content
  9071. if (status === 204 || s.type === "HEAD") {
  9072. statusText = "nocontent";
  9073. // if not modified
  9074. } else if (status === 304) {
  9075. statusText = "notmodified";
  9076. // If we have data, let's convert it
  9077. } else {
  9078. statusText = response.state;
  9079. success = response.data;
  9080. error = response.error;
  9081. isSuccess = !error;
  9082. }
  9083. } else {
  9084. // We extract error from statusText
  9085. // then normalize statusText and status for non-aborts
  9086. error = statusText;
  9087. if (status || !statusText) {
  9088. statusText = "error";
  9089. if (status < 0) {
  9090. status = 0;
  9091. }
  9092. }
  9093. }
  9094. // Set data for the fake xhr object
  9095. jqXHR.status = status;
  9096. jqXHR.statusText = (nativeStatusText || statusText) + "";
  9097. // Success/Error
  9098. if (isSuccess) {
  9099. deferred.resolveWith(callbackContext, [success, statusText, jqXHR]);
  9100. } else {
  9101. deferred.rejectWith(callbackContext, [jqXHR, statusText, error]);
  9102. }
  9103. // Status-dependent callbacks
  9104. jqXHR.statusCode(statusCode);
  9105. statusCode = undefined;
  9106. if (fireGlobals) {
  9107. globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError", [jqXHR, s, isSuccess ? success : error]);
  9108. }
  9109. // Complete
  9110. completeDeferred.fireWith(callbackContext, [jqXHR, statusText]);
  9111. if (fireGlobals) {
  9112. globalEventContext.trigger("ajaxComplete", [jqXHR, s]);
  9113. // Handle the global AJAX counter
  9114. if (! --jQuery.active) {
  9115. jQuery.event.trigger("ajaxStop");
  9116. }
  9117. }
  9118. }
  9119. return jqXHR;
  9120. },
  9121. getJSON: function (url, data, callback) {
  9122. return jQuery.get(url, data, callback, "json");
  9123. },
  9124. getScript: function (url, callback) {
  9125. return jQuery.get(url, undefined, callback, "script");
  9126. }
  9127. });
  9128. jQuery.each(["get", "post"], function (i, method) {
  9129. jQuery[method] = function (url, data, callback, type) {
  9130. // shift arguments if data argument was omitted
  9131. if (jQuery.isFunction(data)) {
  9132. type = type || callback;
  9133. callback = data;
  9134. data = undefined;
  9135. }
  9136. return jQuery.ajax({
  9137. url: url,
  9138. type: method,
  9139. dataType: type,
  9140. data: data,
  9141. success: callback
  9142. });
  9143. };
  9144. });
  9145. // Attach a bunch of functions for handling common AJAX events
  9146. jQuery.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function (i, type) {
  9147. jQuery.fn[type] = function (fn) {
  9148. return this.on(type, fn);
  9149. };
  9150. });
  9151. jQuery._evalUrl = function (url) {
  9152. return jQuery.ajax({
  9153. url: url,
  9154. type: "GET",
  9155. dataType: "script",
  9156. async: false,
  9157. global: false,
  9158. "throws": true
  9159. });
  9160. };
  9161. var r20 = /%20/g,
  9162. rbracket = /\[\]$/,
  9163. rCRLF = /\r?\n/g,
  9164. rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
  9165. rsubmittable = /^(?:input|select|textarea|keygen)/i;
  9166. function buildParams(prefix, obj, traditional, add) {
  9167. var name;
  9168. if (jQuery.isArray(obj)) {
  9169. // Serialize array item.
  9170. jQuery.each(obj, function (i, v) {
  9171. if (traditional || rbracket.test(prefix)) {
  9172. // Treat each array item as a scalar.
  9173. add(prefix, v);
  9174. } else {
  9175. // Item is non-scalar (array or object), encode its numeric index.
  9176. buildParams(prefix + "[" + (typeof v === "object" ? i : "") + "]", v, traditional, add);
  9177. }
  9178. });
  9179. } else if (!traditional && jQuery.type(obj) === "object") {
  9180. // Serialize object item.
  9181. for (name in obj) {
  9182. buildParams(prefix + "[" + name + "]", obj[name], traditional, add);
  9183. }
  9184. } else {
  9185. // Serialize scalar item.
  9186. add(prefix, obj);
  9187. }
  9188. }
  9189. // Serialize an array of form elements or a set of
  9190. // key/values into a query string
  9191. jQuery.param = function (a, traditional) {
  9192. var prefix,
  9193. s = [],
  9194. add = function (key, value) {
  9195. // If value is a function, invoke it and return its value
  9196. value = jQuery.isFunction(value) ? value() : value == null ? "" : value;
  9197. s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
  9198. };
  9199. // Set traditional to true for jQuery <= 1.3.2 behavior.
  9200. if (traditional === undefined) {
  9201. traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
  9202. }
  9203. // If an array was passed in, assume that it is an array of form elements.
  9204. if (jQuery.isArray(a) || a.jquery && !jQuery.isPlainObject(a)) {
  9205. // Serialize the form elements
  9206. jQuery.each(a, function () {
  9207. add(this.name, this.value);
  9208. });
  9209. } else {
  9210. // If traditional, encode the "old" way (the way 1.3.2 or older
  9211. // did it), otherwise encode params recursively.
  9212. for (prefix in a) {
  9213. buildParams(prefix, a[prefix], traditional, add);
  9214. }
  9215. }
  9216. // Return the resulting serialization
  9217. return s.join("&").replace(r20, "+");
  9218. };
  9219. jQuery.fn.extend({
  9220. serialize: function () {
  9221. return jQuery.param(this.serializeArray());
  9222. },
  9223. serializeArray: function () {
  9224. return this.map(function () {
  9225. // Can add propHook for "elements" to filter or add form elements
  9226. var elements = jQuery.prop(this, "elements");
  9227. return elements ? jQuery.makeArray(elements) : this;
  9228. }).filter(function () {
  9229. var type = this.type;
  9230. // Use .is(":disabled") so that fieldset[disabled] works
  9231. return this.name && !jQuery(this).is(":disabled") && rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && (this.checked || !rcheckableType.test(type));
  9232. }).map(function (i, elem) {
  9233. var val = jQuery(this).val();
  9234. return val == null ? null : jQuery.isArray(val) ? jQuery.map(val, function (val) {
  9235. return { name: elem.name, value: val.replace(rCRLF, "\r\n") };
  9236. }) : { name: elem.name, value: val.replace(rCRLF, "\r\n") };
  9237. }).get();
  9238. }
  9239. });
  9240. // Create the request object
  9241. // (This is still attached to ajaxSettings for backward compatibility)
  9242. jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
  9243. // Support: IE6+
  9244. function () {
  9245. // XHR cannot access local files, always use ActiveX for that case
  9246. return !this.isLocal &&
  9247. // Support: IE7-8
  9248. // oldIE XHR does not support non-RFC2616 methods (#13240)
  9249. // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
  9250. // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
  9251. // Although this check for six methods instead of eight
  9252. // since IE also does not support "trace" and "connect"
  9253. /^(get|post|head|put|delete|options)$/i.test(this.type) && createStandardXHR() || createActiveXHR();
  9254. } :
  9255. // For all other browsers, use the standard XMLHttpRequest object
  9256. createStandardXHR;
  9257. var xhrId = 0,
  9258. xhrCallbacks = {},
  9259. xhrSupported = jQuery.ajaxSettings.xhr();
  9260. // Support: IE<10
  9261. // Open requests must be manually aborted on unload (#5280)
  9262. if (window.ActiveXObject) {
  9263. jQuery(window).on("unload", function () {
  9264. for (var key in xhrCallbacks) {
  9265. xhrCallbacks[key](undefined, true);
  9266. }
  9267. });
  9268. }
  9269. // Determine support properties
  9270. support.cors = !!xhrSupported && "withCredentials" in xhrSupported;
  9271. xhrSupported = support.ajax = !!xhrSupported;
  9272. // Create transport if the browser can provide an xhr
  9273. if (xhrSupported) {
  9274. jQuery.ajaxTransport(function (options) {
  9275. // Cross domain only allowed if supported through XMLHttpRequest
  9276. if (!options.crossDomain || support.cors) {
  9277. var callback;
  9278. return {
  9279. send: function (headers, complete) {
  9280. var i,
  9281. xhr = options.xhr(),
  9282. id = ++xhrId;
  9283. // Open the socket
  9284. xhr.open(options.type, options.url, options.async, options.username, options.password);
  9285. // Apply custom fields if provided
  9286. if (options.xhrFields) {
  9287. for (i in options.xhrFields) {
  9288. xhr[i] = options.xhrFields[i];
  9289. }
  9290. }
  9291. // Override mime type if needed
  9292. if (options.mimeType && xhr.overrideMimeType) {
  9293. xhr.overrideMimeType(options.mimeType);
  9294. }
  9295. // X-Requested-With header
  9296. // For cross-domain requests, seeing as conditions for a preflight are
  9297. // akin to a jigsaw puzzle, we simply never set it to be sure.
  9298. // (it can always be set on a per-request basis or even using ajaxSetup)
  9299. // For same-domain requests, won't change header if already provided.
  9300. if (!options.crossDomain && !headers["X-Requested-With"]) {
  9301. headers["X-Requested-With"] = "XMLHttpRequest";
  9302. }
  9303. // Set headers
  9304. for (i in headers) {
  9305. // Support: IE<9
  9306. // IE's ActiveXObject throws a 'Type Mismatch' exception when setting
  9307. // request header to a null-value.
  9308. //
  9309. // To keep consistent with other XHR implementations, cast the value
  9310. // to string and ignore `undefined`.
  9311. if (headers[i] !== undefined) {
  9312. xhr.setRequestHeader(i, headers[i] + "");
  9313. }
  9314. }
  9315. if (xhr.upload && options.progress) {
  9316. xhr.upload.onprogress = options.progress;
  9317. }
  9318. // Do send the request
  9319. // This may raise an exception which is actually
  9320. // handled in jQuery.ajax (so no try/catch here)
  9321. xhr.send(options.hasContent && (options.body || options.data) || null);
  9322. // Listener
  9323. callback = function (_, isAbort) {
  9324. var status, statusText, responses;
  9325. // Was never called and is aborted or complete
  9326. if (callback && (isAbort || xhr.readyState === 4)) {
  9327. // Clean up
  9328. delete xhrCallbacks[id];
  9329. callback = undefined;
  9330. xhr.onreadystatechange = jQuery.noop;
  9331. // Abort manually if needed
  9332. if (isAbort) {
  9333. if (xhr.readyState !== 4) {
  9334. xhr.abort();
  9335. }
  9336. } else {
  9337. responses = {};
  9338. status = xhr.status;
  9339. // Support: IE<10
  9340. // Accessing binary-data responseText throws an exception
  9341. // (#11426)
  9342. if (typeof xhr.responseText === "string") {
  9343. responses.text = xhr.responseText;
  9344. }
  9345. // Firefox throws an exception when accessing
  9346. // statusText for faulty cross-domain requests
  9347. try {
  9348. statusText = xhr.statusText;
  9349. } catch (e) {
  9350. // We normalize with Webkit giving an empty statusText
  9351. statusText = "";
  9352. }
  9353. // Filter status for non standard behaviors
  9354. // If the request is local and we have data: assume a success
  9355. // (success with no data won't get notified, that's the best we
  9356. // can do given current implementations)
  9357. if (!status && options.isLocal && !options.crossDomain) {
  9358. status = responses.text ? 200 : 404;
  9359. // IE - #1450: sometimes returns 1223 when it should be 204
  9360. } else if (status === 1223) {
  9361. status = 204;
  9362. }
  9363. }
  9364. }
  9365. // Call complete if needed
  9366. if (responses) {
  9367. complete(status, statusText, responses, xhr.getAllResponseHeaders());
  9368. }
  9369. };
  9370. if (!options.async) {
  9371. // if we're in sync mode we fire the callback
  9372. callback();
  9373. } else if (xhr.readyState === 4) {
  9374. // (IE6 & IE7) if it's in cache and has been
  9375. // retrieved directly we need to fire the callback
  9376. setTimeout(callback);
  9377. } else {
  9378. // Add to the list of active xhr callbacks
  9379. xhr.onreadystatechange = xhrCallbacks[id] = callback;
  9380. }
  9381. },
  9382. abort: function () {
  9383. if (callback) {
  9384. callback(undefined, true);
  9385. }
  9386. }
  9387. };
  9388. }
  9389. });
  9390. }
  9391. // Functions to create xhrs
  9392. function createStandardXHR() {
  9393. try {
  9394. return new window.XMLHttpRequest();
  9395. } catch (e) {}
  9396. }
  9397. function createActiveXHR() {
  9398. try {
  9399. return new window.ActiveXObject("Microsoft.XMLHTTP");
  9400. } catch (e) {}
  9401. }
  9402. // Install script dataType
  9403. jQuery.ajaxSetup({
  9404. accepts: {
  9405. script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
  9406. },
  9407. contents: {
  9408. script: /(?:java|ecma)script/
  9409. },
  9410. converters: {
  9411. "text script": function (text) {
  9412. jQuery.globalEval(text);
  9413. return text;
  9414. }
  9415. }
  9416. });
  9417. // Handle cache's special case and global
  9418. jQuery.ajaxPrefilter("script", function (s) {
  9419. if (s.cache === undefined) {
  9420. s.cache = false;
  9421. }
  9422. if (s.crossDomain) {
  9423. s.type = "GET";
  9424. s.global = false;
  9425. }
  9426. });
  9427. // Bind script tag hack transport
  9428. jQuery.ajaxTransport("script", function (s) {
  9429. // This transport only deals with cross domain requests
  9430. if (s.crossDomain) {
  9431. var script,
  9432. head = document.head || jQuery("head")[0] || document.documentElement;
  9433. return {
  9434. send: function (_, callback) {
  9435. script = document.createElement("script");
  9436. script.async = true;
  9437. if (s.scriptCharset) {
  9438. script.charset = s.scriptCharset;
  9439. }
  9440. script.src = s.url;
  9441. // Attach handlers for all browsers
  9442. script.onload = script.onreadystatechange = function (_, isAbort) {
  9443. if (isAbort || !script.readyState || /loaded|complete/.test(script.readyState)) {
  9444. // Handle memory leak in IE
  9445. script.onload = script.onreadystatechange = null;
  9446. // Remove the script
  9447. if (script.parentNode) {
  9448. script.parentNode.removeChild(script);
  9449. }
  9450. // Dereference the script
  9451. script = null;
  9452. // Callback if not abort
  9453. if (!isAbort) {
  9454. callback(200, "success");
  9455. }
  9456. }
  9457. };
  9458. // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
  9459. // Use native DOM manipulation to avoid our domManip AJAX trickery
  9460. head.insertBefore(script, head.firstChild);
  9461. },
  9462. abort: function () {
  9463. if (script) {
  9464. script.onload(undefined, true);
  9465. }
  9466. }
  9467. };
  9468. }
  9469. });
  9470. var oldCallbacks = [],
  9471. rjsonp = /(=)\?(?=&|$)|\?\?/;
  9472. // Default jsonp settings
  9473. jQuery.ajaxSetup({
  9474. jsonp: "callback",
  9475. jsonpCallback: function () {
  9476. var callback = oldCallbacks.pop() || jQuery.expando + "_" + nonce++;
  9477. this[callback] = true;
  9478. return callback;
  9479. }
  9480. });
  9481. // Detect, normalize options and install callbacks for jsonp requests
  9482. jQuery.ajaxPrefilter("json jsonp", function (s, originalSettings, jqXHR) {
  9483. var callbackName,
  9484. overwritten,
  9485. responseContainer,
  9486. jsonProp = s.jsonp !== false && (rjsonp.test(s.url) ? "url" : typeof s.data === "string" && !(s.contentType || "").indexOf("application/x-www-form-urlencoded") && rjsonp.test(s.data) && "data");
  9487. // Handle iff the expected data type is "jsonp" or we have a parameter to set
  9488. if (jsonProp || s.dataTypes[0] === "jsonp") {
  9489. // Get callback name, remembering preexisting value associated with it
  9490. callbackName = s.jsonpCallback = jQuery.isFunction(s.jsonpCallback) ? s.jsonpCallback() : s.jsonpCallback;
  9491. // Insert callback into url or form data
  9492. if (jsonProp) {
  9493. s[jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName);
  9494. } else if (s.jsonp !== false) {
  9495. s.url += (rquery.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName;
  9496. }
  9497. // Use data converter to retrieve json after script execution
  9498. s.converters["script json"] = function () {
  9499. if (!responseContainer) {
  9500. jQuery.error(callbackName + " was not called");
  9501. }
  9502. return responseContainer[0];
  9503. };
  9504. // force json dataType
  9505. s.dataTypes[0] = "json";
  9506. // Install callback
  9507. overwritten = window[callbackName];
  9508. window[callbackName] = function () {
  9509. responseContainer = arguments;
  9510. };
  9511. // Clean-up function (fires after converters)
  9512. jqXHR.always(function () {
  9513. // Restore preexisting value
  9514. window[callbackName] = overwritten;
  9515. // Save back as free
  9516. if (s[callbackName]) {
  9517. // make sure that re-using the options doesn't screw things around
  9518. s.jsonpCallback = originalSettings.jsonpCallback;
  9519. // save the callback name for future use
  9520. oldCallbacks.push(callbackName);
  9521. }
  9522. // Call if it was a function and we have a response
  9523. if (responseContainer && jQuery.isFunction(overwritten)) {
  9524. overwritten(responseContainer[0]);
  9525. }
  9526. responseContainer = overwritten = undefined;
  9527. });
  9528. // Delegate to script
  9529. return "script";
  9530. }
  9531. });
  9532. // data: string of html
  9533. // context (optional): If specified, the fragment will be created in this context, defaults to document
  9534. // keepScripts (optional): If true, will include scripts passed in the html string
  9535. jQuery.parseHTML = function (data, context, keepScripts) {
  9536. if (!data || typeof data !== "string") {
  9537. return null;
  9538. }
  9539. if (typeof context === "boolean") {
  9540. keepScripts = context;
  9541. context = false;
  9542. }
  9543. context = context || document;
  9544. var parsed = rsingleTag.exec(data),
  9545. scripts = !keepScripts && [];
  9546. // Single tag
  9547. if (parsed) {
  9548. return [context.createElement(parsed[1])];
  9549. }
  9550. parsed = jQuery.buildFragment([data], context, scripts);
  9551. if (scripts && scripts.length) {
  9552. jQuery(scripts).remove();
  9553. }
  9554. return jQuery.merge([], parsed.childNodes);
  9555. };
  9556. return jQuery;
  9557. }();
  9558. var stringifyPrimitive = function (v) {
  9559. switch (typeof v) {
  9560. case 'string':
  9561. return v;
  9562. case 'boolean':
  9563. return v ? 'true' : 'false';
  9564. case 'number':
  9565. return isFinite(v) ? v : '';
  9566. default:
  9567. return '';
  9568. }
  9569. };
  9570. var queryStringify = function (obj, sep, eq, name) {
  9571. sep = sep || '&';
  9572. eq = eq || '=';
  9573. if (obj === null) {
  9574. obj = undefined;
  9575. }
  9576. if (typeof obj === 'object') {
  9577. return Object.keys(obj).map(function (k) {
  9578. var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
  9579. if (Array.isArray(obj[k])) {
  9580. return obj[k].map(function (v) {
  9581. return ks + encodeURIComponent(stringifyPrimitive(v));
  9582. }).join(sep);
  9583. } else {
  9584. return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
  9585. }
  9586. }).filter(Boolean).join(sep);
  9587. }
  9588. if (!name) return '';
  9589. return encodeURIComponent(stringifyPrimitive(name)) + eq + encodeURIComponent(stringifyPrimitive(obj));
  9590. };
  9591. var request = function (options, callback) {
  9592. options = $.extend(true, { headers: {}, qs: {} }, options);
  9593. // method
  9594. options.type = options.method;
  9595. delete options.method;
  9596. // progress
  9597. if (options.onProgress) {
  9598. options.progress = options.onProgress;
  9599. delete options.onProgress;
  9600. }
  9601. // qs
  9602. if (options.qs) {
  9603. var qsStr = queryStringify(options.qs);
  9604. if (qsStr) {
  9605. options.url += (options.url.indexOf('?') === -1 ? '?' : '&') + qsStr;
  9606. }
  9607. delete options.qs;
  9608. }
  9609. // json
  9610. if (options.json) {
  9611. options.data = options.body;
  9612. delete options.json;
  9613. delete options.body;
  9614. !options.headers && (options.headers = {});
  9615. options.headers['Content-Type'] = 'application/json';
  9616. }
  9617. // body
  9618. if (options.body) {
  9619. if (!(options.body instanceof Blob || options.body.toString() === '[object File]' || options.body.toString() === '[object Blob]')) {
  9620. options.data = options.body;
  9621. delete options.body;
  9622. }
  9623. }
  9624. // headers
  9625. if (options.headers) {
  9626. var headers = options.headers;
  9627. delete options.headers;
  9628. options.beforeSend = function (xhr) {
  9629. for (var key in headers) {
  9630. if (headers.hasOwnProperty(key) && key.toLowerCase() !== 'content-length' && key.toLowerCase() !== 'user-agent' && key.toLowerCase() !== 'origin' && key.toLowerCase() !== 'host') {
  9631. xhr.setRequestHeader(key, headers[key]);
  9632. }
  9633. }
  9634. };
  9635. }
  9636. var getResponse = function (xhr) {
  9637. var headers = {};
  9638. xhr.getAllResponseHeaders().trim().split('\n').forEach(function (item) {
  9639. if (item) {
  9640. var index = item.indexOf(':');
  9641. var key = item.substr(0, index).trim().toLowerCase();
  9642. var val = item.substr(index + 1).trim();
  9643. headers[key] = val;
  9644. }
  9645. });
  9646. return {
  9647. statusCode: xhr.status,
  9648. statusMessage: xhr.statusText,
  9649. headers: headers
  9650. };
  9651. };
  9652. // callback
  9653. options.success = function (data, state, xhr) {
  9654. callback(null, getResponse(xhr), data);
  9655. };
  9656. options.error = function (xhr) {
  9657. if (xhr.responseText) {
  9658. callback(null, getResponse(xhr), xhr.responseText);
  9659. } else {
  9660. callback(xhr.statusText, getResponse(xhr), xhr.responseText);
  9661. }
  9662. };
  9663. options.dataType = 'text';
  9664. // send
  9665. return $.ajax(options);
  9666. };
  9667. module.exports = request;
  9668. /***/ }),
  9669. /* 15 */
  9670. /***/ (function(module, exports, __webpack_require__) {
  9671. var session = __webpack_require__(3);
  9672. var Async = __webpack_require__(16);
  9673. var EventProxy = __webpack_require__(2).EventProxy;
  9674. var util = __webpack_require__(0);
  9675. // 文件分块上传全过程,暴露的分块上传接口
  9676. function sliceUploadFile(params, callback) {
  9677. var self = this;
  9678. var ep = new EventProxy();
  9679. var TaskId = params.TaskId;
  9680. var Bucket = params.Bucket;
  9681. var Region = params.Region;
  9682. var Key = params.Key;
  9683. var Body = params.Body;
  9684. var ChunkSize = params.ChunkSize || params.SliceSize || self.options.ChunkSize;
  9685. var AsyncLimit = params.AsyncLimit;
  9686. var StorageClass = params.StorageClass || 'Standard';
  9687. var ServerSideEncryption = params.ServerSideEncryption;
  9688. var FileSize;
  9689. var onProgress;
  9690. var onHashProgress = params.onHashProgress;
  9691. // 上传过程中出现错误,返回错误
  9692. ep.on('error', function (err) {
  9693. if (!self._isRunningTask(TaskId)) return;
  9694. return callback(err);
  9695. });
  9696. // 上传分块完成,开始 uploadSliceComplete 操作
  9697. ep.on('upload_complete', function (UploadCompleteData) {
  9698. callback(null, UploadCompleteData);
  9699. });
  9700. // 上传分块完成,开始 uploadSliceComplete 操作
  9701. ep.on('upload_slice_complete', function (UploadData) {
  9702. uploadSliceComplete.call(self, {
  9703. Bucket: Bucket,
  9704. Region: Region,
  9705. Key: Key,
  9706. UploadId: UploadData.UploadId,
  9707. SliceList: UploadData.SliceList
  9708. }, function (err, data) {
  9709. if (!self._isRunningTask(TaskId)) return;
  9710. session.removeUsing(UploadData.UploadId);
  9711. if (err) {
  9712. onProgress(null, true);
  9713. return ep.emit('error', err);
  9714. }
  9715. session.removeUploadId(UploadData.UploadId);
  9716. onProgress({ loaded: FileSize, total: FileSize }, true);
  9717. ep.emit('upload_complete', data);
  9718. });
  9719. });
  9720. // 获取 UploadId 完成,开始上传每个分片
  9721. ep.on('get_upload_data_finish', function (UploadData) {
  9722. // 处理 UploadId 缓存
  9723. var uuid = session.getFileId(Body, params.ChunkSize, Bucket, Key);
  9724. uuid && session.saveUploadId(uuid, UploadData.UploadId, self.options.UploadIdCacheLimit); // 缓存 UploadId
  9725. session.setUsing(UploadData.UploadId); // 标记 UploadId 为正在使用
  9726. // 获取 UploadId
  9727. onProgress(null, true); // 任务状态开始 uploading
  9728. uploadSliceList.call(self, {
  9729. TaskId: TaskId,
  9730. Bucket: Bucket,
  9731. Region: Region,
  9732. Key: Key,
  9733. Body: Body,
  9734. FileSize: FileSize,
  9735. SliceSize: ChunkSize,
  9736. AsyncLimit: AsyncLimit,
  9737. ServerSideEncryption: ServerSideEncryption,
  9738. UploadData: UploadData,
  9739. onProgress: onProgress
  9740. }, function (err, data) {
  9741. if (!self._isRunningTask(TaskId)) return;
  9742. if (err) {
  9743. onProgress(null, true);
  9744. return ep.emit('error', err);
  9745. }
  9746. ep.emit('upload_slice_complete', data);
  9747. });
  9748. });
  9749. // 开始获取文件 UploadId,里面会视情况计算 ETag,并比对,保证文件一致性,也优化上传
  9750. ep.on('get_file_size_finish', function () {
  9751. onProgress = util.throttleOnProgress.call(self, FileSize, params.onProgress);
  9752. if (params.UploadData.UploadId) {
  9753. ep.emit('get_upload_data_finish', params.UploadData);
  9754. } else {
  9755. var _params = util.extend({
  9756. TaskId: TaskId,
  9757. Bucket: Bucket,
  9758. Region: Region,
  9759. Key: Key,
  9760. Headers: params.Headers,
  9761. StorageClass: StorageClass,
  9762. Body: Body,
  9763. FileSize: FileSize,
  9764. SliceSize: ChunkSize,
  9765. onHashProgress: onHashProgress
  9766. }, params);
  9767. getUploadIdAndPartList.call(self, _params, function (err, UploadData) {
  9768. if (!self._isRunningTask(TaskId)) return;
  9769. if (err) return ep.emit('error', err);
  9770. params.UploadData.UploadId = UploadData.UploadId;
  9771. params.UploadData.PartList = UploadData.PartList;
  9772. ep.emit('get_upload_data_finish', params.UploadData);
  9773. });
  9774. }
  9775. });
  9776. // 获取上传文件大小
  9777. FileSize = params.ContentLength;
  9778. delete params.ContentLength;
  9779. !params.Headers && (params.Headers = {});
  9780. util.each(params.Headers, function (item, key) {
  9781. if (key.toLowerCase() === 'content-length') {
  9782. delete params.Headers[key];
  9783. }
  9784. });
  9785. // 控制分片大小
  9786. (function () {
  9787. var SIZE = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 1024 * 2, 1024 * 4, 1024 * 5];
  9788. var AutoChunkSize = 1024 * 1024;
  9789. for (var i = 0; i < SIZE.length; i++) {
  9790. AutoChunkSize = SIZE[i] * 1024 * 1024;
  9791. if (FileSize / AutoChunkSize <= self.options.MaxPartNumber) break;
  9792. }
  9793. params.ChunkSize = params.SliceSize = ChunkSize = Math.max(ChunkSize, AutoChunkSize);
  9794. })();
  9795. // 开始上传
  9796. if (FileSize === 0) {
  9797. params.Body = '';
  9798. params.ContentLength = 0;
  9799. params.SkipTask = true;
  9800. self.putObject(params, function (err, data) {
  9801. if (err) {
  9802. return callback(err);
  9803. }
  9804. callback(null, data);
  9805. });
  9806. } else {
  9807. ep.emit('get_file_size_finish');
  9808. }
  9809. }
  9810. // 获取上传任务的 UploadId
  9811. function getUploadIdAndPartList(params, callback) {
  9812. var TaskId = params.TaskId;
  9813. var Bucket = params.Bucket;
  9814. var Region = params.Region;
  9815. var Key = params.Key;
  9816. var StorageClass = params.StorageClass;
  9817. var self = this;
  9818. // 计算 ETag
  9819. var ETagMap = {};
  9820. var FileSize = params.FileSize;
  9821. var SliceSize = params.SliceSize;
  9822. var SliceCount = Math.ceil(FileSize / SliceSize);
  9823. var FinishSliceCount = 0;
  9824. var FinishSize = 0;
  9825. var onHashProgress = util.throttleOnProgress.call(self, FileSize, params.onHashProgress);
  9826. var getChunkETag = function (PartNumber, callback) {
  9827. var start = SliceSize * (PartNumber - 1);
  9828. var end = Math.min(start + SliceSize, FileSize);
  9829. var ChunkSize = end - start;
  9830. if (ETagMap[PartNumber]) {
  9831. callback(null, {
  9832. PartNumber: PartNumber,
  9833. ETag: ETagMap[PartNumber],
  9834. Size: ChunkSize
  9835. });
  9836. } else {
  9837. util.fileSlice(params.Body, start, end, false, function (chunkItem) {
  9838. util.getFileMd5(chunkItem, function (err, md5) {
  9839. if (err) return callback(err);
  9840. var ETag = '"' + md5 + '"';
  9841. ETagMap[PartNumber] = ETag;
  9842. FinishSliceCount += 1;
  9843. FinishSize += ChunkSize;
  9844. callback(err, {
  9845. PartNumber: PartNumber,
  9846. ETag: ETag,
  9847. Size: ChunkSize
  9848. });
  9849. onHashProgress({ loaded: FinishSize, total: FileSize });
  9850. });
  9851. });
  9852. }
  9853. };
  9854. // 通过和文件的 md5 对比,判断 UploadId 是否可用
  9855. var isAvailableUploadList = function (PartList, callback) {
  9856. var PartCount = PartList.length;
  9857. // 如果没有分片,通过
  9858. if (PartCount === 0) {
  9859. return callback(null, true);
  9860. }
  9861. // 检查分片数量
  9862. if (PartCount > SliceCount) {
  9863. return callback(null, false);
  9864. }
  9865. // 检查分片大小
  9866. if (PartCount > 1) {
  9867. var PartSliceSize = Math.max(PartList[0].Size, PartList[1].Size);
  9868. if (PartSliceSize !== SliceSize) {
  9869. return callback(null, false);
  9870. }
  9871. }
  9872. // 逐个分片计算并检查 ETag 是否一致
  9873. var next = function (index) {
  9874. if (index < PartCount) {
  9875. var Part = PartList[index];
  9876. getChunkETag(Part.PartNumber, function (err, chunk) {
  9877. if (chunk && chunk.ETag === Part.ETag && chunk.Size === Part.Size) {
  9878. next(index + 1);
  9879. } else {
  9880. callback(null, false);
  9881. }
  9882. });
  9883. } else {
  9884. callback(null, true);
  9885. }
  9886. };
  9887. next(0);
  9888. };
  9889. var ep = new EventProxy();
  9890. ep.on('error', function (errData) {
  9891. if (!self._isRunningTask(TaskId)) return;
  9892. return callback(errData);
  9893. });
  9894. // 存在 UploadId
  9895. ep.on('upload_id_available', function (UploadData) {
  9896. // 转换成 map
  9897. var map = {};
  9898. var list = [];
  9899. util.each(UploadData.PartList, function (item) {
  9900. map[item.PartNumber] = item;
  9901. });
  9902. for (var PartNumber = 1; PartNumber <= SliceCount; PartNumber++) {
  9903. var item = map[PartNumber];
  9904. if (item) {
  9905. item.PartNumber = PartNumber;
  9906. item.Uploaded = true;
  9907. } else {
  9908. item = {
  9909. PartNumber: PartNumber,
  9910. ETag: null,
  9911. Uploaded: false
  9912. };
  9913. }
  9914. list.push(item);
  9915. }
  9916. UploadData.PartList = list;
  9917. callback(null, UploadData);
  9918. });
  9919. // 不存在 UploadId, 初始化生成 UploadId
  9920. ep.on('no_available_upload_id', function () {
  9921. if (!self._isRunningTask(TaskId)) return;
  9922. var _params = util.extend({
  9923. Bucket: Bucket,
  9924. Region: Region,
  9925. Key: Key,
  9926. Headers: util.clone(params.Headers),
  9927. StorageClass: StorageClass,
  9928. Body: params.Body
  9929. }, params);
  9930. // 获取 File 或 Blob 的 type 属性,如果有,作为文件 Content-Type
  9931. var ContentType = params.Headers['Content-Type'] || params.Body && params.Body.type;
  9932. if (ContentType) {
  9933. _params.Headers['Content-Type'] = ContentType;
  9934. }
  9935. self.multipartInit(_params, function (err, data) {
  9936. if (!self._isRunningTask(TaskId)) return;
  9937. if (err) return ep.emit('error', err);
  9938. var UploadId = data.UploadId;
  9939. if (!UploadId) {
  9940. return callback({ Message: 'no upload id' });
  9941. }
  9942. ep.emit('upload_id_available', { UploadId: UploadId, PartList: [] });
  9943. });
  9944. });
  9945. // 如果已存在 UploadId,找一个可以用的 UploadId
  9946. ep.on('has_and_check_upload_id', function (UploadIdList) {
  9947. // 串行地,找一个内容一致的 UploadId
  9948. UploadIdList = UploadIdList.reverse();
  9949. Async.eachLimit(UploadIdList, 1, function (UploadId, asyncCallback) {
  9950. if (!self._isRunningTask(TaskId)) return;
  9951. // 如果正在上传,跳过
  9952. if (session.using[UploadId]) {
  9953. asyncCallback(); // 检查下一个 UploadId
  9954. return;
  9955. }
  9956. // 判断 UploadId 是否可用
  9957. wholeMultipartListPart.call(self, {
  9958. Bucket: Bucket,
  9959. Region: Region,
  9960. Key: Key,
  9961. UploadId: UploadId
  9962. }, function (err, PartListData) {
  9963. if (!self._isRunningTask(TaskId)) return;
  9964. if (err) {
  9965. session.removeUsing(UploadId);
  9966. return ep.emit('error', err);
  9967. }
  9968. var PartList = PartListData.PartList;
  9969. PartList.forEach(function (item) {
  9970. item.PartNumber *= 1;
  9971. item.Size *= 1;
  9972. item.ETag = item.ETag || '';
  9973. });
  9974. isAvailableUploadList(PartList, function (err, isAvailable) {
  9975. if (!self._isRunningTask(TaskId)) return;
  9976. if (err) return ep.emit('error', err);
  9977. if (isAvailable) {
  9978. asyncCallback({
  9979. UploadId: UploadId,
  9980. PartList: PartList
  9981. }); // 马上结束
  9982. } else {
  9983. asyncCallback(); // 检查下一个 UploadId
  9984. }
  9985. });
  9986. });
  9987. }, function (AvailableUploadData) {
  9988. if (!self._isRunningTask(TaskId)) return;
  9989. onHashProgress(null, true);
  9990. if (AvailableUploadData && AvailableUploadData.UploadId) {
  9991. ep.emit('upload_id_available', AvailableUploadData);
  9992. } else {
  9993. ep.emit('no_available_upload_id');
  9994. }
  9995. });
  9996. });
  9997. // 在本地缓存找可用的 UploadId
  9998. ep.on('seek_local_avail_upload_id', function (RemoteUploadIdList) {
  9999. // 在本地找可用的 UploadId
  10000. var uuid = session.getFileId(params.Body, params.ChunkSize, Bucket, Key);
  10001. var LocalUploadIdList = session.getUploadIdList(uuid);
  10002. if (!uuid || !LocalUploadIdList) {
  10003. ep.emit('has_and_check_upload_id', RemoteUploadIdList);
  10004. return;
  10005. }
  10006. var next = function (index) {
  10007. // 如果本地找不到可用 UploadId,再一个个遍历校验远端
  10008. if (index >= LocalUploadIdList.length) {
  10009. ep.emit('has_and_check_upload_id', RemoteUploadIdList);
  10010. return;
  10011. }
  10012. var UploadId = LocalUploadIdList[index];
  10013. // 如果不在远端 UploadId 列表里,跳过并删除
  10014. if (!util.isInArray(RemoteUploadIdList, UploadId)) {
  10015. session.removeUploadId(UploadId);
  10016. next(index + 1);
  10017. return;
  10018. }
  10019. // 如果正在上传,跳过
  10020. if (session.using[UploadId]) {
  10021. next(index + 1);
  10022. return;
  10023. }
  10024. // 判断 UploadId 是否存在线上
  10025. wholeMultipartListPart.call(self, {
  10026. Bucket: Bucket,
  10027. Region: Region,
  10028. Key: Key,
  10029. UploadId: UploadId
  10030. }, function (err, PartListData) {
  10031. if (!self._isRunningTask(TaskId)) return;
  10032. if (err) {
  10033. // 如果 UploadId 获取会出错,跳过并删除
  10034. session.removeUploadId(UploadId);
  10035. next(index + 1);
  10036. } else {
  10037. // 找到可用 UploadId
  10038. ep.emit('upload_id_available', {
  10039. UploadId: UploadId,
  10040. PartList: PartListData.PartList
  10041. });
  10042. }
  10043. });
  10044. };
  10045. next(0);
  10046. });
  10047. // 获取线上 UploadId 列表
  10048. ep.on('get_remote_upload_id_list', function (RemoteUploadIdList) {
  10049. // 获取符合条件的 UploadId 列表,因为同一个文件可以有多个上传任务。
  10050. wholeMultipartList.call(self, {
  10051. Bucket: Bucket,
  10052. Region: Region,
  10053. Key: Key
  10054. }, function (err, data) {
  10055. if (!self._isRunningTask(TaskId)) return;
  10056. if (err) {
  10057. return ep.emit('error', err);
  10058. }
  10059. // 整理远端 UploadId 列表
  10060. var RemoteUploadIdList = util.filter(data.UploadList, function (item) {
  10061. return item.Key === Key && (!StorageClass || item.StorageClass.toUpperCase() === StorageClass.toUpperCase());
  10062. }).reverse().map(function (item) {
  10063. return item.UploadId || item.UploadID;
  10064. });
  10065. if (RemoteUploadIdList.length) {
  10066. ep.emit('seek_local_avail_upload_id', RemoteUploadIdList);
  10067. } else {
  10068. // 远端没有 UploadId,清理缓存的 UploadId
  10069. var uuid = session.getFileId(params.Body, params.ChunkSize, Bucket, Key),
  10070. LocalUploadIdList;
  10071. if (uuid && (LocalUploadIdList = session.getUploadIdList(uuid))) {
  10072. util.each(LocalUploadIdList, function (UploadId) {
  10073. session.removeUploadId(UploadId);
  10074. });
  10075. }
  10076. ep.emit('no_available_upload_id');
  10077. }
  10078. });
  10079. });
  10080. // 开始找可用 UploadId
  10081. ep.emit('get_remote_upload_id_list');
  10082. }
  10083. // 获取符合条件的全部上传任务 (条件包括 Bucket, Region, Prefix)
  10084. function wholeMultipartList(params, callback) {
  10085. var self = this;
  10086. var UploadList = [];
  10087. var sendParams = {
  10088. Bucket: params.Bucket,
  10089. Region: params.Region,
  10090. Prefix: params.Key
  10091. };
  10092. var next = function () {
  10093. self.multipartList(sendParams, function (err, data) {
  10094. if (err) return callback(err);
  10095. UploadList.push.apply(UploadList, data.Upload || []);
  10096. if (data.IsTruncated === 'true') {
  10097. // 列表不完整
  10098. sendParams.KeyMarker = data.NextKeyMarker;
  10099. sendParams.UploadIdMarker = data.NextUploadIdMarker;
  10100. next();
  10101. } else {
  10102. callback(null, { UploadList: UploadList });
  10103. }
  10104. });
  10105. };
  10106. next();
  10107. }
  10108. // 获取指定上传任务的分块列表
  10109. function wholeMultipartListPart(params, callback) {
  10110. var self = this;
  10111. var PartList = [];
  10112. var sendParams = {
  10113. Bucket: params.Bucket,
  10114. Region: params.Region,
  10115. Key: params.Key,
  10116. UploadId: params.UploadId
  10117. };
  10118. var next = function () {
  10119. self.multipartListPart(sendParams, function (err, data) {
  10120. if (err) return callback(err);
  10121. PartList.push.apply(PartList, data.Part || []);
  10122. if (data.IsTruncated === 'true') {
  10123. // 列表不完整
  10124. sendParams.PartNumberMarker = data.NextPartNumberMarker;
  10125. next();
  10126. } else {
  10127. callback(null, { PartList: PartList });
  10128. }
  10129. });
  10130. };
  10131. next();
  10132. }
  10133. // 上传文件分块,包括
  10134. /*
  10135. UploadId (上传任务编号)
  10136. AsyncLimit (并发量),
  10137. SliceList (上传的分块数组),
  10138. FilePath (本地文件的位置),
  10139. SliceSize (文件分块大小)
  10140. FileSize (文件大小)
  10141. onProgress (上传成功之后的回调函数)
  10142. */
  10143. function uploadSliceList(params, cb) {
  10144. var self = this;
  10145. var TaskId = params.TaskId;
  10146. var Bucket = params.Bucket;
  10147. var Region = params.Region;
  10148. var Key = params.Key;
  10149. var UploadData = params.UploadData;
  10150. var FileSize = params.FileSize;
  10151. var SliceSize = params.SliceSize;
  10152. var ChunkParallel = Math.min(params.AsyncLimit || self.options.ChunkParallelLimit || 1, 256);
  10153. var Body = params.Body;
  10154. var SliceCount = Math.ceil(FileSize / SliceSize);
  10155. var FinishSize = 0;
  10156. var ServerSideEncryption = params.ServerSideEncryption;
  10157. var needUploadSlices = util.filter(UploadData.PartList, function (SliceItem) {
  10158. if (SliceItem['Uploaded']) {
  10159. FinishSize += SliceItem['PartNumber'] >= SliceCount ? FileSize % SliceSize || SliceSize : SliceSize;
  10160. }
  10161. return !SliceItem['Uploaded'];
  10162. });
  10163. var onProgress = params.onProgress;
  10164. Async.eachLimit(needUploadSlices, ChunkParallel, function (SliceItem, asyncCallback) {
  10165. if (!self._isRunningTask(TaskId)) return;
  10166. var PartNumber = SliceItem['PartNumber'];
  10167. var currentSize = Math.min(FileSize, SliceItem['PartNumber'] * SliceSize) - (SliceItem['PartNumber'] - 1) * SliceSize;
  10168. var preAddSize = 0;
  10169. uploadSliceItem.call(self, {
  10170. TaskId: TaskId,
  10171. Bucket: Bucket,
  10172. Region: Region,
  10173. Key: Key,
  10174. SliceSize: SliceSize,
  10175. FileSize: FileSize,
  10176. PartNumber: PartNumber,
  10177. ServerSideEncryption: ServerSideEncryption,
  10178. Body: Body,
  10179. UploadData: UploadData,
  10180. onProgress: function (data) {
  10181. FinishSize += data.loaded - preAddSize;
  10182. preAddSize = data.loaded;
  10183. onProgress({ loaded: FinishSize, total: FileSize });
  10184. }
  10185. }, function (err, data) {
  10186. if (!self._isRunningTask(TaskId)) return;
  10187. if (util.isBrowser && !err && !data.ETag) {
  10188. err = 'get ETag error, please add "ETag" to CORS ExposeHeader setting.';
  10189. }
  10190. if (err) {
  10191. FinishSize -= preAddSize;
  10192. } else {
  10193. FinishSize += currentSize - preAddSize;
  10194. SliceItem.ETag = data.ETag;
  10195. }
  10196. asyncCallback(err || null, data);
  10197. });
  10198. }, function (err) {
  10199. if (!self._isRunningTask(TaskId)) return;
  10200. if (err) return cb(err);
  10201. cb(null, {
  10202. UploadId: UploadData.UploadId,
  10203. SliceList: UploadData.PartList
  10204. });
  10205. });
  10206. }
  10207. // 上传指定分片
  10208. function uploadSliceItem(params, callback) {
  10209. var self = this;
  10210. var TaskId = params.TaskId;
  10211. var Bucket = params.Bucket;
  10212. var Region = params.Region;
  10213. var Key = params.Key;
  10214. var FileSize = params.FileSize;
  10215. var FileBody = params.Body;
  10216. var PartNumber = params.PartNumber * 1;
  10217. var SliceSize = params.SliceSize;
  10218. var ServerSideEncryption = params.ServerSideEncryption;
  10219. var UploadData = params.UploadData;
  10220. var ChunkRetryTimes = self.options.ChunkRetryTimes + 1;
  10221. var start = SliceSize * (PartNumber - 1);
  10222. var ContentLength = SliceSize;
  10223. var end = start + SliceSize;
  10224. if (end > FileSize) {
  10225. end = FileSize;
  10226. ContentLength = end - start;
  10227. }
  10228. var PartItem = UploadData.PartList[PartNumber - 1];
  10229. Async.retry(ChunkRetryTimes, function (tryCallback) {
  10230. if (!self._isRunningTask(TaskId)) return;
  10231. util.fileSlice(FileBody, start, end, true, function (Body) {
  10232. self.multipartUpload({
  10233. TaskId: TaskId,
  10234. Bucket: Bucket,
  10235. Region: Region,
  10236. Key: Key,
  10237. ContentLength: ContentLength,
  10238. PartNumber: PartNumber,
  10239. UploadId: UploadData.UploadId,
  10240. ServerSideEncryption: ServerSideEncryption,
  10241. Body: Body,
  10242. onProgress: params.onProgress
  10243. }, function (err, data) {
  10244. if (!self._isRunningTask(TaskId)) return;
  10245. if (err) {
  10246. return tryCallback(err);
  10247. } else {
  10248. PartItem.Uploaded = true;
  10249. return tryCallback(null, data);
  10250. }
  10251. });
  10252. });
  10253. }, function (err, data) {
  10254. if (!self._isRunningTask(TaskId)) return;
  10255. return callback(err, data);
  10256. });
  10257. }
  10258. // 完成分块上传
  10259. function uploadSliceComplete(params, callback) {
  10260. var Bucket = params.Bucket;
  10261. var Region = params.Region;
  10262. var Key = params.Key;
  10263. var UploadId = params.UploadId;
  10264. var SliceList = params.SliceList;
  10265. var self = this;
  10266. var ChunkRetryTimes = this.options.ChunkRetryTimes + 1;
  10267. var Parts = SliceList.map(function (item) {
  10268. return {
  10269. PartNumber: item.PartNumber,
  10270. ETag: item.ETag
  10271. };
  10272. });
  10273. // 完成上传的请求也做重试
  10274. Async.retry(ChunkRetryTimes, function (tryCallback) {
  10275. self.multipartComplete({
  10276. Bucket: Bucket,
  10277. Region: Region,
  10278. Key: Key,
  10279. UploadId: UploadId,
  10280. Parts: Parts
  10281. }, tryCallback);
  10282. }, function (err, data) {
  10283. callback(err, data);
  10284. });
  10285. }
  10286. // 抛弃分块上传任务
  10287. /*
  10288. AsyncLimit (抛弃上传任务的并发量),
  10289. UploadId (上传任务的编号,当 Level 为 task 时候需要)
  10290. Level (抛弃分块上传任务的级别,task : 抛弃指定的上传任务,file : 抛弃指定的文件对应的上传任务,其他值 :抛弃指定Bucket 的全部上传任务)
  10291. */
  10292. function abortUploadTask(params, callback) {
  10293. var Bucket = params.Bucket;
  10294. var Region = params.Region;
  10295. var Key = params.Key;
  10296. var UploadId = params.UploadId;
  10297. var Level = params.Level || 'task';
  10298. var AsyncLimit = params.AsyncLimit;
  10299. var self = this;
  10300. var ep = new EventProxy();
  10301. ep.on('error', function (errData) {
  10302. return callback(errData);
  10303. });
  10304. // 已经获取到需要抛弃的任务列表
  10305. ep.on('get_abort_array', function (AbortArray) {
  10306. abortUploadTaskArray.call(self, {
  10307. Bucket: Bucket,
  10308. Region: Region,
  10309. Key: Key,
  10310. Headers: params.Headers,
  10311. AsyncLimit: AsyncLimit,
  10312. AbortArray: AbortArray
  10313. }, function (err, data) {
  10314. if (err) {
  10315. return callback(err);
  10316. }
  10317. callback(null, data);
  10318. });
  10319. });
  10320. if (Level === 'bucket') {
  10321. // Bucket 级别的任务抛弃,抛弃该 Bucket 下的全部上传任务
  10322. wholeMultipartList.call(self, {
  10323. Bucket: Bucket,
  10324. Region: Region
  10325. }, function (err, data) {
  10326. if (err) {
  10327. return callback(err);
  10328. }
  10329. ep.emit('get_abort_array', data.UploadList || []);
  10330. });
  10331. } else if (Level === 'file') {
  10332. // 文件级别的任务抛弃,抛弃该文件的全部上传任务
  10333. if (!Key) return callback({ error: 'abort_upload_task_no_key' });
  10334. wholeMultipartList.call(self, {
  10335. Bucket: Bucket,
  10336. Region: Region,
  10337. Key: Key
  10338. }, function (err, data) {
  10339. if (err) {
  10340. return callback(err);
  10341. }
  10342. ep.emit('get_abort_array', data.UploadList || []);
  10343. });
  10344. } else if (Level === 'task') {
  10345. // 单个任务级别的任务抛弃,抛弃指定 UploadId 的上传任务
  10346. if (!UploadId) return callback({ error: 'abort_upload_task_no_id' });
  10347. if (!Key) return callback({ error: 'abort_upload_task_no_key' });
  10348. ep.emit('get_abort_array', [{
  10349. Key: Key,
  10350. UploadId: UploadId
  10351. }]);
  10352. } else {
  10353. return callback({ error: 'abort_unknown_level' });
  10354. }
  10355. }
  10356. // 批量抛弃分块上传任务
  10357. function abortUploadTaskArray(params, callback) {
  10358. var Bucket = params.Bucket;
  10359. var Region = params.Region;
  10360. var Key = params.Key;
  10361. var AbortArray = params.AbortArray;
  10362. var AsyncLimit = params.AsyncLimit || 1;
  10363. var self = this;
  10364. var index = 0;
  10365. var resultList = new Array(AbortArray.length);
  10366. Async.eachLimit(AbortArray, AsyncLimit, function (AbortItem, callback) {
  10367. var eachIndex = index;
  10368. if (Key && Key !== AbortItem.Key) {
  10369. resultList[eachIndex] = { error: { KeyNotMatch: true } };
  10370. callback(null);
  10371. return;
  10372. }
  10373. var UploadId = AbortItem.UploadId || AbortItem.UploadID;
  10374. self.multipartAbort({
  10375. Bucket: Bucket,
  10376. Region: Region,
  10377. Key: AbortItem.Key,
  10378. Headers: params.Headers,
  10379. UploadId: UploadId
  10380. }, function (err, data) {
  10381. var task = {
  10382. Bucket: Bucket,
  10383. Region: Region,
  10384. Key: AbortItem.Key,
  10385. UploadId: UploadId
  10386. };
  10387. resultList[eachIndex] = { error: err, task: task };
  10388. callback(null);
  10389. });
  10390. index++;
  10391. }, function (err) {
  10392. if (err) {
  10393. return callback(err);
  10394. }
  10395. var successList = [];
  10396. var errorList = [];
  10397. for (var i = 0, len = resultList.length; i < len; i++) {
  10398. var item = resultList[i];
  10399. if (item['task']) {
  10400. if (item['error']) {
  10401. errorList.push(item['task']);
  10402. } else {
  10403. successList.push(item['task']);
  10404. }
  10405. }
  10406. }
  10407. return callback(null, {
  10408. successList: successList,
  10409. errorList: errorList
  10410. });
  10411. });
  10412. }
  10413. // 批量上传文件
  10414. function uploadFiles(params, callback) {
  10415. var self = this;
  10416. // 判断多大的文件使用分片上传
  10417. var SliceSize = params.SliceSize === undefined ? self.options.SliceSize : params.SliceSize;
  10418. // 汇总返回进度
  10419. var TotalSize = 0;
  10420. var TotalFinish = 0;
  10421. var onTotalProgress = util.throttleOnProgress.call(self, TotalFinish, params.onProgress);
  10422. // 汇总返回回调
  10423. var unFinishCount = params.files.length;
  10424. var _onTotalFileFinish = params.onFileFinish;
  10425. var resultList = Array(unFinishCount);
  10426. var onTotalFileFinish = function (err, data, options) {
  10427. onTotalProgress(null, true);
  10428. _onTotalFileFinish && _onTotalFileFinish(err, data, options);
  10429. resultList[options.Index] = {
  10430. options: options,
  10431. error: err,
  10432. data: data
  10433. };
  10434. if (--unFinishCount <= 0 && callback) {
  10435. callback(null, {
  10436. files: resultList
  10437. });
  10438. }
  10439. };
  10440. // 开始处理每个文件
  10441. var taskList = [];
  10442. util.each(params.files, function (fileParams, index) {
  10443. (function () {
  10444. // 对齐 nodejs 缩进
  10445. var Body = fileParams.Body;
  10446. var FileSize = Body.size || Body.length || 0;
  10447. var fileInfo = { Index: index, TaskId: '' };
  10448. // 更新文件总大小
  10449. TotalSize += FileSize;
  10450. // 整理 option,用于返回给回调
  10451. util.each(fileParams, function (v, k) {
  10452. if (typeof v !== 'object' && typeof v !== 'function') {
  10453. fileInfo[k] = v;
  10454. }
  10455. });
  10456. // 处理单个文件 TaskReady
  10457. var _onTaskReady = fileParams.onTaskReady;
  10458. var onTaskReady = function (tid) {
  10459. fileInfo.TaskId = tid;
  10460. _onTaskReady && _onTaskReady(tid);
  10461. };
  10462. fileParams.onTaskReady = onTaskReady;
  10463. // 处理单个文件进度
  10464. var PreAddSize = 0;
  10465. var _onProgress = fileParams.onProgress;
  10466. var onProgress = function (info) {
  10467. TotalFinish = TotalFinish - PreAddSize + info.loaded;
  10468. PreAddSize = info.loaded;
  10469. _onProgress && _onProgress(info);
  10470. onTotalProgress({ loaded: TotalFinish, total: TotalSize });
  10471. };
  10472. fileParams.onProgress = onProgress;
  10473. // 处理单个文件完成
  10474. var _onFileFinish = fileParams.onFileFinish;
  10475. var onFileFinish = function (err, data) {
  10476. _onFileFinish && _onFileFinish(err, data);
  10477. onTotalFileFinish && onTotalFileFinish(err, data, fileInfo);
  10478. };
  10479. // 添加上传任务
  10480. var api = FileSize >= SliceSize ? 'sliceUploadFile' : 'putObject';
  10481. taskList.push({
  10482. api: api,
  10483. params: fileParams,
  10484. callback: onFileFinish
  10485. });
  10486. })();
  10487. });
  10488. self._addTasks(taskList);
  10489. }
  10490. // 分片复制文件
  10491. function sliceCopyFile(params, callback) {
  10492. var ep = new EventProxy();
  10493. var self = this;
  10494. var Bucket = params.Bucket;
  10495. var Region = params.Region;
  10496. var Key = params.Key;
  10497. var CopySource = params.CopySource;
  10498. var m = CopySource.match(/^([^.]+-\d+)\.cos(v6)?\.([^.]+)\.[^/]+\/(.+)$/);
  10499. if (!m) {
  10500. callback({ error: 'CopySource format error' });
  10501. return;
  10502. }
  10503. var SourceBucket = m[1];
  10504. var SourceRegion = m[3];
  10505. var SourceKey = decodeURIComponent(m[4]);
  10506. var CopySliceSize = params.CopySliceSize === undefined ? self.options.CopySliceSize : params.CopySliceSize;
  10507. CopySliceSize = Math.max(0, CopySliceSize);
  10508. var ChunkSize = params.CopyChunkSize || this.options.CopyChunkSize;
  10509. var ChunkParallel = this.options.CopyChunkParallelLimit;
  10510. var FinishSize = 0;
  10511. var FileSize;
  10512. var onProgress;
  10513. // 分片复制完成,开始 multipartComplete 操作
  10514. ep.on('copy_slice_complete', function (UploadData) {
  10515. self.multipartComplete({
  10516. Bucket: Bucket,
  10517. Region: Region,
  10518. Key: Key,
  10519. UploadId: UploadData.UploadId,
  10520. Parts: UploadData.PartList
  10521. }, function (err, data) {
  10522. if (err) {
  10523. onProgress(null, true);
  10524. return callback(err);
  10525. }
  10526. onProgress({ loaded: FileSize, total: FileSize }, true);
  10527. callback(null, data);
  10528. });
  10529. });
  10530. ep.on('get_copy_data_finish', function (UploadData) {
  10531. Async.eachLimit(UploadData.PartList, ChunkParallel, function (SliceItem, asyncCallback) {
  10532. var PartNumber = SliceItem.PartNumber;
  10533. var CopySourceRange = SliceItem.CopySourceRange;
  10534. var currentSize = SliceItem.end - SliceItem.start;
  10535. var preAddSize = 0;
  10536. copySliceItem.call(self, {
  10537. Bucket: Bucket,
  10538. Region: Region,
  10539. Key: Key,
  10540. CopySource: CopySource,
  10541. UploadId: UploadData.UploadId,
  10542. PartNumber: PartNumber,
  10543. CopySourceRange: CopySourceRange,
  10544. onProgress: function (data) {
  10545. FinishSize += data.loaded - preAddSize;
  10546. preAddSize = data.loaded;
  10547. onProgress({ loaded: FinishSize, total: FileSize });
  10548. }
  10549. }, function (err, data) {
  10550. if (err) {
  10551. return asyncCallback(err);
  10552. }
  10553. onProgress({ loaded: FinishSize, total: FileSize });
  10554. FinishSize += currentSize - preAddSize;
  10555. SliceItem.ETag = data.ETag;
  10556. asyncCallback(err || null, data);
  10557. });
  10558. }, function (err) {
  10559. if (err) {
  10560. onProgress(null, true);
  10561. return callback(err);
  10562. }
  10563. ep.emit('copy_slice_complete', UploadData);
  10564. });
  10565. });
  10566. ep.on('get_file_size_finish', function (SourceHeaders) {
  10567. // 控制分片大小
  10568. (function () {
  10569. var SIZE = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 1024 * 2, 1024 * 4, 1024 * 5];
  10570. var AutoChunkSize = 1024 * 1024;
  10571. for (var i = 0; i < SIZE.length; i++) {
  10572. AutoChunkSize = SIZE[i] * 1024 * 1024;
  10573. if (FileSize / AutoChunkSize <= self.options.MaxPartNumber) break;
  10574. }
  10575. params.ChunkSize = ChunkSize = Math.max(ChunkSize, AutoChunkSize);
  10576. var ChunkCount = Math.ceil(FileSize / ChunkSize);
  10577. var list = [];
  10578. for (var partNumber = 1; partNumber <= ChunkCount; partNumber++) {
  10579. var start = (partNumber - 1) * ChunkSize;
  10580. var end = partNumber * ChunkSize < FileSize ? partNumber * ChunkSize - 1 : FileSize - 1;
  10581. var item = {
  10582. PartNumber: partNumber,
  10583. start: start,
  10584. end: end,
  10585. CopySourceRange: "bytes=" + start + "-" + end
  10586. };
  10587. list.push(item);
  10588. }
  10589. params.PartList = list;
  10590. })();
  10591. var TargetHeader;
  10592. if (params.Headers['x-cos-metadata-directive'] === 'Replaced') {
  10593. TargetHeader = params.Headers;
  10594. } else {
  10595. TargetHeader = SourceHeaders;
  10596. }
  10597. TargetHeader['x-cos-storage-class'] = params.Headers['x-cos-storage-class'] || SourceHeaders['x-cos-storage-class'];
  10598. TargetHeader = util.clearKey(TargetHeader);
  10599. /**
  10600. * 对于归档存储的对象,如果未恢复副本,则不允许 Copy
  10601. */
  10602. if (SourceHeaders['x-cos-storage-class'] === 'ARCHIVE') {
  10603. var restoreHeader = SourceHeaders['x-cos-restore'];
  10604. if (!restoreHeader || restoreHeader === 'ongoing-request="true"') {
  10605. callback({ error: 'Unrestored archive object is not allowed to be copied' });
  10606. return;
  10607. }
  10608. }
  10609. /**
  10610. * 去除一些无用的头部,规避 multipartInit 出错
  10611. * 这些头部通常是在 putObjectCopy 时才使用
  10612. */
  10613. delete TargetHeader['x-cos-copy-source'];
  10614. delete TargetHeader['x-cos-metadata-directive'];
  10615. delete TargetHeader['x-cos-copy-source-If-Modified-Since'];
  10616. delete TargetHeader['x-cos-copy-source-If-Unmodified-Since'];
  10617. delete TargetHeader['x-cos-copy-source-If-Match'];
  10618. delete TargetHeader['x-cos-copy-source-If-None-Match'];
  10619. self.multipartInit({
  10620. Bucket: Bucket,
  10621. Region: Region,
  10622. Key: Key,
  10623. Headers: TargetHeader
  10624. }, function (err, data) {
  10625. if (err) {
  10626. return callback(err);
  10627. }
  10628. params.UploadId = data.UploadId;
  10629. ep.emit('get_copy_data_finish', params);
  10630. });
  10631. });
  10632. // 获取远端复制源文件的大小
  10633. self.headObject({
  10634. Bucket: SourceBucket,
  10635. Region: SourceRegion,
  10636. Key: SourceKey
  10637. }, function (err, data) {
  10638. if (err) {
  10639. if (err.statusCode && err.statusCode === 404) {
  10640. callback({ ErrorStatus: SourceKey + ' Not Exist' });
  10641. } else {
  10642. callback(err);
  10643. }
  10644. return;
  10645. }
  10646. FileSize = params.FileSize = data.headers['content-length'];
  10647. if (FileSize === undefined || !FileSize) {
  10648. callback({ error: 'get Content-Length error, please add "Content-Length" to CORS ExposeHeader setting.' });
  10649. return;
  10650. }
  10651. onProgress = util.throttleOnProgress.call(self, FileSize, params.onProgress);
  10652. // 开始上传
  10653. if (FileSize <= CopySliceSize) {
  10654. if (!params.Headers['x-cos-metadata-directive']) {
  10655. params.Headers['x-cos-metadata-directive'] = 'Copy';
  10656. }
  10657. self.putObjectCopy(params, function (err, data) {
  10658. if (err) {
  10659. onProgress(null, true);
  10660. return callback(err);
  10661. }
  10662. onProgress({ loaded: FileSize, total: FileSize }, true);
  10663. callback(err, data);
  10664. });
  10665. } else {
  10666. var resHeaders = data.headers;
  10667. var SourceHeaders = {
  10668. 'Cache-Control': resHeaders['cache-control'],
  10669. 'Content-Disposition': resHeaders['content-disposition'],
  10670. 'Content-Encoding': resHeaders['content-encoding'],
  10671. 'Content-Type': resHeaders['content-type'],
  10672. 'Expires': resHeaders['expires'],
  10673. 'x-cos-storage-class': resHeaders['x-cos-storage-class']
  10674. };
  10675. util.each(resHeaders, function (v, k) {
  10676. var metaPrefix = 'x-cos-meta-';
  10677. if (k.indexOf(metaPrefix) === 0 && k.length > metaPrefix.length) {
  10678. SourceHeaders[k] = v;
  10679. }
  10680. });
  10681. ep.emit('get_file_size_finish', SourceHeaders);
  10682. }
  10683. });
  10684. }
  10685. // 复制指定分片
  10686. function copySliceItem(params, callback) {
  10687. var TaskId = params.TaskId;
  10688. var Bucket = params.Bucket;
  10689. var Region = params.Region;
  10690. var Key = params.Key;
  10691. var CopySource = params.CopySource;
  10692. var UploadId = params.UploadId;
  10693. var PartNumber = params.PartNumber * 1;
  10694. var CopySourceRange = params.CopySourceRange;
  10695. var ChunkRetryTimes = this.options.ChunkRetryTimes + 1;
  10696. var self = this;
  10697. Async.retry(ChunkRetryTimes, function (tryCallback) {
  10698. self.uploadPartCopy({
  10699. TaskId: TaskId,
  10700. Bucket: Bucket,
  10701. Region: Region,
  10702. Key: Key,
  10703. CopySource: CopySource,
  10704. UploadId: UploadId,
  10705. PartNumber: PartNumber,
  10706. CopySourceRange: CopySourceRange,
  10707. onProgress: params.onProgress
  10708. }, function (err, data) {
  10709. tryCallback(err || null, data);
  10710. });
  10711. }, function (err, data) {
  10712. return callback(err, data);
  10713. });
  10714. }
  10715. var API_MAP = {
  10716. sliceUploadFile: sliceUploadFile,
  10717. abortUploadTask: abortUploadTask,
  10718. uploadFiles: uploadFiles,
  10719. sliceCopyFile: sliceCopyFile
  10720. };
  10721. module.exports.init = function (COS, task) {
  10722. task.transferToTaskMethod(API_MAP, 'sliceUploadFile');
  10723. util.each(API_MAP, function (fn, apiName) {
  10724. COS.prototype[apiName] = util.apiWrapper(apiName, fn);
  10725. });
  10726. };
  10727. /***/ }),
  10728. /* 16 */
  10729. /***/ (function(module, exports) {
  10730. var eachLimit = function (arr, limit, iterator, callback) {
  10731. callback = callback || function () {};
  10732. if (!arr.length || limit <= 0) {
  10733. return callback();
  10734. }
  10735. var completed = 0;
  10736. var started = 0;
  10737. var running = 0;
  10738. (function replenish() {
  10739. if (completed >= arr.length) {
  10740. return callback();
  10741. }
  10742. while (running < limit && started < arr.length) {
  10743. started += 1;
  10744. running += 1;
  10745. iterator(arr[started - 1], function (err) {
  10746. if (err) {
  10747. callback(err);
  10748. callback = function () {};
  10749. } else {
  10750. completed += 1;
  10751. running -= 1;
  10752. if (completed >= arr.length) {
  10753. callback();
  10754. } else {
  10755. replenish();
  10756. }
  10757. }
  10758. });
  10759. }
  10760. })();
  10761. };
  10762. var retry = function (times, iterator, callback) {
  10763. var next = function (index) {
  10764. iterator(function (err, data) {
  10765. if (err && index < times) {
  10766. next(index + 1);
  10767. } else {
  10768. callback(err, data);
  10769. }
  10770. });
  10771. };
  10772. if (times < 1) {
  10773. callback();
  10774. } else {
  10775. next(1);
  10776. }
  10777. };
  10778. var async = {
  10779. eachLimit: eachLimit,
  10780. retry: retry
  10781. };
  10782. module.exports = async;
  10783. /***/ })
  10784. /******/ ]);
  10785. });