im-weapp.js 773 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  3. typeof define === 'function' && define.amd ? define('leancloud-realtime', ['exports'], factory) :
  4. (global = global || self, factory(global.AV = global.AV || {}));
  5. }(this, (function (exports) { 'use strict';
  6. var define = undefined;
  7. var require = require || function(id) {throw new Error('Unexpected required ' + id)};
  8. var process = (typeof window !== 'undefined' && window.process) || {};
  9. process.env = process.env || {};
  10. global.Object=Object;function Function(){return function(){return {}}};
  11. var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
  12. function unwrapExports (x) {
  13. return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
  14. }
  15. function createCommonjsModule(fn, basedir, module) {
  16. return module = {
  17. path: basedir,
  18. exports: {},
  19. require: function (path, base) {
  20. return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
  21. }
  22. }, fn(module, module.exports), module.exports;
  23. }
  24. function getCjsExportFromNamespace (n) {
  25. return n && n['default'] || n;
  26. }
  27. function commonjsRequire () {
  28. throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
  29. }
  30. var lib = createCommonjsModule(function (module, exports) {
  31. Object.defineProperty(exports, '__esModule', {
  32. value: true
  33. });
  34. /*! *****************************************************************************
  35. Copyright (c) Microsoft Corporation.
  36. Permission to use, copy, modify, and/or distribute this software for any
  37. purpose with or without fee is hereby granted.
  38. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  39. REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  40. AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  41. INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  42. LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  43. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  44. PERFORMANCE OF THIS SOFTWARE.
  45. ***************************************************************************** */
  46. /* global Reflect, Promise */
  47. var extendStatics = function (d, b) {
  48. extendStatics = Object.setPrototypeOf || {
  49. __proto__: []
  50. } instanceof Array && function (d, b) {
  51. d.__proto__ = b;
  52. } || function (d, b) {
  53. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  54. };
  55. return extendStatics(d, b);
  56. };
  57. function __extends(d, b) {
  58. extendStatics(d, b);
  59. function __() {
  60. this.constructor = d;
  61. }
  62. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  63. }
  64. var __assign = function () {
  65. __assign = Object.assign || function __assign(t) {
  66. for (var s, i = 1, n = arguments.length; i < n; i++) {
  67. s = arguments[i];
  68. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
  69. }
  70. return t;
  71. };
  72. return __assign.apply(this, arguments);
  73. };
  74. function __rest(s, e) {
  75. var t = {};
  76. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
  77. if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  78. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
  79. }
  80. return t;
  81. }
  82. function __awaiter(thisArg, _arguments, P, generator) {
  83. function adopt(value) {
  84. return value instanceof P ? value : new P(function (resolve) {
  85. resolve(value);
  86. });
  87. }
  88. return new (P || (P = Promise))(function (resolve, reject) {
  89. function fulfilled(value) {
  90. try {
  91. step(generator.next(value));
  92. } catch (e) {
  93. reject(e);
  94. }
  95. }
  96. function rejected(value) {
  97. try {
  98. step(generator["throw"](value));
  99. } catch (e) {
  100. reject(e);
  101. }
  102. }
  103. function step(result) {
  104. result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
  105. }
  106. step((generator = generator.apply(thisArg, _arguments || [])).next());
  107. });
  108. }
  109. function __generator(thisArg, body) {
  110. var _ = {
  111. label: 0,
  112. sent: function () {
  113. if (t[0] & 1) throw t[1];
  114. return t[1];
  115. },
  116. trys: [],
  117. ops: []
  118. },
  119. f,
  120. y,
  121. t,
  122. g;
  123. return g = {
  124. next: verb(0),
  125. "throw": verb(1),
  126. "return": verb(2)
  127. }, typeof Symbol === "function" && (g[Symbol.iterator] = function () {
  128. return this;
  129. }), g;
  130. function verb(n) {
  131. return function (v) {
  132. return step([n, v]);
  133. };
  134. }
  135. function step(op) {
  136. if (f) throw new TypeError("Generator is already executing.");
  137. while (_) try {
  138. if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
  139. if (y = 0, t) op = [op[0] & 2, t.value];
  140. switch (op[0]) {
  141. case 0:
  142. case 1:
  143. t = op;
  144. break;
  145. case 4:
  146. _.label++;
  147. return {
  148. value: op[1],
  149. done: false
  150. };
  151. case 5:
  152. _.label++;
  153. y = op[1];
  154. op = [0];
  155. continue;
  156. case 7:
  157. op = _.ops.pop();
  158. _.trys.pop();
  159. continue;
  160. default:
  161. if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
  162. _ = 0;
  163. continue;
  164. }
  165. if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
  166. _.label = op[1];
  167. break;
  168. }
  169. if (op[0] === 6 && _.label < t[1]) {
  170. _.label = t[1];
  171. t = op;
  172. break;
  173. }
  174. if (t && _.label < t[2]) {
  175. _.label = t[2];
  176. _.ops.push(op);
  177. break;
  178. }
  179. if (t[2]) _.ops.pop();
  180. _.trys.pop();
  181. continue;
  182. }
  183. op = body.call(thisArg, _);
  184. } catch (e) {
  185. op = [6, e];
  186. y = 0;
  187. } finally {
  188. f = t = 0;
  189. }
  190. if (op[0] & 5) throw op[1];
  191. return {
  192. value: op[0] ? op[1] : void 0,
  193. done: true
  194. };
  195. }
  196. }
  197. var PROVIDER = "lc_weapp";
  198. var PLATFORM = "weixin";
  199. function getLoginCode() {
  200. return new Promise(function (resolve, reject) {
  201. wx.login({
  202. success: function (res) {
  203. return res.code ? resolve(res.code) : reject(new Error(res.errMsg));
  204. },
  205. fail: function (_a) {
  206. var errMsg = _a.errMsg;
  207. return reject(new Error(errMsg));
  208. }
  209. });
  210. });
  211. }
  212. var getAuthInfo = function (_a) {
  213. var _b = _a === void 0 ? {} : _a,
  214. _c = _b.platform,
  215. platform = _c === void 0 ? PLATFORM : _c,
  216. _d = _b.preferUnionId,
  217. preferUnionId = _d === void 0 ? false : _d,
  218. _e = _b.asMainAccount,
  219. asMainAccount = _e === void 0 ? false : _e;
  220. return __awaiter(this, void 0, void 0, function () {
  221. var code, authData;
  222. return __generator(this, function (_f) {
  223. switch (_f.label) {
  224. case 0:
  225. return [4
  226. /*yield*/
  227. , getLoginCode()];
  228. case 1:
  229. code = _f.sent();
  230. authData = {
  231. code: code
  232. };
  233. if (preferUnionId) {
  234. authData.platform = platform;
  235. authData.main_account = asMainAccount;
  236. }
  237. return [2
  238. /*return*/
  239. , {
  240. authData: authData,
  241. platform: platform,
  242. provider: PROVIDER
  243. }];
  244. }
  245. });
  246. });
  247. };
  248. var storage = {
  249. getItem: function (key) {
  250. return wx.getStorageSync(key);
  251. },
  252. setItem: function (key, value) {
  253. return wx.setStorageSync(key, value);
  254. },
  255. removeItem: function (key) {
  256. return wx.removeStorageSync(key);
  257. },
  258. clear: function () {
  259. return wx.clearStorageSync();
  260. }
  261. };
  262. var request = function (url, _a) {
  263. var _b = _a === void 0 ? {} : _a,
  264. method = _b.method,
  265. data = _b.data,
  266. headers = _b.headers;
  267. return new Promise(function (resolve, reject) {
  268. return wx.request({
  269. url: url,
  270. method: method,
  271. data: data,
  272. header: headers,
  273. responseType: "text",
  274. success: function (response) {
  275. var status = response.statusCode,
  276. data = response.data,
  277. rest = __rest(response, ["statusCode", "data"]);
  278. resolve(__assign(__assign({}, rest), {
  279. data: typeof data === "string" ? JSON.parse(data) : data,
  280. status: status,
  281. ok: !(status >= 400)
  282. }));
  283. },
  284. fail: function (response) {
  285. reject(new Error(response.errMsg));
  286. }
  287. });
  288. });
  289. };
  290. var upload = function (url, file, _a) {
  291. var _b = _a === void 0 ? {} : _a,
  292. headers = _b.headers,
  293. data = _b.data,
  294. onprogress = _b.onprogress;
  295. if (!(file && file.data && file.data.uri)) {
  296. return Promise.reject(new TypeError("File data must be an object like { uri: localPath }."));
  297. }
  298. return new Promise(function (resolve, reject) {
  299. var _a;
  300. var task = wx.uploadFile({
  301. url: url,
  302. header: headers,
  303. filePath: file.data.uri,
  304. name: file.field,
  305. formData: data,
  306. success: function (response) {
  307. var status = response.statusCode,
  308. data = response.data,
  309. rest = __rest(response, ["statusCode", "data"]);
  310. resolve(__assign(__assign({}, rest), {
  311. data: typeof data === "string" ? JSON.parse(data) : data,
  312. status: status,
  313. ok: !(status >= 400)
  314. }));
  315. },
  316. fail: function (response) {
  317. reject(new Error(response.errMsg));
  318. }
  319. });
  320. (_a = task === null || task === void 0 ? void 0 : task.onProgressUpdate) === null || _a === void 0 ? void 0 : _a.call(task, function (_a) {
  321. var progress = _a.progress,
  322. totalBytesSent = _a.totalBytesSent,
  323. totalBytesExpectedToSend = _a.totalBytesExpectedToSend;
  324. return onprogress === null || onprogress === void 0 ? void 0 : onprogress({
  325. percent: progress,
  326. loaded: totalBytesSent,
  327. total: totalBytesExpectedToSend
  328. });
  329. });
  330. });
  331. };
  332. /**
  333. * @author Toru Nagashima <https://github.com/mysticatea>
  334. * @copyright 2015 Toru Nagashima. All rights reserved.
  335. * See LICENSE file in root directory for full license.
  336. */
  337. /**
  338. * @typedef {object} PrivateData
  339. * @property {EventTarget} eventTarget The event target.
  340. * @property {{type:string}} event The original event object.
  341. * @property {number} eventPhase The current event phase.
  342. * @property {EventTarget|null} currentTarget The current event target.
  343. * @property {boolean} canceled The flag to prevent default.
  344. * @property {boolean} stopped The flag to stop propagation.
  345. * @property {boolean} immediateStopped The flag to stop propagation immediately.
  346. * @property {Function|null} passiveListener The listener if the current listener is passive. Otherwise this is null.
  347. * @property {number} timeStamp The unix time.
  348. * @private
  349. */
  350. /**
  351. * Private data for event wrappers.
  352. * @type {WeakMap<Event, PrivateData>}
  353. * @private
  354. */
  355. const privateData = new WeakMap();
  356. /**
  357. * Cache for wrapper classes.
  358. * @type {WeakMap<Object, Function>}
  359. * @private
  360. */
  361. const wrappers = new WeakMap();
  362. /**
  363. * Get private data.
  364. * @param {Event} event The event object to get private data.
  365. * @returns {PrivateData} The private data of the event.
  366. * @private
  367. */
  368. function pd(event) {
  369. const retv = privateData.get(event);
  370. console.assert(retv != null, "'this' is expected an Event object, but got", event);
  371. return retv;
  372. }
  373. /**
  374. * https://dom.spec.whatwg.org/#set-the-canceled-flag
  375. * @param data {PrivateData} private data.
  376. */
  377. function setCancelFlag(data) {
  378. if (data.passiveListener != null) {
  379. if (typeof console !== "undefined" && typeof console.error === "function") {
  380. console.error("Unable to preventDefault inside passive event listener invocation.", data.passiveListener);
  381. }
  382. return;
  383. }
  384. if (!data.event.cancelable) {
  385. return;
  386. }
  387. data.canceled = true;
  388. if (typeof data.event.preventDefault === "function") {
  389. data.event.preventDefault();
  390. }
  391. }
  392. /**
  393. * @see https://dom.spec.whatwg.org/#interface-event
  394. * @private
  395. */
  396. /**
  397. * The event wrapper.
  398. * @constructor
  399. * @param {EventTarget} eventTarget The event target of this dispatching.
  400. * @param {Event|{type:string}} event The original event to wrap.
  401. */
  402. function Event(eventTarget, event) {
  403. privateData.set(this, {
  404. eventTarget,
  405. event,
  406. eventPhase: 2,
  407. currentTarget: eventTarget,
  408. canceled: false,
  409. stopped: false,
  410. immediateStopped: false,
  411. passiveListener: null,
  412. timeStamp: event.timeStamp || Date.now()
  413. }); // https://heycam.github.io/webidl/#Unforgeable
  414. Object.defineProperty(this, "isTrusted", {
  415. value: false,
  416. enumerable: true
  417. }); // Define accessors
  418. const keys = Object.keys(event);
  419. for (let i = 0; i < keys.length; ++i) {
  420. const key = keys[i];
  421. if (!(key in this)) {
  422. Object.defineProperty(this, key, defineRedirectDescriptor(key));
  423. }
  424. }
  425. } // Should be enumerable, but class methods are not enumerable.
  426. Event.prototype = {
  427. /**
  428. * The type of this event.
  429. * @type {string}
  430. */
  431. get type() {
  432. return pd(this).event.type;
  433. },
  434. /**
  435. * The target of this event.
  436. * @type {EventTarget}
  437. */
  438. get target() {
  439. return pd(this).eventTarget;
  440. },
  441. /**
  442. * The target of this event.
  443. * @type {EventTarget}
  444. */
  445. get currentTarget() {
  446. return pd(this).currentTarget;
  447. },
  448. /**
  449. * @returns {EventTarget[]} The composed path of this event.
  450. */
  451. composedPath() {
  452. const currentTarget = pd(this).currentTarget;
  453. if (currentTarget == null) {
  454. return [];
  455. }
  456. return [currentTarget];
  457. },
  458. /**
  459. * Constant of NONE.
  460. * @type {number}
  461. */
  462. get NONE() {
  463. return 0;
  464. },
  465. /**
  466. * Constant of CAPTURING_PHASE.
  467. * @type {number}
  468. */
  469. get CAPTURING_PHASE() {
  470. return 1;
  471. },
  472. /**
  473. * Constant of AT_TARGET.
  474. * @type {number}
  475. */
  476. get AT_TARGET() {
  477. return 2;
  478. },
  479. /**
  480. * Constant of BUBBLING_PHASE.
  481. * @type {number}
  482. */
  483. get BUBBLING_PHASE() {
  484. return 3;
  485. },
  486. /**
  487. * The target of this event.
  488. * @type {number}
  489. */
  490. get eventPhase() {
  491. return pd(this).eventPhase;
  492. },
  493. /**
  494. * Stop event bubbling.
  495. * @returns {void}
  496. */
  497. stopPropagation() {
  498. const data = pd(this);
  499. data.stopped = true;
  500. if (typeof data.event.stopPropagation === "function") {
  501. data.event.stopPropagation();
  502. }
  503. },
  504. /**
  505. * Stop event bubbling.
  506. * @returns {void}
  507. */
  508. stopImmediatePropagation() {
  509. const data = pd(this);
  510. data.stopped = true;
  511. data.immediateStopped = true;
  512. if (typeof data.event.stopImmediatePropagation === "function") {
  513. data.event.stopImmediatePropagation();
  514. }
  515. },
  516. /**
  517. * The flag to be bubbling.
  518. * @type {boolean}
  519. */
  520. get bubbles() {
  521. return Boolean(pd(this).event.bubbles);
  522. },
  523. /**
  524. * The flag to be cancelable.
  525. * @type {boolean}
  526. */
  527. get cancelable() {
  528. return Boolean(pd(this).event.cancelable);
  529. },
  530. /**
  531. * Cancel this event.
  532. * @returns {void}
  533. */
  534. preventDefault() {
  535. setCancelFlag(pd(this));
  536. },
  537. /**
  538. * The flag to indicate cancellation state.
  539. * @type {boolean}
  540. */
  541. get defaultPrevented() {
  542. return pd(this).canceled;
  543. },
  544. /**
  545. * The flag to be composed.
  546. * @type {boolean}
  547. */
  548. get composed() {
  549. return Boolean(pd(this).event.composed);
  550. },
  551. /**
  552. * The unix time of this event.
  553. * @type {number}
  554. */
  555. get timeStamp() {
  556. return pd(this).timeStamp;
  557. },
  558. /**
  559. * The target of this event.
  560. * @type {EventTarget}
  561. * @deprecated
  562. */
  563. get srcElement() {
  564. return pd(this).eventTarget;
  565. },
  566. /**
  567. * The flag to stop event bubbling.
  568. * @type {boolean}
  569. * @deprecated
  570. */
  571. get cancelBubble() {
  572. return pd(this).stopped;
  573. },
  574. set cancelBubble(value) {
  575. if (!value) {
  576. return;
  577. }
  578. const data = pd(this);
  579. data.stopped = true;
  580. if (typeof data.event.cancelBubble === "boolean") {
  581. data.event.cancelBubble = true;
  582. }
  583. },
  584. /**
  585. * The flag to indicate cancellation state.
  586. * @type {boolean}
  587. * @deprecated
  588. */
  589. get returnValue() {
  590. return !pd(this).canceled;
  591. },
  592. set returnValue(value) {
  593. if (!value) {
  594. setCancelFlag(pd(this));
  595. }
  596. },
  597. /**
  598. * Initialize this event object. But do nothing under event dispatching.
  599. * @param {string} type The event type.
  600. * @param {boolean} [bubbles=false] The flag to be possible to bubble up.
  601. * @param {boolean} [cancelable=false] The flag to be possible to cancel.
  602. * @deprecated
  603. */
  604. initEvent() {// Do nothing.
  605. }
  606. }; // `constructor` is not enumerable.
  607. Object.defineProperty(Event.prototype, "constructor", {
  608. value: Event,
  609. configurable: true,
  610. writable: true
  611. }); // Ensure `event instanceof window.Event` is `true`.
  612. if (typeof window !== "undefined" && typeof window.Event !== "undefined") {
  613. Object.setPrototypeOf(Event.prototype, window.Event.prototype); // Make association for wrappers.
  614. wrappers.set(window.Event.prototype, Event);
  615. }
  616. /**
  617. * Get the property descriptor to redirect a given property.
  618. * @param {string} key Property name to define property descriptor.
  619. * @returns {PropertyDescriptor} The property descriptor to redirect the property.
  620. * @private
  621. */
  622. function defineRedirectDescriptor(key) {
  623. return {
  624. get() {
  625. return pd(this).event[key];
  626. },
  627. set(value) {
  628. pd(this).event[key] = value;
  629. },
  630. configurable: true,
  631. enumerable: true
  632. };
  633. }
  634. /**
  635. * Get the property descriptor to call a given method property.
  636. * @param {string} key Property name to define property descriptor.
  637. * @returns {PropertyDescriptor} The property descriptor to call the method property.
  638. * @private
  639. */
  640. function defineCallDescriptor(key) {
  641. return {
  642. value() {
  643. const event = pd(this).event;
  644. return event[key].apply(event, arguments);
  645. },
  646. configurable: true,
  647. enumerable: true
  648. };
  649. }
  650. /**
  651. * Define new wrapper class.
  652. * @param {Function} BaseEvent The base wrapper class.
  653. * @param {Object} proto The prototype of the original event.
  654. * @returns {Function} The defined wrapper class.
  655. * @private
  656. */
  657. function defineWrapper(BaseEvent, proto) {
  658. const keys = Object.keys(proto);
  659. if (keys.length === 0) {
  660. return BaseEvent;
  661. }
  662. /** CustomEvent */
  663. function CustomEvent(eventTarget, event) {
  664. BaseEvent.call(this, eventTarget, event);
  665. }
  666. CustomEvent.prototype = Object.create(BaseEvent.prototype, {
  667. constructor: {
  668. value: CustomEvent,
  669. configurable: true,
  670. writable: true
  671. }
  672. }); // Define accessors.
  673. for (let i = 0; i < keys.length; ++i) {
  674. const key = keys[i];
  675. if (!(key in BaseEvent.prototype)) {
  676. const descriptor = Object.getOwnPropertyDescriptor(proto, key);
  677. const isFunc = typeof descriptor.value === "function";
  678. Object.defineProperty(CustomEvent.prototype, key, isFunc ? defineCallDescriptor(key) : defineRedirectDescriptor(key));
  679. }
  680. }
  681. return CustomEvent;
  682. }
  683. /**
  684. * Get the wrapper class of a given prototype.
  685. * @param {Object} proto The prototype of the original event to get its wrapper.
  686. * @returns {Function} The wrapper class.
  687. * @private
  688. */
  689. function getWrapper(proto) {
  690. if (proto == null || proto === Object.prototype) {
  691. return Event;
  692. }
  693. let wrapper = wrappers.get(proto);
  694. if (wrapper == null) {
  695. wrapper = defineWrapper(getWrapper(Object.getPrototypeOf(proto)), proto);
  696. wrappers.set(proto, wrapper);
  697. }
  698. return wrapper;
  699. }
  700. /**
  701. * Wrap a given event to management a dispatching.
  702. * @param {EventTarget} eventTarget The event target of this dispatching.
  703. * @param {Object} event The event to wrap.
  704. * @returns {Event} The wrapper instance.
  705. * @private
  706. */
  707. function wrapEvent(eventTarget, event) {
  708. const Wrapper = getWrapper(Object.getPrototypeOf(event));
  709. return new Wrapper(eventTarget, event);
  710. }
  711. /**
  712. * Get the immediateStopped flag of a given event.
  713. * @param {Event} event The event to get.
  714. * @returns {boolean} The flag to stop propagation immediately.
  715. * @private
  716. */
  717. function isStopped(event) {
  718. return pd(event).immediateStopped;
  719. }
  720. /**
  721. * Set the current event phase of a given event.
  722. * @param {Event} event The event to set current target.
  723. * @param {number} eventPhase New event phase.
  724. * @returns {void}
  725. * @private
  726. */
  727. function setEventPhase(event, eventPhase) {
  728. pd(event).eventPhase = eventPhase;
  729. }
  730. /**
  731. * Set the current target of a given event.
  732. * @param {Event} event The event to set current target.
  733. * @param {EventTarget|null} currentTarget New current target.
  734. * @returns {void}
  735. * @private
  736. */
  737. function setCurrentTarget(event, currentTarget) {
  738. pd(event).currentTarget = currentTarget;
  739. }
  740. /**
  741. * Set a passive listener of a given event.
  742. * @param {Event} event The event to set current target.
  743. * @param {Function|null} passiveListener New passive listener.
  744. * @returns {void}
  745. * @private
  746. */
  747. function setPassiveListener(event, passiveListener) {
  748. pd(event).passiveListener = passiveListener;
  749. }
  750. /**
  751. * @typedef {object} ListenerNode
  752. * @property {Function} listener
  753. * @property {1|2|3} listenerType
  754. * @property {boolean} passive
  755. * @property {boolean} once
  756. * @property {ListenerNode|null} next
  757. * @private
  758. */
  759. /**
  760. * @type {WeakMap<object, Map<string, ListenerNode>>}
  761. * @private
  762. */
  763. const listenersMap = new WeakMap(); // Listener types
  764. const CAPTURE = 1;
  765. const BUBBLE = 2;
  766. const ATTRIBUTE = 3;
  767. /**
  768. * Check whether a given value is an object or not.
  769. * @param {any} x The value to check.
  770. * @returns {boolean} `true` if the value is an object.
  771. */
  772. function isObject(x) {
  773. return x !== null && typeof x === "object"; //eslint-disable-line no-restricted-syntax
  774. }
  775. /**
  776. * Get listeners.
  777. * @param {EventTarget} eventTarget The event target to get.
  778. * @returns {Map<string, ListenerNode>} The listeners.
  779. * @private
  780. */
  781. function getListeners(eventTarget) {
  782. const listeners = listenersMap.get(eventTarget);
  783. if (listeners == null) {
  784. throw new TypeError("'this' is expected an EventTarget object, but got another value.");
  785. }
  786. return listeners;
  787. }
  788. /**
  789. * Get the property descriptor for the event attribute of a given event.
  790. * @param {string} eventName The event name to get property descriptor.
  791. * @returns {PropertyDescriptor} The property descriptor.
  792. * @private
  793. */
  794. function defineEventAttributeDescriptor(eventName) {
  795. return {
  796. get() {
  797. const listeners = getListeners(this);
  798. let node = listeners.get(eventName);
  799. while (node != null) {
  800. if (node.listenerType === ATTRIBUTE) {
  801. return node.listener;
  802. }
  803. node = node.next;
  804. }
  805. return null;
  806. },
  807. set(listener) {
  808. if (typeof listener !== "function" && !isObject(listener)) {
  809. listener = null; // eslint-disable-line no-param-reassign
  810. }
  811. const listeners = getListeners(this); // Traverse to the tail while removing old value.
  812. let prev = null;
  813. let node = listeners.get(eventName);
  814. while (node != null) {
  815. if (node.listenerType === ATTRIBUTE) {
  816. // Remove old value.
  817. if (prev !== null) {
  818. prev.next = node.next;
  819. } else if (node.next !== null) {
  820. listeners.set(eventName, node.next);
  821. } else {
  822. listeners.delete(eventName);
  823. }
  824. } else {
  825. prev = node;
  826. }
  827. node = node.next;
  828. } // Add new value.
  829. if (listener !== null) {
  830. const newNode = {
  831. listener,
  832. listenerType: ATTRIBUTE,
  833. passive: false,
  834. once: false,
  835. next: null
  836. };
  837. if (prev === null) {
  838. listeners.set(eventName, newNode);
  839. } else {
  840. prev.next = newNode;
  841. }
  842. }
  843. },
  844. configurable: true,
  845. enumerable: true
  846. };
  847. }
  848. /**
  849. * Define an event attribute (e.g. `eventTarget.onclick`).
  850. * @param {Object} eventTargetPrototype The event target prototype to define an event attrbite.
  851. * @param {string} eventName The event name to define.
  852. * @returns {void}
  853. */
  854. function defineEventAttribute(eventTargetPrototype, eventName) {
  855. Object.defineProperty(eventTargetPrototype, `on${eventName}`, defineEventAttributeDescriptor(eventName));
  856. }
  857. /**
  858. * Define a custom EventTarget with event attributes.
  859. * @param {string[]} eventNames Event names for event attributes.
  860. * @returns {EventTarget} The custom EventTarget.
  861. * @private
  862. */
  863. function defineCustomEventTarget(eventNames) {
  864. /** CustomEventTarget */
  865. function CustomEventTarget() {
  866. EventTarget.call(this);
  867. }
  868. CustomEventTarget.prototype = Object.create(EventTarget.prototype, {
  869. constructor: {
  870. value: CustomEventTarget,
  871. configurable: true,
  872. writable: true
  873. }
  874. });
  875. for (let i = 0; i < eventNames.length; ++i) {
  876. defineEventAttribute(CustomEventTarget.prototype, eventNames[i]);
  877. }
  878. return CustomEventTarget;
  879. }
  880. /**
  881. * EventTarget.
  882. *
  883. * - This is constructor if no arguments.
  884. * - This is a function which returns a CustomEventTarget constructor if there are arguments.
  885. *
  886. * For example:
  887. *
  888. * class A extends EventTarget {}
  889. * class B extends EventTarget("message") {}
  890. * class C extends EventTarget("message", "error") {}
  891. * class D extends EventTarget(["message", "error"]) {}
  892. */
  893. function EventTarget() {
  894. /*eslint-disable consistent-return */
  895. if (this instanceof EventTarget) {
  896. listenersMap.set(this, new Map());
  897. return;
  898. }
  899. if (arguments.length === 1 && Array.isArray(arguments[0])) {
  900. return defineCustomEventTarget(arguments[0]);
  901. }
  902. if (arguments.length > 0) {
  903. const types = new Array(arguments.length);
  904. for (let i = 0; i < arguments.length; ++i) {
  905. types[i] = arguments[i];
  906. }
  907. return defineCustomEventTarget(types);
  908. }
  909. throw new TypeError("Cannot call a class as a function");
  910. /*eslint-enable consistent-return */
  911. } // Should be enumerable, but class methods are not enumerable.
  912. EventTarget.prototype = {
  913. /**
  914. * Add a given listener to this event target.
  915. * @param {string} eventName The event name to add.
  916. * @param {Function} listener The listener to add.
  917. * @param {boolean|{capture?:boolean,passive?:boolean,once?:boolean}} [options] The options for this listener.
  918. * @returns {void}
  919. */
  920. addEventListener(eventName, listener, options) {
  921. if (listener == null) {
  922. return;
  923. }
  924. if (typeof listener !== "function" && !isObject(listener)) {
  925. throw new TypeError("'listener' should be a function or an object.");
  926. }
  927. const listeners = getListeners(this);
  928. const optionsIsObj = isObject(options);
  929. const capture = optionsIsObj ? Boolean(options.capture) : Boolean(options);
  930. const listenerType = capture ? CAPTURE : BUBBLE;
  931. const newNode = {
  932. listener,
  933. listenerType,
  934. passive: optionsIsObj && Boolean(options.passive),
  935. once: optionsIsObj && Boolean(options.once),
  936. next: null
  937. }; // Set it as the first node if the first node is null.
  938. let node = listeners.get(eventName);
  939. if (node === undefined) {
  940. listeners.set(eventName, newNode);
  941. return;
  942. } // Traverse to the tail while checking duplication..
  943. let prev = null;
  944. while (node != null) {
  945. if (node.listener === listener && node.listenerType === listenerType) {
  946. // Should ignore duplication.
  947. return;
  948. }
  949. prev = node;
  950. node = node.next;
  951. } // Add it.
  952. prev.next = newNode;
  953. },
  954. /**
  955. * Remove a given listener from this event target.
  956. * @param {string} eventName The event name to remove.
  957. * @param {Function} listener The listener to remove.
  958. * @param {boolean|{capture?:boolean,passive?:boolean,once?:boolean}} [options] The options for this listener.
  959. * @returns {void}
  960. */
  961. removeEventListener(eventName, listener, options) {
  962. if (listener == null) {
  963. return;
  964. }
  965. const listeners = getListeners(this);
  966. const capture = isObject(options) ? Boolean(options.capture) : Boolean(options);
  967. const listenerType = capture ? CAPTURE : BUBBLE;
  968. let prev = null;
  969. let node = listeners.get(eventName);
  970. while (node != null) {
  971. if (node.listener === listener && node.listenerType === listenerType) {
  972. if (prev !== null) {
  973. prev.next = node.next;
  974. } else if (node.next !== null) {
  975. listeners.set(eventName, node.next);
  976. } else {
  977. listeners.delete(eventName);
  978. }
  979. return;
  980. }
  981. prev = node;
  982. node = node.next;
  983. }
  984. },
  985. /**
  986. * Dispatch a given event.
  987. * @param {Event|{type:string}} event The event to dispatch.
  988. * @returns {boolean} `false` if canceled.
  989. */
  990. dispatchEvent(event) {
  991. if (event == null || typeof event.type !== "string") {
  992. throw new TypeError('"event.type" should be a string.');
  993. } // If listeners aren't registered, terminate.
  994. const listeners = getListeners(this);
  995. const eventName = event.type;
  996. let node = listeners.get(eventName);
  997. if (node == null) {
  998. return true;
  999. } // Since we cannot rewrite several properties, so wrap object.
  1000. const wrappedEvent = wrapEvent(this, event); // This doesn't process capturing phase and bubbling phase.
  1001. // This isn't participating in a tree.
  1002. let prev = null;
  1003. while (node != null) {
  1004. // Remove this listener if it's once
  1005. if (node.once) {
  1006. if (prev !== null) {
  1007. prev.next = node.next;
  1008. } else if (node.next !== null) {
  1009. listeners.set(eventName, node.next);
  1010. } else {
  1011. listeners.delete(eventName);
  1012. }
  1013. } else {
  1014. prev = node;
  1015. } // Call this listener
  1016. setPassiveListener(wrappedEvent, node.passive ? node.listener : null);
  1017. if (typeof node.listener === "function") {
  1018. try {
  1019. node.listener.call(this, wrappedEvent);
  1020. } catch (err) {
  1021. if (typeof console !== "undefined" && typeof console.error === "function") {
  1022. console.error(err);
  1023. }
  1024. }
  1025. } else if (node.listenerType !== ATTRIBUTE && typeof node.listener.handleEvent === "function") {
  1026. node.listener.handleEvent(wrappedEvent);
  1027. } // Break if `event.stopImmediatePropagation` was called.
  1028. if (isStopped(wrappedEvent)) {
  1029. break;
  1030. }
  1031. node = node.next;
  1032. }
  1033. setPassiveListener(wrappedEvent, null);
  1034. setEventPhase(wrappedEvent, 0);
  1035. setCurrentTarget(wrappedEvent, null);
  1036. return !wrappedEvent.defaultPrevented;
  1037. }
  1038. }; // `constructor` is not enumerable.
  1039. Object.defineProperty(EventTarget.prototype, "constructor", {
  1040. value: EventTarget,
  1041. configurable: true,
  1042. writable: true
  1043. }); // Ensure `eventTarget instanceof window.EventTarget` is `true`.
  1044. if (typeof window !== "undefined" && typeof window.EventTarget !== "undefined") {
  1045. Object.setPrototypeOf(EventTarget.prototype, window.EventTarget.prototype);
  1046. }
  1047. var EVENTS = ["open", "error", "message", "close"];
  1048. var WS =
  1049. /** @class */
  1050. function (_super) {
  1051. __extends(WS, _super);
  1052. function WS(url, protocol) {
  1053. var _this = this;
  1054. if (!url) {
  1055. throw new TypeError("Failed to construct 'WebSocket': url required");
  1056. }
  1057. if (protocol && !(wx.canIUse && wx.canIUse("connectSocket.object.protocols"))) {
  1058. throw new Error("subprotocol not supported in weapp");
  1059. }
  1060. _this = _super.call(this) || this;
  1061. _this._url = url;
  1062. _this._protocol = protocol;
  1063. _this._readyState = WS.CONNECTING;
  1064. var errorHandler = function (event) {
  1065. _this._readyState = WS.CLOSED;
  1066. _this.dispatchEvent({
  1067. type: "error",
  1068. message: event.errMsg
  1069. });
  1070. };
  1071. var socketTask = wx.connectSocket({
  1072. url: url,
  1073. protocols: _this._protocol === undefined || Array.isArray(_this._protocol) ? _this._protocol : [_this._protocol],
  1074. fail: function (error) {
  1075. return setTimeout(function () {
  1076. return errorHandler(error);
  1077. }, 0);
  1078. }
  1079. });
  1080. _this._socketTask = socketTask;
  1081. socketTask.onOpen(function (event) {
  1082. _this._readyState = WS.OPEN;
  1083. _this.dispatchEvent({
  1084. type: "open"
  1085. });
  1086. });
  1087. socketTask.onError(errorHandler);
  1088. socketTask.onMessage(function (event) {
  1089. var data = event.data;
  1090. _this.dispatchEvent({
  1091. data: data,
  1092. type: "message"
  1093. });
  1094. });
  1095. socketTask.onClose(function (event) {
  1096. _this._readyState = WS.CLOSED;
  1097. var code = event.code,
  1098. reason = event.reason;
  1099. _this.dispatchEvent({
  1100. code: code,
  1101. reason: reason,
  1102. type: "close"
  1103. });
  1104. });
  1105. return _this;
  1106. }
  1107. Object.defineProperty(WS.prototype, "url", {
  1108. get: function () {
  1109. return this._url;
  1110. },
  1111. enumerable: true,
  1112. configurable: true
  1113. });
  1114. Object.defineProperty(WS.prototype, "protocol", {
  1115. get: function () {
  1116. return this._protocol;
  1117. },
  1118. enumerable: true,
  1119. configurable: true
  1120. });
  1121. Object.defineProperty(WS.prototype, "readyState", {
  1122. get: function () {
  1123. return this._readyState;
  1124. },
  1125. enumerable: true,
  1126. configurable: true
  1127. });
  1128. WS.prototype.close = function () {
  1129. if (this.readyState === WS.CLOSED) return;
  1130. if (this.readyState === WS.CONNECTING) {
  1131. console.warn("close WebSocket which is connecting might not work");
  1132. }
  1133. this._socketTask.close({});
  1134. };
  1135. WS.prototype.send = function (data) {
  1136. if (this.readyState !== WS.OPEN) {
  1137. throw new Error("INVALID_STATE_ERR");
  1138. }
  1139. if (!(typeof data === "string" || data instanceof ArrayBuffer)) {
  1140. throw new TypeError("only String/ArrayBuffer supported");
  1141. }
  1142. this._socketTask.send({
  1143. data: data
  1144. });
  1145. };
  1146. WS.CONNECTING = 0;
  1147. WS.OPEN = 1;
  1148. WS.CLOSING = 2;
  1149. WS.CLOSED = 3;
  1150. return WS;
  1151. }(EventTarget(EVENTS));
  1152. var WebSocket = WS;
  1153. var platformInfo = {
  1154. name: "Weapp"
  1155. };
  1156. exports.WebSocket = WebSocket;
  1157. exports.getAuthInfo = getAuthInfo;
  1158. exports.platformInfo = platformInfo;
  1159. exports.request = request;
  1160. exports.storage = storage;
  1161. exports.upload = upload;
  1162. });
  1163. unwrapExports(lib);
  1164. var lib_1 = lib.WebSocket;
  1165. var lib_2 = lib.getAuthInfo;
  1166. var lib_3 = lib.platformInfo;
  1167. var lib_4 = lib.request;
  1168. var lib_5 = lib.storage;
  1169. var lib_6 = lib.upload;
  1170. var long_1 = createCommonjsModule(function (module) {
  1171. /*
  1172. Copyright 2013 Daniel Wirtz <dcode@dcode.io>
  1173. Copyright 2009 The Closure Library Authors. All Rights Reserved.
  1174. Licensed under the Apache License, Version 2.0 (the "License");
  1175. you may not use this file except in compliance with the License.
  1176. You may obtain a copy of the License at
  1177. http://www.apache.org/licenses/LICENSE-2.0
  1178. Unless required by applicable law or agreed to in writing, software
  1179. distributed under the License is distributed on an "AS-IS" BASIS,
  1180. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1181. See the License for the specific language governing permissions and
  1182. limitations under the License.
  1183. */
  1184. /**
  1185. * @license long.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
  1186. * Released under the Apache License, Version 2.0
  1187. * see: https://github.com/dcodeIO/long.js for details
  1188. */
  1189. (function(global, factory) {
  1190. /* AMD */ if (typeof commonjsRequire === 'function' && 'object' === "object" && module && module["exports"])
  1191. module["exports"] = factory();
  1192. /* Global */ else
  1193. (global["dcodeIO"] = global["dcodeIO"] || {})["Long"] = factory();
  1194. })(commonjsGlobal, function() {
  1195. /**
  1196. * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers.
  1197. * See the from* functions below for more convenient ways of constructing Longs.
  1198. * @exports Long
  1199. * @class A Long class for representing a 64 bit two's-complement integer value.
  1200. * @param {number} low The low (signed) 32 bits of the long
  1201. * @param {number} high The high (signed) 32 bits of the long
  1202. * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
  1203. * @constructor
  1204. */
  1205. function Long(low, high, unsigned) {
  1206. /**
  1207. * The low 32 bits as a signed value.
  1208. * @type {number}
  1209. */
  1210. this.low = low | 0;
  1211. /**
  1212. * The high 32 bits as a signed value.
  1213. * @type {number}
  1214. */
  1215. this.high = high | 0;
  1216. /**
  1217. * Whether unsigned or not.
  1218. * @type {boolean}
  1219. */
  1220. this.unsigned = !!unsigned;
  1221. }
  1222. // The internal representation of a long is the two given signed, 32-bit values.
  1223. // We use 32-bit pieces because these are the size of integers on which
  1224. // Javascript performs bit-operations. For operations like addition and
  1225. // multiplication, we split each number into 16 bit pieces, which can easily be
  1226. // multiplied within Javascript's floating-point representation without overflow
  1227. // or change in sign.
  1228. //
  1229. // In the algorithms below, we frequently reduce the negative case to the
  1230. // positive case by negating the input(s) and then post-processing the result.
  1231. // Note that we must ALWAYS check specially whether those values are MIN_VALUE
  1232. // (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
  1233. // a positive number, it overflows back into a negative). Not handling this
  1234. // case would often result in infinite recursion.
  1235. //
  1236. // Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from*
  1237. // methods on which they depend.
  1238. /**
  1239. * An indicator used to reliably determine if an object is a Long or not.
  1240. * @type {boolean}
  1241. * @const
  1242. * @private
  1243. */
  1244. Long.prototype.__isLong__;
  1245. Object.defineProperty(Long.prototype, "__isLong__", {
  1246. value: true,
  1247. enumerable: false,
  1248. configurable: false
  1249. });
  1250. /**
  1251. * @function
  1252. * @param {*} obj Object
  1253. * @returns {boolean}
  1254. * @inner
  1255. */
  1256. function isLong(obj) {
  1257. return (obj && obj["__isLong__"]) === true;
  1258. }
  1259. /**
  1260. * Tests if the specified object is a Long.
  1261. * @function
  1262. * @param {*} obj Object
  1263. * @returns {boolean}
  1264. */
  1265. Long.isLong = isLong;
  1266. /**
  1267. * A cache of the Long representations of small integer values.
  1268. * @type {!Object}
  1269. * @inner
  1270. */
  1271. var INT_CACHE = {};
  1272. /**
  1273. * A cache of the Long representations of small unsigned integer values.
  1274. * @type {!Object}
  1275. * @inner
  1276. */
  1277. var UINT_CACHE = {};
  1278. /**
  1279. * @param {number} value
  1280. * @param {boolean=} unsigned
  1281. * @returns {!Long}
  1282. * @inner
  1283. */
  1284. function fromInt(value, unsigned) {
  1285. var obj, cachedObj, cache;
  1286. if (unsigned) {
  1287. value >>>= 0;
  1288. if (cache = (0 <= value && value < 256)) {
  1289. cachedObj = UINT_CACHE[value];
  1290. if (cachedObj)
  1291. return cachedObj;
  1292. }
  1293. obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true);
  1294. if (cache)
  1295. UINT_CACHE[value] = obj;
  1296. return obj;
  1297. } else {
  1298. value |= 0;
  1299. if (cache = (-128 <= value && value < 128)) {
  1300. cachedObj = INT_CACHE[value];
  1301. if (cachedObj)
  1302. return cachedObj;
  1303. }
  1304. obj = fromBits(value, value < 0 ? -1 : 0, false);
  1305. if (cache)
  1306. INT_CACHE[value] = obj;
  1307. return obj;
  1308. }
  1309. }
  1310. /**
  1311. * Returns a Long representing the given 32 bit integer value.
  1312. * @function
  1313. * @param {number} value The 32 bit integer in question
  1314. * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
  1315. * @returns {!Long} The corresponding Long value
  1316. */
  1317. Long.fromInt = fromInt;
  1318. /**
  1319. * @param {number} value
  1320. * @param {boolean=} unsigned
  1321. * @returns {!Long}
  1322. * @inner
  1323. */
  1324. function fromNumber(value, unsigned) {
  1325. if (isNaN(value) || !isFinite(value))
  1326. return unsigned ? UZERO : ZERO;
  1327. if (unsigned) {
  1328. if (value < 0)
  1329. return UZERO;
  1330. if (value >= TWO_PWR_64_DBL)
  1331. return MAX_UNSIGNED_VALUE;
  1332. } else {
  1333. if (value <= -TWO_PWR_63_DBL)
  1334. return MIN_VALUE;
  1335. if (value + 1 >= TWO_PWR_63_DBL)
  1336. return MAX_VALUE;
  1337. }
  1338. if (value < 0)
  1339. return fromNumber(-value, unsigned).neg();
  1340. return fromBits((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned);
  1341. }
  1342. /**
  1343. * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.
  1344. * @function
  1345. * @param {number} value The number in question
  1346. * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
  1347. * @returns {!Long} The corresponding Long value
  1348. */
  1349. Long.fromNumber = fromNumber;
  1350. /**
  1351. * @param {number} lowBits
  1352. * @param {number} highBits
  1353. * @param {boolean=} unsigned
  1354. * @returns {!Long}
  1355. * @inner
  1356. */
  1357. function fromBits(lowBits, highBits, unsigned) {
  1358. return new Long(lowBits, highBits, unsigned);
  1359. }
  1360. /**
  1361. * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is
  1362. * assumed to use 32 bits.
  1363. * @function
  1364. * @param {number} lowBits The low 32 bits
  1365. * @param {number} highBits The high 32 bits
  1366. * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
  1367. * @returns {!Long} The corresponding Long value
  1368. */
  1369. Long.fromBits = fromBits;
  1370. /**
  1371. * @function
  1372. * @param {number} base
  1373. * @param {number} exponent
  1374. * @returns {number}
  1375. * @inner
  1376. */
  1377. var pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4)
  1378. /**
  1379. * @param {string} str
  1380. * @param {(boolean|number)=} unsigned
  1381. * @param {number=} radix
  1382. * @returns {!Long}
  1383. * @inner
  1384. */
  1385. function fromString(str, unsigned, radix) {
  1386. if (str.length === 0)
  1387. throw Error('empty string');
  1388. if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity")
  1389. return ZERO;
  1390. if (typeof unsigned === 'number') {
  1391. // For goog.math.long compatibility
  1392. radix = unsigned,
  1393. unsigned = false;
  1394. } else {
  1395. unsigned = !! unsigned;
  1396. }
  1397. radix = radix || 10;
  1398. if (radix < 2 || 36 < radix)
  1399. throw RangeError('radix');
  1400. var p;
  1401. if ((p = str.indexOf('-')) > 0)
  1402. throw Error('interior hyphen');
  1403. else if (p === 0) {
  1404. return fromString(str.substring(1), unsigned, radix).neg();
  1405. }
  1406. // Do several (8) digits each time through the loop, so as to
  1407. // minimize the calls to the very expensive emulated div.
  1408. var radixToPower = fromNumber(pow_dbl(radix, 8));
  1409. var result = ZERO;
  1410. for (var i = 0; i < str.length; i += 8) {
  1411. var size = Math.min(8, str.length - i),
  1412. value = parseInt(str.substring(i, i + size), radix);
  1413. if (size < 8) {
  1414. var power = fromNumber(pow_dbl(radix, size));
  1415. result = result.mul(power).add(fromNumber(value));
  1416. } else {
  1417. result = result.mul(radixToPower);
  1418. result = result.add(fromNumber(value));
  1419. }
  1420. }
  1421. result.unsigned = unsigned;
  1422. return result;
  1423. }
  1424. /**
  1425. * Returns a Long representation of the given string, written using the specified radix.
  1426. * @function
  1427. * @param {string} str The textual representation of the Long
  1428. * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed
  1429. * @param {number=} radix The radix in which the text is written (2-36), defaults to 10
  1430. * @returns {!Long} The corresponding Long value
  1431. */
  1432. Long.fromString = fromString;
  1433. /**
  1434. * @function
  1435. * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val
  1436. * @returns {!Long}
  1437. * @inner
  1438. */
  1439. function fromValue(val) {
  1440. if (val /* is compatible */ instanceof Long)
  1441. return val;
  1442. if (typeof val === 'number')
  1443. return fromNumber(val);
  1444. if (typeof val === 'string')
  1445. return fromString(val);
  1446. // Throws for non-objects, converts non-instanceof Long:
  1447. return fromBits(val.low, val.high, val.unsigned);
  1448. }
  1449. /**
  1450. * Converts the specified value to a Long.
  1451. * @function
  1452. * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value
  1453. * @returns {!Long}
  1454. */
  1455. Long.fromValue = fromValue;
  1456. // NOTE: the compiler should inline these constant values below and then remove these variables, so there should be
  1457. // no runtime penalty for these.
  1458. /**
  1459. * @type {number}
  1460. * @const
  1461. * @inner
  1462. */
  1463. var TWO_PWR_16_DBL = 1 << 16;
  1464. /**
  1465. * @type {number}
  1466. * @const
  1467. * @inner
  1468. */
  1469. var TWO_PWR_24_DBL = 1 << 24;
  1470. /**
  1471. * @type {number}
  1472. * @const
  1473. * @inner
  1474. */
  1475. var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;
  1476. /**
  1477. * @type {number}
  1478. * @const
  1479. * @inner
  1480. */
  1481. var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;
  1482. /**
  1483. * @type {number}
  1484. * @const
  1485. * @inner
  1486. */
  1487. var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;
  1488. /**
  1489. * @type {!Long}
  1490. * @const
  1491. * @inner
  1492. */
  1493. var TWO_PWR_24 = fromInt(TWO_PWR_24_DBL);
  1494. /**
  1495. * @type {!Long}
  1496. * @inner
  1497. */
  1498. var ZERO = fromInt(0);
  1499. /**
  1500. * Signed zero.
  1501. * @type {!Long}
  1502. */
  1503. Long.ZERO = ZERO;
  1504. /**
  1505. * @type {!Long}
  1506. * @inner
  1507. */
  1508. var UZERO = fromInt(0, true);
  1509. /**
  1510. * Unsigned zero.
  1511. * @type {!Long}
  1512. */
  1513. Long.UZERO = UZERO;
  1514. /**
  1515. * @type {!Long}
  1516. * @inner
  1517. */
  1518. var ONE = fromInt(1);
  1519. /**
  1520. * Signed one.
  1521. * @type {!Long}
  1522. */
  1523. Long.ONE = ONE;
  1524. /**
  1525. * @type {!Long}
  1526. * @inner
  1527. */
  1528. var UONE = fromInt(1, true);
  1529. /**
  1530. * Unsigned one.
  1531. * @type {!Long}
  1532. */
  1533. Long.UONE = UONE;
  1534. /**
  1535. * @type {!Long}
  1536. * @inner
  1537. */
  1538. var NEG_ONE = fromInt(-1);
  1539. /**
  1540. * Signed negative one.
  1541. * @type {!Long}
  1542. */
  1543. Long.NEG_ONE = NEG_ONE;
  1544. /**
  1545. * @type {!Long}
  1546. * @inner
  1547. */
  1548. var MAX_VALUE = fromBits(0xFFFFFFFF|0, 0x7FFFFFFF|0, false);
  1549. /**
  1550. * Maximum signed value.
  1551. * @type {!Long}
  1552. */
  1553. Long.MAX_VALUE = MAX_VALUE;
  1554. /**
  1555. * @type {!Long}
  1556. * @inner
  1557. */
  1558. var MAX_UNSIGNED_VALUE = fromBits(0xFFFFFFFF|0, 0xFFFFFFFF|0, true);
  1559. /**
  1560. * Maximum unsigned value.
  1561. * @type {!Long}
  1562. */
  1563. Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE;
  1564. /**
  1565. * @type {!Long}
  1566. * @inner
  1567. */
  1568. var MIN_VALUE = fromBits(0, 0x80000000|0, false);
  1569. /**
  1570. * Minimum signed value.
  1571. * @type {!Long}
  1572. */
  1573. Long.MIN_VALUE = MIN_VALUE;
  1574. /**
  1575. * @alias Long.prototype
  1576. * @inner
  1577. */
  1578. var LongPrototype = Long.prototype;
  1579. /**
  1580. * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.
  1581. * @returns {number}
  1582. */
  1583. LongPrototype.toInt = function toInt() {
  1584. return this.unsigned ? this.low >>> 0 : this.low;
  1585. };
  1586. /**
  1587. * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).
  1588. * @returns {number}
  1589. */
  1590. LongPrototype.toNumber = function toNumber() {
  1591. if (this.unsigned)
  1592. return ((this.high >>> 0) * TWO_PWR_32_DBL) + (this.low >>> 0);
  1593. return this.high * TWO_PWR_32_DBL + (this.low >>> 0);
  1594. };
  1595. /**
  1596. * Converts the Long to a string written in the specified radix.
  1597. * @param {number=} radix Radix (2-36), defaults to 10
  1598. * @returns {string}
  1599. * @override
  1600. * @throws {RangeError} If `radix` is out of range
  1601. */
  1602. LongPrototype.toString = function toString(radix) {
  1603. radix = radix || 10;
  1604. if (radix < 2 || 36 < radix)
  1605. throw RangeError('radix');
  1606. if (this.isZero())
  1607. return '0';
  1608. if (this.isNegative()) { // Unsigned Longs are never negative
  1609. if (this.eq(MIN_VALUE)) {
  1610. // We need to change the Long value before it can be negated, so we remove
  1611. // the bottom-most digit in this base and then recurse to do the rest.
  1612. var radixLong = fromNumber(radix),
  1613. div = this.div(radixLong),
  1614. rem1 = div.mul(radixLong).sub(this);
  1615. return div.toString(radix) + rem1.toInt().toString(radix);
  1616. } else
  1617. return '-' + this.neg().toString(radix);
  1618. }
  1619. // Do several (6) digits each time through the loop, so as to
  1620. // minimize the calls to the very expensive emulated div.
  1621. var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned),
  1622. rem = this;
  1623. var result = '';
  1624. while (true) {
  1625. var remDiv = rem.div(radixToPower),
  1626. intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0,
  1627. digits = intval.toString(radix);
  1628. rem = remDiv;
  1629. if (rem.isZero())
  1630. return digits + result;
  1631. else {
  1632. while (digits.length < 6)
  1633. digits = '0' + digits;
  1634. result = '' + digits + result;
  1635. }
  1636. }
  1637. };
  1638. /**
  1639. * Gets the high 32 bits as a signed integer.
  1640. * @returns {number} Signed high bits
  1641. */
  1642. LongPrototype.getHighBits = function getHighBits() {
  1643. return this.high;
  1644. };
  1645. /**
  1646. * Gets the high 32 bits as an unsigned integer.
  1647. * @returns {number} Unsigned high bits
  1648. */
  1649. LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() {
  1650. return this.high >>> 0;
  1651. };
  1652. /**
  1653. * Gets the low 32 bits as a signed integer.
  1654. * @returns {number} Signed low bits
  1655. */
  1656. LongPrototype.getLowBits = function getLowBits() {
  1657. return this.low;
  1658. };
  1659. /**
  1660. * Gets the low 32 bits as an unsigned integer.
  1661. * @returns {number} Unsigned low bits
  1662. */
  1663. LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() {
  1664. return this.low >>> 0;
  1665. };
  1666. /**
  1667. * Gets the number of bits needed to represent the absolute value of this Long.
  1668. * @returns {number}
  1669. */
  1670. LongPrototype.getNumBitsAbs = function getNumBitsAbs() {
  1671. if (this.isNegative()) // Unsigned Longs are never negative
  1672. return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs();
  1673. var val = this.high != 0 ? this.high : this.low;
  1674. for (var bit = 31; bit > 0; bit--)
  1675. if ((val & (1 << bit)) != 0)
  1676. break;
  1677. return this.high != 0 ? bit + 33 : bit + 1;
  1678. };
  1679. /**
  1680. * Tests if this Long's value equals zero.
  1681. * @returns {boolean}
  1682. */
  1683. LongPrototype.isZero = function isZero() {
  1684. return this.high === 0 && this.low === 0;
  1685. };
  1686. /**
  1687. * Tests if this Long's value is negative.
  1688. * @returns {boolean}
  1689. */
  1690. LongPrototype.isNegative = function isNegative() {
  1691. return !this.unsigned && this.high < 0;
  1692. };
  1693. /**
  1694. * Tests if this Long's value is positive.
  1695. * @returns {boolean}
  1696. */
  1697. LongPrototype.isPositive = function isPositive() {
  1698. return this.unsigned || this.high >= 0;
  1699. };
  1700. /**
  1701. * Tests if this Long's value is odd.
  1702. * @returns {boolean}
  1703. */
  1704. LongPrototype.isOdd = function isOdd() {
  1705. return (this.low & 1) === 1;
  1706. };
  1707. /**
  1708. * Tests if this Long's value is even.
  1709. * @returns {boolean}
  1710. */
  1711. LongPrototype.isEven = function isEven() {
  1712. return (this.low & 1) === 0;
  1713. };
  1714. /**
  1715. * Tests if this Long's value equals the specified's.
  1716. * @param {!Long|number|string} other Other value
  1717. * @returns {boolean}
  1718. */
  1719. LongPrototype.equals = function equals(other) {
  1720. if (!isLong(other))
  1721. other = fromValue(other);
  1722. if (this.unsigned !== other.unsigned && (this.high >>> 31) === 1 && (other.high >>> 31) === 1)
  1723. return false;
  1724. return this.high === other.high && this.low === other.low;
  1725. };
  1726. /**
  1727. * Tests if this Long's value equals the specified's. This is an alias of {@link Long#equals}.
  1728. * @function
  1729. * @param {!Long|number|string} other Other value
  1730. * @returns {boolean}
  1731. */
  1732. LongPrototype.eq = LongPrototype.equals;
  1733. /**
  1734. * Tests if this Long's value differs from the specified's.
  1735. * @param {!Long|number|string} other Other value
  1736. * @returns {boolean}
  1737. */
  1738. LongPrototype.notEquals = function notEquals(other) {
  1739. return !this.eq(/* validates */ other);
  1740. };
  1741. /**
  1742. * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}.
  1743. * @function
  1744. * @param {!Long|number|string} other Other value
  1745. * @returns {boolean}
  1746. */
  1747. LongPrototype.neq = LongPrototype.notEquals;
  1748. /**
  1749. * Tests if this Long's value is less than the specified's.
  1750. * @param {!Long|number|string} other Other value
  1751. * @returns {boolean}
  1752. */
  1753. LongPrototype.lessThan = function lessThan(other) {
  1754. return this.comp(/* validates */ other) < 0;
  1755. };
  1756. /**
  1757. * Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}.
  1758. * @function
  1759. * @param {!Long|number|string} other Other value
  1760. * @returns {boolean}
  1761. */
  1762. LongPrototype.lt = LongPrototype.lessThan;
  1763. /**
  1764. * Tests if this Long's value is less than or equal the specified's.
  1765. * @param {!Long|number|string} other Other value
  1766. * @returns {boolean}
  1767. */
  1768. LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) {
  1769. return this.comp(/* validates */ other) <= 0;
  1770. };
  1771. /**
  1772. * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.
  1773. * @function
  1774. * @param {!Long|number|string} other Other value
  1775. * @returns {boolean}
  1776. */
  1777. LongPrototype.lte = LongPrototype.lessThanOrEqual;
  1778. /**
  1779. * Tests if this Long's value is greater than the specified's.
  1780. * @param {!Long|number|string} other Other value
  1781. * @returns {boolean}
  1782. */
  1783. LongPrototype.greaterThan = function greaterThan(other) {
  1784. return this.comp(/* validates */ other) > 0;
  1785. };
  1786. /**
  1787. * Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}.
  1788. * @function
  1789. * @param {!Long|number|string} other Other value
  1790. * @returns {boolean}
  1791. */
  1792. LongPrototype.gt = LongPrototype.greaterThan;
  1793. /**
  1794. * Tests if this Long's value is greater than or equal the specified's.
  1795. * @param {!Long|number|string} other Other value
  1796. * @returns {boolean}
  1797. */
  1798. LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) {
  1799. return this.comp(/* validates */ other) >= 0;
  1800. };
  1801. /**
  1802. * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.
  1803. * @function
  1804. * @param {!Long|number|string} other Other value
  1805. * @returns {boolean}
  1806. */
  1807. LongPrototype.gte = LongPrototype.greaterThanOrEqual;
  1808. /**
  1809. * Compares this Long's value with the specified's.
  1810. * @param {!Long|number|string} other Other value
  1811. * @returns {number} 0 if they are the same, 1 if the this is greater and -1
  1812. * if the given one is greater
  1813. */
  1814. LongPrototype.compare = function compare(other) {
  1815. if (!isLong(other))
  1816. other = fromValue(other);
  1817. if (this.eq(other))
  1818. return 0;
  1819. var thisNeg = this.isNegative(),
  1820. otherNeg = other.isNegative();
  1821. if (thisNeg && !otherNeg)
  1822. return -1;
  1823. if (!thisNeg && otherNeg)
  1824. return 1;
  1825. // At this point the sign bits are the same
  1826. if (!this.unsigned)
  1827. return this.sub(other).isNegative() ? -1 : 1;
  1828. // Both are positive if at least one is unsigned
  1829. return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1;
  1830. };
  1831. /**
  1832. * Compares this Long's value with the specified's. This is an alias of {@link Long#compare}.
  1833. * @function
  1834. * @param {!Long|number|string} other Other value
  1835. * @returns {number} 0 if they are the same, 1 if the this is greater and -1
  1836. * if the given one is greater
  1837. */
  1838. LongPrototype.comp = LongPrototype.compare;
  1839. /**
  1840. * Negates this Long's value.
  1841. * @returns {!Long} Negated Long
  1842. */
  1843. LongPrototype.negate = function negate() {
  1844. if (!this.unsigned && this.eq(MIN_VALUE))
  1845. return MIN_VALUE;
  1846. return this.not().add(ONE);
  1847. };
  1848. /**
  1849. * Negates this Long's value. This is an alias of {@link Long#negate}.
  1850. * @function
  1851. * @returns {!Long} Negated Long
  1852. */
  1853. LongPrototype.neg = LongPrototype.negate;
  1854. /**
  1855. * Returns the sum of this and the specified Long.
  1856. * @param {!Long|number|string} addend Addend
  1857. * @returns {!Long} Sum
  1858. */
  1859. LongPrototype.add = function add(addend) {
  1860. if (!isLong(addend))
  1861. addend = fromValue(addend);
  1862. // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
  1863. var a48 = this.high >>> 16;
  1864. var a32 = this.high & 0xFFFF;
  1865. var a16 = this.low >>> 16;
  1866. var a00 = this.low & 0xFFFF;
  1867. var b48 = addend.high >>> 16;
  1868. var b32 = addend.high & 0xFFFF;
  1869. var b16 = addend.low >>> 16;
  1870. var b00 = addend.low & 0xFFFF;
  1871. var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
  1872. c00 += a00 + b00;
  1873. c16 += c00 >>> 16;
  1874. c00 &= 0xFFFF;
  1875. c16 += a16 + b16;
  1876. c32 += c16 >>> 16;
  1877. c16 &= 0xFFFF;
  1878. c32 += a32 + b32;
  1879. c48 += c32 >>> 16;
  1880. c32 &= 0xFFFF;
  1881. c48 += a48 + b48;
  1882. c48 &= 0xFFFF;
  1883. return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
  1884. };
  1885. /**
  1886. * Returns the difference of this and the specified Long.
  1887. * @param {!Long|number|string} subtrahend Subtrahend
  1888. * @returns {!Long} Difference
  1889. */
  1890. LongPrototype.subtract = function subtract(subtrahend) {
  1891. if (!isLong(subtrahend))
  1892. subtrahend = fromValue(subtrahend);
  1893. return this.add(subtrahend.neg());
  1894. };
  1895. /**
  1896. * Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}.
  1897. * @function
  1898. * @param {!Long|number|string} subtrahend Subtrahend
  1899. * @returns {!Long} Difference
  1900. */
  1901. LongPrototype.sub = LongPrototype.subtract;
  1902. /**
  1903. * Returns the product of this and the specified Long.
  1904. * @param {!Long|number|string} multiplier Multiplier
  1905. * @returns {!Long} Product
  1906. */
  1907. LongPrototype.multiply = function multiply(multiplier) {
  1908. if (this.isZero())
  1909. return ZERO;
  1910. if (!isLong(multiplier))
  1911. multiplier = fromValue(multiplier);
  1912. if (multiplier.isZero())
  1913. return ZERO;
  1914. if (this.eq(MIN_VALUE))
  1915. return multiplier.isOdd() ? MIN_VALUE : ZERO;
  1916. if (multiplier.eq(MIN_VALUE))
  1917. return this.isOdd() ? MIN_VALUE : ZERO;
  1918. if (this.isNegative()) {
  1919. if (multiplier.isNegative())
  1920. return this.neg().mul(multiplier.neg());
  1921. else
  1922. return this.neg().mul(multiplier).neg();
  1923. } else if (multiplier.isNegative())
  1924. return this.mul(multiplier.neg()).neg();
  1925. // If both longs are small, use float multiplication
  1926. if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24))
  1927. return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned);
  1928. // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
  1929. // We can skip products that would overflow.
  1930. var a48 = this.high >>> 16;
  1931. var a32 = this.high & 0xFFFF;
  1932. var a16 = this.low >>> 16;
  1933. var a00 = this.low & 0xFFFF;
  1934. var b48 = multiplier.high >>> 16;
  1935. var b32 = multiplier.high & 0xFFFF;
  1936. var b16 = multiplier.low >>> 16;
  1937. var b00 = multiplier.low & 0xFFFF;
  1938. var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
  1939. c00 += a00 * b00;
  1940. c16 += c00 >>> 16;
  1941. c00 &= 0xFFFF;
  1942. c16 += a16 * b00;
  1943. c32 += c16 >>> 16;
  1944. c16 &= 0xFFFF;
  1945. c16 += a00 * b16;
  1946. c32 += c16 >>> 16;
  1947. c16 &= 0xFFFF;
  1948. c32 += a32 * b00;
  1949. c48 += c32 >>> 16;
  1950. c32 &= 0xFFFF;
  1951. c32 += a16 * b16;
  1952. c48 += c32 >>> 16;
  1953. c32 &= 0xFFFF;
  1954. c32 += a00 * b32;
  1955. c48 += c32 >>> 16;
  1956. c32 &= 0xFFFF;
  1957. c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
  1958. c48 &= 0xFFFF;
  1959. return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
  1960. };
  1961. /**
  1962. * Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}.
  1963. * @function
  1964. * @param {!Long|number|string} multiplier Multiplier
  1965. * @returns {!Long} Product
  1966. */
  1967. LongPrototype.mul = LongPrototype.multiply;
  1968. /**
  1969. * Returns this Long divided by the specified. The result is signed if this Long is signed or
  1970. * unsigned if this Long is unsigned.
  1971. * @param {!Long|number|string} divisor Divisor
  1972. * @returns {!Long} Quotient
  1973. */
  1974. LongPrototype.divide = function divide(divisor) {
  1975. if (!isLong(divisor))
  1976. divisor = fromValue(divisor);
  1977. if (divisor.isZero())
  1978. throw Error('division by zero');
  1979. if (this.isZero())
  1980. return this.unsigned ? UZERO : ZERO;
  1981. var approx, rem, res;
  1982. if (!this.unsigned) {
  1983. // This section is only relevant for signed longs and is derived from the
  1984. // closure library as a whole.
  1985. if (this.eq(MIN_VALUE)) {
  1986. if (divisor.eq(ONE) || divisor.eq(NEG_ONE))
  1987. return MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE
  1988. else if (divisor.eq(MIN_VALUE))
  1989. return ONE;
  1990. else {
  1991. // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
  1992. var halfThis = this.shr(1);
  1993. approx = halfThis.div(divisor).shl(1);
  1994. if (approx.eq(ZERO)) {
  1995. return divisor.isNegative() ? ONE : NEG_ONE;
  1996. } else {
  1997. rem = this.sub(divisor.mul(approx));
  1998. res = approx.add(rem.div(divisor));
  1999. return res;
  2000. }
  2001. }
  2002. } else if (divisor.eq(MIN_VALUE))
  2003. return this.unsigned ? UZERO : ZERO;
  2004. if (this.isNegative()) {
  2005. if (divisor.isNegative())
  2006. return this.neg().div(divisor.neg());
  2007. return this.neg().div(divisor).neg();
  2008. } else if (divisor.isNegative())
  2009. return this.div(divisor.neg()).neg();
  2010. res = ZERO;
  2011. } else {
  2012. // The algorithm below has not been made for unsigned longs. It's therefore
  2013. // required to take special care of the MSB prior to running it.
  2014. if (!divisor.unsigned)
  2015. divisor = divisor.toUnsigned();
  2016. if (divisor.gt(this))
  2017. return UZERO;
  2018. if (divisor.gt(this.shru(1))) // 15 >>> 1 = 7 ; with divisor = 8 ; true
  2019. return UONE;
  2020. res = UZERO;
  2021. }
  2022. // Repeat the following until the remainder is less than other: find a
  2023. // floating-point that approximates remainder / other *from below*, add this
  2024. // into the result, and subtract it from the remainder. It is critical that
  2025. // the approximate value is less than or equal to the real value so that the
  2026. // remainder never becomes negative.
  2027. rem = this;
  2028. while (rem.gte(divisor)) {
  2029. // Approximate the result of division. This may be a little greater or
  2030. // smaller than the actual value.
  2031. approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber()));
  2032. // We will tweak the approximate result by changing it in the 48-th digit or
  2033. // the smallest non-fractional digit, whichever is larger.
  2034. var log2 = Math.ceil(Math.log(approx) / Math.LN2),
  2035. delta = (log2 <= 48) ? 1 : pow_dbl(2, log2 - 48),
  2036. // Decrease the approximation until it is smaller than the remainder. Note
  2037. // that if it is too large, the product overflows and is negative.
  2038. approxRes = fromNumber(approx),
  2039. approxRem = approxRes.mul(divisor);
  2040. while (approxRem.isNegative() || approxRem.gt(rem)) {
  2041. approx -= delta;
  2042. approxRes = fromNumber(approx, this.unsigned);
  2043. approxRem = approxRes.mul(divisor);
  2044. }
  2045. // We know the answer can't be zero... and actually, zero would cause
  2046. // infinite recursion since we would make no progress.
  2047. if (approxRes.isZero())
  2048. approxRes = ONE;
  2049. res = res.add(approxRes);
  2050. rem = rem.sub(approxRem);
  2051. }
  2052. return res;
  2053. };
  2054. /**
  2055. * Returns this Long divided by the specified. This is an alias of {@link Long#divide}.
  2056. * @function
  2057. * @param {!Long|number|string} divisor Divisor
  2058. * @returns {!Long} Quotient
  2059. */
  2060. LongPrototype.div = LongPrototype.divide;
  2061. /**
  2062. * Returns this Long modulo the specified.
  2063. * @param {!Long|number|string} divisor Divisor
  2064. * @returns {!Long} Remainder
  2065. */
  2066. LongPrototype.modulo = function modulo(divisor) {
  2067. if (!isLong(divisor))
  2068. divisor = fromValue(divisor);
  2069. return this.sub(this.div(divisor).mul(divisor));
  2070. };
  2071. /**
  2072. * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.
  2073. * @function
  2074. * @param {!Long|number|string} divisor Divisor
  2075. * @returns {!Long} Remainder
  2076. */
  2077. LongPrototype.mod = LongPrototype.modulo;
  2078. /**
  2079. * Returns the bitwise NOT of this Long.
  2080. * @returns {!Long}
  2081. */
  2082. LongPrototype.not = function not() {
  2083. return fromBits(~this.low, ~this.high, this.unsigned);
  2084. };
  2085. /**
  2086. * Returns the bitwise AND of this Long and the specified.
  2087. * @param {!Long|number|string} other Other Long
  2088. * @returns {!Long}
  2089. */
  2090. LongPrototype.and = function and(other) {
  2091. if (!isLong(other))
  2092. other = fromValue(other);
  2093. return fromBits(this.low & other.low, this.high & other.high, this.unsigned);
  2094. };
  2095. /**
  2096. * Returns the bitwise OR of this Long and the specified.
  2097. * @param {!Long|number|string} other Other Long
  2098. * @returns {!Long}
  2099. */
  2100. LongPrototype.or = function or(other) {
  2101. if (!isLong(other))
  2102. other = fromValue(other);
  2103. return fromBits(this.low | other.low, this.high | other.high, this.unsigned);
  2104. };
  2105. /**
  2106. * Returns the bitwise XOR of this Long and the given one.
  2107. * @param {!Long|number|string} other Other Long
  2108. * @returns {!Long}
  2109. */
  2110. LongPrototype.xor = function xor(other) {
  2111. if (!isLong(other))
  2112. other = fromValue(other);
  2113. return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned);
  2114. };
  2115. /**
  2116. * Returns this Long with bits shifted to the left by the given amount.
  2117. * @param {number|!Long} numBits Number of bits
  2118. * @returns {!Long} Shifted Long
  2119. */
  2120. LongPrototype.shiftLeft = function shiftLeft(numBits) {
  2121. if (isLong(numBits))
  2122. numBits = numBits.toInt();
  2123. if ((numBits &= 63) === 0)
  2124. return this;
  2125. else if (numBits < 32)
  2126. return fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned);
  2127. else
  2128. return fromBits(0, this.low << (numBits - 32), this.unsigned);
  2129. };
  2130. /**
  2131. * Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}.
  2132. * @function
  2133. * @param {number|!Long} numBits Number of bits
  2134. * @returns {!Long} Shifted Long
  2135. */
  2136. LongPrototype.shl = LongPrototype.shiftLeft;
  2137. /**
  2138. * Returns this Long with bits arithmetically shifted to the right by the given amount.
  2139. * @param {number|!Long} numBits Number of bits
  2140. * @returns {!Long} Shifted Long
  2141. */
  2142. LongPrototype.shiftRight = function shiftRight(numBits) {
  2143. if (isLong(numBits))
  2144. numBits = numBits.toInt();
  2145. if ((numBits &= 63) === 0)
  2146. return this;
  2147. else if (numBits < 32)
  2148. return fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned);
  2149. else
  2150. return fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned);
  2151. };
  2152. /**
  2153. * Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}.
  2154. * @function
  2155. * @param {number|!Long} numBits Number of bits
  2156. * @returns {!Long} Shifted Long
  2157. */
  2158. LongPrototype.shr = LongPrototype.shiftRight;
  2159. /**
  2160. * Returns this Long with bits logically shifted to the right by the given amount.
  2161. * @param {number|!Long} numBits Number of bits
  2162. * @returns {!Long} Shifted Long
  2163. */
  2164. LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) {
  2165. if (isLong(numBits))
  2166. numBits = numBits.toInt();
  2167. numBits &= 63;
  2168. if (numBits === 0)
  2169. return this;
  2170. else {
  2171. var high = this.high;
  2172. if (numBits < 32) {
  2173. var low = this.low;
  2174. return fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned);
  2175. } else if (numBits === 32)
  2176. return fromBits(high, 0, this.unsigned);
  2177. else
  2178. return fromBits(high >>> (numBits - 32), 0, this.unsigned);
  2179. }
  2180. };
  2181. /**
  2182. * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.
  2183. * @function
  2184. * @param {number|!Long} numBits Number of bits
  2185. * @returns {!Long} Shifted Long
  2186. */
  2187. LongPrototype.shru = LongPrototype.shiftRightUnsigned;
  2188. /**
  2189. * Converts this Long to signed.
  2190. * @returns {!Long} Signed long
  2191. */
  2192. LongPrototype.toSigned = function toSigned() {
  2193. if (!this.unsigned)
  2194. return this;
  2195. return fromBits(this.low, this.high, false);
  2196. };
  2197. /**
  2198. * Converts this Long to unsigned.
  2199. * @returns {!Long} Unsigned long
  2200. */
  2201. LongPrototype.toUnsigned = function toUnsigned() {
  2202. if (this.unsigned)
  2203. return this;
  2204. return fromBits(this.low, this.high, true);
  2205. };
  2206. /**
  2207. * Converts this Long to its byte representation.
  2208. * @param {boolean=} le Whether little or big endian, defaults to big endian
  2209. * @returns {!Array.<number>} Byte representation
  2210. */
  2211. LongPrototype.toBytes = function(le) {
  2212. return le ? this.toBytesLE() : this.toBytesBE();
  2213. };
  2214. /**
  2215. * Converts this Long to its little endian byte representation.
  2216. * @returns {!Array.<number>} Little endian byte representation
  2217. */
  2218. LongPrototype.toBytesLE = function() {
  2219. var hi = this.high,
  2220. lo = this.low;
  2221. return [
  2222. lo & 0xff,
  2223. (lo >>> 8) & 0xff,
  2224. (lo >>> 16) & 0xff,
  2225. (lo >>> 24) & 0xff,
  2226. hi & 0xff,
  2227. (hi >>> 8) & 0xff,
  2228. (hi >>> 16) & 0xff,
  2229. (hi >>> 24) & 0xff
  2230. ];
  2231. };
  2232. /**
  2233. * Converts this Long to its big endian byte representation.
  2234. * @returns {!Array.<number>} Big endian byte representation
  2235. */
  2236. LongPrototype.toBytesBE = function() {
  2237. var hi = this.high,
  2238. lo = this.low;
  2239. return [
  2240. (hi >>> 24) & 0xff,
  2241. (hi >>> 16) & 0xff,
  2242. (hi >>> 8) & 0xff,
  2243. hi & 0xff,
  2244. (lo >>> 24) & 0xff,
  2245. (lo >>> 16) & 0xff,
  2246. (lo >>> 8) & 0xff,
  2247. lo & 0xff
  2248. ];
  2249. };
  2250. return Long;
  2251. });
  2252. });
  2253. var bytebuffer = createCommonjsModule(function (module) {
  2254. /*
  2255. Copyright 2013-2014 Daniel Wirtz <dcode@dcode.io>
  2256. Licensed under the Apache License, Version 2.0 (the "License");
  2257. you may not use this file except in compliance with the License.
  2258. You may obtain a copy of the License at
  2259. http://www.apache.org/licenses/LICENSE-2.0
  2260. Unless required by applicable law or agreed to in writing, software
  2261. distributed under the License is distributed on an "AS IS" BASIS,
  2262. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2263. See the License for the specific language governing permissions and
  2264. limitations under the License.
  2265. */
  2266. /**
  2267. * @license bytebuffer.js (c) 2015 Daniel Wirtz <dcode@dcode.io>
  2268. * Backing buffer: ArrayBuffer, Accessor: Uint8Array
  2269. * Released under the Apache License, Version 2.0
  2270. * see: https://github.com/dcodeIO/bytebuffer.js for details
  2271. */
  2272. (function(global, factory) {
  2273. /* AMD */ if (typeof commonjsRequire === 'function' && 'object' === "object" && module && module["exports"])
  2274. module['exports'] = (function() {
  2275. var Long; try { Long = long_1; } catch (e) {}
  2276. return factory(Long);
  2277. })();
  2278. /* Global */ else
  2279. (global["dcodeIO"] = global["dcodeIO"] || {})["ByteBuffer"] = factory(global["dcodeIO"]["Long"]);
  2280. })(commonjsGlobal, function(Long) {
  2281. /**
  2282. * Constructs a new ByteBuffer.
  2283. * @class The swiss army knife for binary data in JavaScript.
  2284. * @exports ByteBuffer
  2285. * @constructor
  2286. * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
  2287. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  2288. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  2289. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  2290. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  2291. * @expose
  2292. */
  2293. var ByteBuffer = function(capacity, littleEndian, noAssert) {
  2294. if (typeof capacity === 'undefined')
  2295. capacity = ByteBuffer.DEFAULT_CAPACITY;
  2296. if (typeof littleEndian === 'undefined')
  2297. littleEndian = ByteBuffer.DEFAULT_ENDIAN;
  2298. if (typeof noAssert === 'undefined')
  2299. noAssert = ByteBuffer.DEFAULT_NOASSERT;
  2300. if (!noAssert) {
  2301. capacity = capacity | 0;
  2302. if (capacity < 0)
  2303. throw RangeError("Illegal capacity");
  2304. littleEndian = !!littleEndian;
  2305. noAssert = !!noAssert;
  2306. }
  2307. /**
  2308. * Backing ArrayBuffer.
  2309. * @type {!ArrayBuffer}
  2310. * @expose
  2311. */
  2312. this.buffer = capacity === 0 ? EMPTY_BUFFER : new ArrayBuffer(capacity);
  2313. /**
  2314. * Uint8Array utilized to manipulate the backing buffer. Becomes `null` if the backing buffer has a capacity of `0`.
  2315. * @type {?Uint8Array}
  2316. * @expose
  2317. */
  2318. this.view = capacity === 0 ? null : new Uint8Array(this.buffer);
  2319. /**
  2320. * Absolute read/write offset.
  2321. * @type {number}
  2322. * @expose
  2323. * @see ByteBuffer#flip
  2324. * @see ByteBuffer#clear
  2325. */
  2326. this.offset = 0;
  2327. /**
  2328. * Marked offset.
  2329. * @type {number}
  2330. * @expose
  2331. * @see ByteBuffer#mark
  2332. * @see ByteBuffer#reset
  2333. */
  2334. this.markedOffset = -1;
  2335. /**
  2336. * Absolute limit of the contained data. Set to the backing buffer's capacity upon allocation.
  2337. * @type {number}
  2338. * @expose
  2339. * @see ByteBuffer#flip
  2340. * @see ByteBuffer#clear
  2341. */
  2342. this.limit = capacity;
  2343. /**
  2344. * Whether to use little endian byte order, defaults to `false` for big endian.
  2345. * @type {boolean}
  2346. * @expose
  2347. */
  2348. this.littleEndian = littleEndian;
  2349. /**
  2350. * Whether to skip assertions of offsets and values, defaults to `false`.
  2351. * @type {boolean}
  2352. * @expose
  2353. */
  2354. this.noAssert = noAssert;
  2355. };
  2356. /**
  2357. * ByteBuffer version.
  2358. * @type {string}
  2359. * @const
  2360. * @expose
  2361. */
  2362. ByteBuffer.VERSION = "5.0.1";
  2363. /**
  2364. * Little endian constant that can be used instead of its boolean value. Evaluates to `true`.
  2365. * @type {boolean}
  2366. * @const
  2367. * @expose
  2368. */
  2369. ByteBuffer.LITTLE_ENDIAN = true;
  2370. /**
  2371. * Big endian constant that can be used instead of its boolean value. Evaluates to `false`.
  2372. * @type {boolean}
  2373. * @const
  2374. * @expose
  2375. */
  2376. ByteBuffer.BIG_ENDIAN = false;
  2377. /**
  2378. * Default initial capacity of `16`.
  2379. * @type {number}
  2380. * @expose
  2381. */
  2382. ByteBuffer.DEFAULT_CAPACITY = 16;
  2383. /**
  2384. * Default endianess of `false` for big endian.
  2385. * @type {boolean}
  2386. * @expose
  2387. */
  2388. ByteBuffer.DEFAULT_ENDIAN = ByteBuffer.BIG_ENDIAN;
  2389. /**
  2390. * Default no assertions flag of `false`.
  2391. * @type {boolean}
  2392. * @expose
  2393. */
  2394. ByteBuffer.DEFAULT_NOASSERT = false;
  2395. /**
  2396. * A `Long` class for representing a 64-bit two's-complement integer value. May be `null` if Long.js has not been loaded
  2397. * and int64 support is not available.
  2398. * @type {?Long}
  2399. * @const
  2400. * @see https://github.com/dcodeIO/long.js
  2401. * @expose
  2402. */
  2403. ByteBuffer.Long = Long || null;
  2404. /**
  2405. * @alias ByteBuffer.prototype
  2406. * @inner
  2407. */
  2408. var ByteBufferPrototype = ByteBuffer.prototype;
  2409. /**
  2410. * An indicator used to reliably determine if an object is a ByteBuffer or not.
  2411. * @type {boolean}
  2412. * @const
  2413. * @expose
  2414. * @private
  2415. */
  2416. ByteBufferPrototype.__isByteBuffer__;
  2417. Object.defineProperty(ByteBufferPrototype, "__isByteBuffer__", {
  2418. value: true,
  2419. enumerable: false,
  2420. configurable: false
  2421. });
  2422. // helpers
  2423. /**
  2424. * @type {!ArrayBuffer}
  2425. * @inner
  2426. */
  2427. var EMPTY_BUFFER = new ArrayBuffer(0);
  2428. /**
  2429. * String.fromCharCode reference for compile-time renaming.
  2430. * @type {function(...number):string}
  2431. * @inner
  2432. */
  2433. var stringFromCharCode = String.fromCharCode;
  2434. /**
  2435. * Creates a source function for a string.
  2436. * @param {string} s String to read from
  2437. * @returns {function():number|null} Source function returning the next char code respectively `null` if there are
  2438. * no more characters left.
  2439. * @throws {TypeError} If the argument is invalid
  2440. * @inner
  2441. */
  2442. function stringSource(s) {
  2443. var i=0; return function() {
  2444. return i < s.length ? s.charCodeAt(i++) : null;
  2445. };
  2446. }
  2447. /**
  2448. * Creates a destination function for a string.
  2449. * @returns {function(number=):undefined|string} Destination function successively called with the next char code.
  2450. * Returns the final string when called without arguments.
  2451. * @inner
  2452. */
  2453. function stringDestination() {
  2454. var cs = [], ps = []; return function() {
  2455. if (arguments.length === 0)
  2456. return ps.join('')+stringFromCharCode.apply(String, cs);
  2457. if (cs.length + arguments.length > 1024)
  2458. ps.push(stringFromCharCode.apply(String, cs)),
  2459. cs.length = 0;
  2460. Array.prototype.push.apply(cs, arguments);
  2461. };
  2462. }
  2463. /**
  2464. * Gets the accessor type.
  2465. * @returns {Function} `Buffer` under node.js, `Uint8Array` respectively `DataView` in the browser (classes)
  2466. * @expose
  2467. */
  2468. ByteBuffer.accessor = function() {
  2469. return Uint8Array;
  2470. };
  2471. /**
  2472. * Allocates a new ByteBuffer backed by a buffer of the specified capacity.
  2473. * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
  2474. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  2475. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  2476. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  2477. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  2478. * @returns {!ByteBuffer}
  2479. * @expose
  2480. */
  2481. ByteBuffer.allocate = function(capacity, littleEndian, noAssert) {
  2482. return new ByteBuffer(capacity, littleEndian, noAssert);
  2483. };
  2484. /**
  2485. * Concatenates multiple ByteBuffers into one.
  2486. * @param {!Array.<!ByteBuffer|!ArrayBuffer|!Uint8Array|string>} buffers Buffers to concatenate
  2487. * @param {(string|boolean)=} encoding String encoding if `buffers` contains a string ("base64", "hex", "binary",
  2488. * defaults to "utf8")
  2489. * @param {boolean=} littleEndian Whether to use little or big endian byte order for the resulting ByteBuffer. Defaults
  2490. * to {@link ByteBuffer.DEFAULT_ENDIAN}.
  2491. * @param {boolean=} noAssert Whether to skip assertions of offsets and values for the resulting ByteBuffer. Defaults to
  2492. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  2493. * @returns {!ByteBuffer} Concatenated ByteBuffer
  2494. * @expose
  2495. */
  2496. ByteBuffer.concat = function(buffers, encoding, littleEndian, noAssert) {
  2497. if (typeof encoding === 'boolean' || typeof encoding !== 'string') {
  2498. noAssert = littleEndian;
  2499. littleEndian = encoding;
  2500. encoding = undefined;
  2501. }
  2502. var capacity = 0;
  2503. for (var i=0, k=buffers.length, length; i<k; ++i) {
  2504. if (!ByteBuffer.isByteBuffer(buffers[i]))
  2505. buffers[i] = ByteBuffer.wrap(buffers[i], encoding);
  2506. length = buffers[i].limit - buffers[i].offset;
  2507. if (length > 0) capacity += length;
  2508. }
  2509. if (capacity === 0)
  2510. return new ByteBuffer(0, littleEndian, noAssert);
  2511. var bb = new ByteBuffer(capacity, littleEndian, noAssert),
  2512. bi;
  2513. i=0; while (i<k) {
  2514. bi = buffers[i++];
  2515. length = bi.limit - bi.offset;
  2516. if (length <= 0) continue;
  2517. bb.view.set(bi.view.subarray(bi.offset, bi.limit), bb.offset);
  2518. bb.offset += length;
  2519. }
  2520. bb.limit = bb.offset;
  2521. bb.offset = 0;
  2522. return bb;
  2523. };
  2524. /**
  2525. * Tests if the specified type is a ByteBuffer.
  2526. * @param {*} bb ByteBuffer to test
  2527. * @returns {boolean} `true` if it is a ByteBuffer, otherwise `false`
  2528. * @expose
  2529. */
  2530. ByteBuffer.isByteBuffer = function(bb) {
  2531. return (bb && bb["__isByteBuffer__"]) === true;
  2532. };
  2533. /**
  2534. * Gets the backing buffer type.
  2535. * @returns {Function} `Buffer` under node.js, `ArrayBuffer` in the browser (classes)
  2536. * @expose
  2537. */
  2538. ByteBuffer.type = function() {
  2539. return ArrayBuffer;
  2540. };
  2541. /**
  2542. * Wraps a buffer or a string. Sets the allocated ByteBuffer's {@link ByteBuffer#offset} to `0` and its
  2543. * {@link ByteBuffer#limit} to the length of the wrapped data.
  2544. * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string|!Array.<number>} buffer Anything that can be wrapped
  2545. * @param {(string|boolean)=} encoding String encoding if `buffer` is a string ("base64", "hex", "binary", defaults to
  2546. * "utf8")
  2547. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  2548. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  2549. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  2550. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  2551. * @returns {!ByteBuffer} A ByteBuffer wrapping `buffer`
  2552. * @expose
  2553. */
  2554. ByteBuffer.wrap = function(buffer, encoding, littleEndian, noAssert) {
  2555. if (typeof encoding !== 'string') {
  2556. noAssert = littleEndian;
  2557. littleEndian = encoding;
  2558. encoding = undefined;
  2559. }
  2560. if (typeof buffer === 'string') {
  2561. if (typeof encoding === 'undefined')
  2562. encoding = "utf8";
  2563. switch (encoding) {
  2564. case "base64":
  2565. return ByteBuffer.fromBase64(buffer, littleEndian);
  2566. case "hex":
  2567. return ByteBuffer.fromHex(buffer, littleEndian);
  2568. case "binary":
  2569. return ByteBuffer.fromBinary(buffer, littleEndian);
  2570. case "utf8":
  2571. return ByteBuffer.fromUTF8(buffer, littleEndian);
  2572. case "debug":
  2573. return ByteBuffer.fromDebug(buffer, littleEndian);
  2574. default:
  2575. throw Error("Unsupported encoding: "+encoding);
  2576. }
  2577. }
  2578. if (buffer === null || typeof buffer !== 'object')
  2579. throw TypeError("Illegal buffer");
  2580. var bb;
  2581. if (ByteBuffer.isByteBuffer(buffer)) {
  2582. bb = ByteBufferPrototype.clone.call(buffer);
  2583. bb.markedOffset = -1;
  2584. return bb;
  2585. }
  2586. if (buffer instanceof Uint8Array) { // Extract ArrayBuffer from Uint8Array
  2587. bb = new ByteBuffer(0, littleEndian, noAssert);
  2588. if (buffer.length > 0) { // Avoid references to more than one EMPTY_BUFFER
  2589. bb.buffer = buffer.buffer;
  2590. bb.offset = buffer.byteOffset;
  2591. bb.limit = buffer.byteOffset + buffer.byteLength;
  2592. bb.view = new Uint8Array(buffer.buffer);
  2593. }
  2594. } else if (buffer instanceof ArrayBuffer) { // Reuse ArrayBuffer
  2595. bb = new ByteBuffer(0, littleEndian, noAssert);
  2596. if (buffer.byteLength > 0) {
  2597. bb.buffer = buffer;
  2598. bb.offset = 0;
  2599. bb.limit = buffer.byteLength;
  2600. bb.view = buffer.byteLength > 0 ? new Uint8Array(buffer) : null;
  2601. }
  2602. } else if (Object.prototype.toString.call(buffer) === "[object Array]") { // Create from octets
  2603. bb = new ByteBuffer(buffer.length, littleEndian, noAssert);
  2604. bb.limit = buffer.length;
  2605. for (var i=0; i<buffer.length; ++i)
  2606. bb.view[i] = buffer[i];
  2607. } else
  2608. throw TypeError("Illegal buffer"); // Otherwise fail
  2609. return bb;
  2610. };
  2611. /**
  2612. * Writes the array as a bitset.
  2613. * @param {Array<boolean>} value Array of booleans to write
  2614. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
  2615. * @returns {!ByteBuffer}
  2616. * @expose
  2617. */
  2618. ByteBufferPrototype.writeBitSet = function(value, offset) {
  2619. var relative = typeof offset === 'undefined';
  2620. if (relative) offset = this.offset;
  2621. if (!this.noAssert) {
  2622. if (!(value instanceof Array))
  2623. throw TypeError("Illegal BitSet: Not an array");
  2624. if (typeof offset !== 'number' || offset % 1 !== 0)
  2625. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2626. offset >>>= 0;
  2627. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  2628. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  2629. }
  2630. var start = offset,
  2631. bits = value.length,
  2632. bytes = (bits >> 3),
  2633. bit = 0,
  2634. k;
  2635. offset += this.writeVarint32(bits,offset);
  2636. while(bytes--) {
  2637. k = (!!value[bit++] & 1) |
  2638. ((!!value[bit++] & 1) << 1) |
  2639. ((!!value[bit++] & 1) << 2) |
  2640. ((!!value[bit++] & 1) << 3) |
  2641. ((!!value[bit++] & 1) << 4) |
  2642. ((!!value[bit++] & 1) << 5) |
  2643. ((!!value[bit++] & 1) << 6) |
  2644. ((!!value[bit++] & 1) << 7);
  2645. this.writeByte(k,offset++);
  2646. }
  2647. if(bit < bits) {
  2648. var m = 0; k = 0;
  2649. while(bit < bits) k = k | ((!!value[bit++] & 1) << (m++));
  2650. this.writeByte(k,offset++);
  2651. }
  2652. if (relative) {
  2653. this.offset = offset;
  2654. return this;
  2655. }
  2656. return offset - start;
  2657. };
  2658. /**
  2659. * Reads a BitSet as an array of booleans.
  2660. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
  2661. * @returns {Array<boolean>
  2662. * @expose
  2663. */
  2664. ByteBufferPrototype.readBitSet = function(offset) {
  2665. var relative = typeof offset === 'undefined';
  2666. if (relative) offset = this.offset;
  2667. var ret = this.readVarint32(offset),
  2668. bits = ret.value,
  2669. bytes = (bits >> 3),
  2670. bit = 0,
  2671. value = [],
  2672. k;
  2673. offset += ret.length;
  2674. while(bytes--) {
  2675. k = this.readByte(offset++);
  2676. value[bit++] = !!(k & 0x01);
  2677. value[bit++] = !!(k & 0x02);
  2678. value[bit++] = !!(k & 0x04);
  2679. value[bit++] = !!(k & 0x08);
  2680. value[bit++] = !!(k & 0x10);
  2681. value[bit++] = !!(k & 0x20);
  2682. value[bit++] = !!(k & 0x40);
  2683. value[bit++] = !!(k & 0x80);
  2684. }
  2685. if(bit < bits) {
  2686. var m = 0;
  2687. k = this.readByte(offset++);
  2688. while(bit < bits) value[bit++] = !!((k >> (m++)) & 1);
  2689. }
  2690. if (relative) {
  2691. this.offset = offset;
  2692. }
  2693. return value;
  2694. };
  2695. /**
  2696. * Reads the specified number of bytes.
  2697. * @param {number} length Number of bytes to read
  2698. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
  2699. * @returns {!ByteBuffer}
  2700. * @expose
  2701. */
  2702. ByteBufferPrototype.readBytes = function(length, offset) {
  2703. var relative = typeof offset === 'undefined';
  2704. if (relative) offset = this.offset;
  2705. if (!this.noAssert) {
  2706. if (typeof offset !== 'number' || offset % 1 !== 0)
  2707. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2708. offset >>>= 0;
  2709. if (offset < 0 || offset + length > this.buffer.byteLength)
  2710. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength);
  2711. }
  2712. var slice = this.slice(offset, offset + length);
  2713. if (relative) this.offset += length;
  2714. return slice;
  2715. };
  2716. /**
  2717. * Writes a payload of bytes. This is an alias of {@link ByteBuffer#append}.
  2718. * @function
  2719. * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to write. If `source` is a ByteBuffer, its offsets
  2720. * will be modified according to the performed read operation.
  2721. * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
  2722. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  2723. * written if omitted.
  2724. * @returns {!ByteBuffer} this
  2725. * @expose
  2726. */
  2727. ByteBufferPrototype.writeBytes = ByteBufferPrototype.append;
  2728. // types/ints/int8
  2729. /**
  2730. * Writes an 8bit signed integer.
  2731. * @param {number} value Value to write
  2732. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  2733. * @returns {!ByteBuffer} this
  2734. * @expose
  2735. */
  2736. ByteBufferPrototype.writeInt8 = function(value, offset) {
  2737. var relative = typeof offset === 'undefined';
  2738. if (relative) offset = this.offset;
  2739. if (!this.noAssert) {
  2740. if (typeof value !== 'number' || value % 1 !== 0)
  2741. throw TypeError("Illegal value: "+value+" (not an integer)");
  2742. value |= 0;
  2743. if (typeof offset !== 'number' || offset % 1 !== 0)
  2744. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2745. offset >>>= 0;
  2746. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  2747. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  2748. }
  2749. offset += 1;
  2750. var capacity0 = this.buffer.byteLength;
  2751. if (offset > capacity0)
  2752. this.resize((capacity0 *= 2) > offset ? capacity0 : offset);
  2753. offset -= 1;
  2754. this.view[offset] = value;
  2755. if (relative) this.offset += 1;
  2756. return this;
  2757. };
  2758. /**
  2759. * Writes an 8bit signed integer. This is an alias of {@link ByteBuffer#writeInt8}.
  2760. * @function
  2761. * @param {number} value Value to write
  2762. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  2763. * @returns {!ByteBuffer} this
  2764. * @expose
  2765. */
  2766. ByteBufferPrototype.writeByte = ByteBufferPrototype.writeInt8;
  2767. /**
  2768. * Reads an 8bit signed integer.
  2769. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  2770. * @returns {number} Value read
  2771. * @expose
  2772. */
  2773. ByteBufferPrototype.readInt8 = function(offset) {
  2774. var relative = typeof offset === 'undefined';
  2775. if (relative) offset = this.offset;
  2776. if (!this.noAssert) {
  2777. if (typeof offset !== 'number' || offset % 1 !== 0)
  2778. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2779. offset >>>= 0;
  2780. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  2781. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  2782. }
  2783. var value = this.view[offset];
  2784. if ((value & 0x80) === 0x80) value = -(0xFF - value + 1); // Cast to signed
  2785. if (relative) this.offset += 1;
  2786. return value;
  2787. };
  2788. /**
  2789. * Reads an 8bit signed integer. This is an alias of {@link ByteBuffer#readInt8}.
  2790. * @function
  2791. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  2792. * @returns {number} Value read
  2793. * @expose
  2794. */
  2795. ByteBufferPrototype.readByte = ByteBufferPrototype.readInt8;
  2796. /**
  2797. * Writes an 8bit unsigned integer.
  2798. * @param {number} value Value to write
  2799. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  2800. * @returns {!ByteBuffer} this
  2801. * @expose
  2802. */
  2803. ByteBufferPrototype.writeUint8 = function(value, offset) {
  2804. var relative = typeof offset === 'undefined';
  2805. if (relative) offset = this.offset;
  2806. if (!this.noAssert) {
  2807. if (typeof value !== 'number' || value % 1 !== 0)
  2808. throw TypeError("Illegal value: "+value+" (not an integer)");
  2809. value >>>= 0;
  2810. if (typeof offset !== 'number' || offset % 1 !== 0)
  2811. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2812. offset >>>= 0;
  2813. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  2814. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  2815. }
  2816. offset += 1;
  2817. var capacity1 = this.buffer.byteLength;
  2818. if (offset > capacity1)
  2819. this.resize((capacity1 *= 2) > offset ? capacity1 : offset);
  2820. offset -= 1;
  2821. this.view[offset] = value;
  2822. if (relative) this.offset += 1;
  2823. return this;
  2824. };
  2825. /**
  2826. * Writes an 8bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint8}.
  2827. * @function
  2828. * @param {number} value Value to write
  2829. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  2830. * @returns {!ByteBuffer} this
  2831. * @expose
  2832. */
  2833. ByteBufferPrototype.writeUInt8 = ByteBufferPrototype.writeUint8;
  2834. /**
  2835. * Reads an 8bit unsigned integer.
  2836. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  2837. * @returns {number} Value read
  2838. * @expose
  2839. */
  2840. ByteBufferPrototype.readUint8 = function(offset) {
  2841. var relative = typeof offset === 'undefined';
  2842. if (relative) offset = this.offset;
  2843. if (!this.noAssert) {
  2844. if (typeof offset !== 'number' || offset % 1 !== 0)
  2845. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2846. offset >>>= 0;
  2847. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  2848. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  2849. }
  2850. var value = this.view[offset];
  2851. if (relative) this.offset += 1;
  2852. return value;
  2853. };
  2854. /**
  2855. * Reads an 8bit unsigned integer. This is an alias of {@link ByteBuffer#readUint8}.
  2856. * @function
  2857. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  2858. * @returns {number} Value read
  2859. * @expose
  2860. */
  2861. ByteBufferPrototype.readUInt8 = ByteBufferPrototype.readUint8;
  2862. // types/ints/int16
  2863. /**
  2864. * Writes a 16bit signed integer.
  2865. * @param {number} value Value to write
  2866. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  2867. * @throws {TypeError} If `offset` or `value` is not a valid number
  2868. * @throws {RangeError} If `offset` is out of bounds
  2869. * @expose
  2870. */
  2871. ByteBufferPrototype.writeInt16 = function(value, offset) {
  2872. var relative = typeof offset === 'undefined';
  2873. if (relative) offset = this.offset;
  2874. if (!this.noAssert) {
  2875. if (typeof value !== 'number' || value % 1 !== 0)
  2876. throw TypeError("Illegal value: "+value+" (not an integer)");
  2877. value |= 0;
  2878. if (typeof offset !== 'number' || offset % 1 !== 0)
  2879. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2880. offset >>>= 0;
  2881. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  2882. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  2883. }
  2884. offset += 2;
  2885. var capacity2 = this.buffer.byteLength;
  2886. if (offset > capacity2)
  2887. this.resize((capacity2 *= 2) > offset ? capacity2 : offset);
  2888. offset -= 2;
  2889. if (this.littleEndian) {
  2890. this.view[offset+1] = (value & 0xFF00) >>> 8;
  2891. this.view[offset ] = value & 0x00FF;
  2892. } else {
  2893. this.view[offset] = (value & 0xFF00) >>> 8;
  2894. this.view[offset+1] = value & 0x00FF;
  2895. }
  2896. if (relative) this.offset += 2;
  2897. return this;
  2898. };
  2899. /**
  2900. * Writes a 16bit signed integer. This is an alias of {@link ByteBuffer#writeInt16}.
  2901. * @function
  2902. * @param {number} value Value to write
  2903. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  2904. * @throws {TypeError} If `offset` or `value` is not a valid number
  2905. * @throws {RangeError} If `offset` is out of bounds
  2906. * @expose
  2907. */
  2908. ByteBufferPrototype.writeShort = ByteBufferPrototype.writeInt16;
  2909. /**
  2910. * Reads a 16bit signed integer.
  2911. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  2912. * @returns {number} Value read
  2913. * @throws {TypeError} If `offset` is not a valid number
  2914. * @throws {RangeError} If `offset` is out of bounds
  2915. * @expose
  2916. */
  2917. ByteBufferPrototype.readInt16 = function(offset) {
  2918. var relative = typeof offset === 'undefined';
  2919. if (relative) offset = this.offset;
  2920. if (!this.noAssert) {
  2921. if (typeof offset !== 'number' || offset % 1 !== 0)
  2922. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2923. offset >>>= 0;
  2924. if (offset < 0 || offset + 2 > this.buffer.byteLength)
  2925. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
  2926. }
  2927. var value = 0;
  2928. if (this.littleEndian) {
  2929. value = this.view[offset ];
  2930. value |= this.view[offset+1] << 8;
  2931. } else {
  2932. value = this.view[offset ] << 8;
  2933. value |= this.view[offset+1];
  2934. }
  2935. if ((value & 0x8000) === 0x8000) value = -(0xFFFF - value + 1); // Cast to signed
  2936. if (relative) this.offset += 2;
  2937. return value;
  2938. };
  2939. /**
  2940. * Reads a 16bit signed integer. This is an alias of {@link ByteBuffer#readInt16}.
  2941. * @function
  2942. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  2943. * @returns {number} Value read
  2944. * @throws {TypeError} If `offset` is not a valid number
  2945. * @throws {RangeError} If `offset` is out of bounds
  2946. * @expose
  2947. */
  2948. ByteBufferPrototype.readShort = ByteBufferPrototype.readInt16;
  2949. /**
  2950. * Writes a 16bit unsigned integer.
  2951. * @param {number} value Value to write
  2952. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  2953. * @throws {TypeError} If `offset` or `value` is not a valid number
  2954. * @throws {RangeError} If `offset` is out of bounds
  2955. * @expose
  2956. */
  2957. ByteBufferPrototype.writeUint16 = function(value, offset) {
  2958. var relative = typeof offset === 'undefined';
  2959. if (relative) offset = this.offset;
  2960. if (!this.noAssert) {
  2961. if (typeof value !== 'number' || value % 1 !== 0)
  2962. throw TypeError("Illegal value: "+value+" (not an integer)");
  2963. value >>>= 0;
  2964. if (typeof offset !== 'number' || offset % 1 !== 0)
  2965. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2966. offset >>>= 0;
  2967. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  2968. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  2969. }
  2970. offset += 2;
  2971. var capacity3 = this.buffer.byteLength;
  2972. if (offset > capacity3)
  2973. this.resize((capacity3 *= 2) > offset ? capacity3 : offset);
  2974. offset -= 2;
  2975. if (this.littleEndian) {
  2976. this.view[offset+1] = (value & 0xFF00) >>> 8;
  2977. this.view[offset ] = value & 0x00FF;
  2978. } else {
  2979. this.view[offset] = (value & 0xFF00) >>> 8;
  2980. this.view[offset+1] = value & 0x00FF;
  2981. }
  2982. if (relative) this.offset += 2;
  2983. return this;
  2984. };
  2985. /**
  2986. * Writes a 16bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint16}.
  2987. * @function
  2988. * @param {number} value Value to write
  2989. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  2990. * @throws {TypeError} If `offset` or `value` is not a valid number
  2991. * @throws {RangeError} If `offset` is out of bounds
  2992. * @expose
  2993. */
  2994. ByteBufferPrototype.writeUInt16 = ByteBufferPrototype.writeUint16;
  2995. /**
  2996. * Reads a 16bit unsigned integer.
  2997. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  2998. * @returns {number} Value read
  2999. * @throws {TypeError} If `offset` is not a valid number
  3000. * @throws {RangeError} If `offset` is out of bounds
  3001. * @expose
  3002. */
  3003. ByteBufferPrototype.readUint16 = function(offset) {
  3004. var relative = typeof offset === 'undefined';
  3005. if (relative) offset = this.offset;
  3006. if (!this.noAssert) {
  3007. if (typeof offset !== 'number' || offset % 1 !== 0)
  3008. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3009. offset >>>= 0;
  3010. if (offset < 0 || offset + 2 > this.buffer.byteLength)
  3011. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
  3012. }
  3013. var value = 0;
  3014. if (this.littleEndian) {
  3015. value = this.view[offset ];
  3016. value |= this.view[offset+1] << 8;
  3017. } else {
  3018. value = this.view[offset ] << 8;
  3019. value |= this.view[offset+1];
  3020. }
  3021. if (relative) this.offset += 2;
  3022. return value;
  3023. };
  3024. /**
  3025. * Reads a 16bit unsigned integer. This is an alias of {@link ByteBuffer#readUint16}.
  3026. * @function
  3027. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  3028. * @returns {number} Value read
  3029. * @throws {TypeError} If `offset` is not a valid number
  3030. * @throws {RangeError} If `offset` is out of bounds
  3031. * @expose
  3032. */
  3033. ByteBufferPrototype.readUInt16 = ByteBufferPrototype.readUint16;
  3034. // types/ints/int32
  3035. /**
  3036. * Writes a 32bit signed integer.
  3037. * @param {number} value Value to write
  3038. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  3039. * @expose
  3040. */
  3041. ByteBufferPrototype.writeInt32 = function(value, offset) {
  3042. var relative = typeof offset === 'undefined';
  3043. if (relative) offset = this.offset;
  3044. if (!this.noAssert) {
  3045. if (typeof value !== 'number' || value % 1 !== 0)
  3046. throw TypeError("Illegal value: "+value+" (not an integer)");
  3047. value |= 0;
  3048. if (typeof offset !== 'number' || offset % 1 !== 0)
  3049. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3050. offset >>>= 0;
  3051. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3052. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3053. }
  3054. offset += 4;
  3055. var capacity4 = this.buffer.byteLength;
  3056. if (offset > capacity4)
  3057. this.resize((capacity4 *= 2) > offset ? capacity4 : offset);
  3058. offset -= 4;
  3059. if (this.littleEndian) {
  3060. this.view[offset+3] = (value >>> 24) & 0xFF;
  3061. this.view[offset+2] = (value >>> 16) & 0xFF;
  3062. this.view[offset+1] = (value >>> 8) & 0xFF;
  3063. this.view[offset ] = value & 0xFF;
  3064. } else {
  3065. this.view[offset ] = (value >>> 24) & 0xFF;
  3066. this.view[offset+1] = (value >>> 16) & 0xFF;
  3067. this.view[offset+2] = (value >>> 8) & 0xFF;
  3068. this.view[offset+3] = value & 0xFF;
  3069. }
  3070. if (relative) this.offset += 4;
  3071. return this;
  3072. };
  3073. /**
  3074. * Writes a 32bit signed integer. This is an alias of {@link ByteBuffer#writeInt32}.
  3075. * @param {number} value Value to write
  3076. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  3077. * @expose
  3078. */
  3079. ByteBufferPrototype.writeInt = ByteBufferPrototype.writeInt32;
  3080. /**
  3081. * Reads a 32bit signed integer.
  3082. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  3083. * @returns {number} Value read
  3084. * @expose
  3085. */
  3086. ByteBufferPrototype.readInt32 = function(offset) {
  3087. var relative = typeof offset === 'undefined';
  3088. if (relative) offset = this.offset;
  3089. if (!this.noAssert) {
  3090. if (typeof offset !== 'number' || offset % 1 !== 0)
  3091. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3092. offset >>>= 0;
  3093. if (offset < 0 || offset + 4 > this.buffer.byteLength)
  3094. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
  3095. }
  3096. var value = 0;
  3097. if (this.littleEndian) {
  3098. value = this.view[offset+2] << 16;
  3099. value |= this.view[offset+1] << 8;
  3100. value |= this.view[offset ];
  3101. value += this.view[offset+3] << 24 >>> 0;
  3102. } else {
  3103. value = this.view[offset+1] << 16;
  3104. value |= this.view[offset+2] << 8;
  3105. value |= this.view[offset+3];
  3106. value += this.view[offset ] << 24 >>> 0;
  3107. }
  3108. value |= 0; // Cast to signed
  3109. if (relative) this.offset += 4;
  3110. return value;
  3111. };
  3112. /**
  3113. * Reads a 32bit signed integer. This is an alias of {@link ByteBuffer#readInt32}.
  3114. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `4` if omitted.
  3115. * @returns {number} Value read
  3116. * @expose
  3117. */
  3118. ByteBufferPrototype.readInt = ByteBufferPrototype.readInt32;
  3119. /**
  3120. * Writes a 32bit unsigned integer.
  3121. * @param {number} value Value to write
  3122. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  3123. * @expose
  3124. */
  3125. ByteBufferPrototype.writeUint32 = function(value, offset) {
  3126. var relative = typeof offset === 'undefined';
  3127. if (relative) offset = this.offset;
  3128. if (!this.noAssert) {
  3129. if (typeof value !== 'number' || value % 1 !== 0)
  3130. throw TypeError("Illegal value: "+value+" (not an integer)");
  3131. value >>>= 0;
  3132. if (typeof offset !== 'number' || offset % 1 !== 0)
  3133. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3134. offset >>>= 0;
  3135. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3136. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3137. }
  3138. offset += 4;
  3139. var capacity5 = this.buffer.byteLength;
  3140. if (offset > capacity5)
  3141. this.resize((capacity5 *= 2) > offset ? capacity5 : offset);
  3142. offset -= 4;
  3143. if (this.littleEndian) {
  3144. this.view[offset+3] = (value >>> 24) & 0xFF;
  3145. this.view[offset+2] = (value >>> 16) & 0xFF;
  3146. this.view[offset+1] = (value >>> 8) & 0xFF;
  3147. this.view[offset ] = value & 0xFF;
  3148. } else {
  3149. this.view[offset ] = (value >>> 24) & 0xFF;
  3150. this.view[offset+1] = (value >>> 16) & 0xFF;
  3151. this.view[offset+2] = (value >>> 8) & 0xFF;
  3152. this.view[offset+3] = value & 0xFF;
  3153. }
  3154. if (relative) this.offset += 4;
  3155. return this;
  3156. };
  3157. /**
  3158. * Writes a 32bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint32}.
  3159. * @function
  3160. * @param {number} value Value to write
  3161. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  3162. * @expose
  3163. */
  3164. ByteBufferPrototype.writeUInt32 = ByteBufferPrototype.writeUint32;
  3165. /**
  3166. * Reads a 32bit unsigned integer.
  3167. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  3168. * @returns {number} Value read
  3169. * @expose
  3170. */
  3171. ByteBufferPrototype.readUint32 = function(offset) {
  3172. var relative = typeof offset === 'undefined';
  3173. if (relative) offset = this.offset;
  3174. if (!this.noAssert) {
  3175. if (typeof offset !== 'number' || offset % 1 !== 0)
  3176. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3177. offset >>>= 0;
  3178. if (offset < 0 || offset + 4 > this.buffer.byteLength)
  3179. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
  3180. }
  3181. var value = 0;
  3182. if (this.littleEndian) {
  3183. value = this.view[offset+2] << 16;
  3184. value |= this.view[offset+1] << 8;
  3185. value |= this.view[offset ];
  3186. value += this.view[offset+3] << 24 >>> 0;
  3187. } else {
  3188. value = this.view[offset+1] << 16;
  3189. value |= this.view[offset+2] << 8;
  3190. value |= this.view[offset+3];
  3191. value += this.view[offset ] << 24 >>> 0;
  3192. }
  3193. if (relative) this.offset += 4;
  3194. return value;
  3195. };
  3196. /**
  3197. * Reads a 32bit unsigned integer. This is an alias of {@link ByteBuffer#readUint32}.
  3198. * @function
  3199. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  3200. * @returns {number} Value read
  3201. * @expose
  3202. */
  3203. ByteBufferPrototype.readUInt32 = ByteBufferPrototype.readUint32;
  3204. // types/ints/int64
  3205. if (Long) {
  3206. /**
  3207. * Writes a 64bit signed integer.
  3208. * @param {number|!Long} value Value to write
  3209. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  3210. * @returns {!ByteBuffer} this
  3211. * @expose
  3212. */
  3213. ByteBufferPrototype.writeInt64 = function(value, offset) {
  3214. var relative = typeof offset === 'undefined';
  3215. if (relative) offset = this.offset;
  3216. if (!this.noAssert) {
  3217. if (typeof value === 'number')
  3218. value = Long.fromNumber(value);
  3219. else if (typeof value === 'string')
  3220. value = Long.fromString(value);
  3221. else if (!(value && value instanceof Long))
  3222. throw TypeError("Illegal value: "+value+" (not an integer or Long)");
  3223. if (typeof offset !== 'number' || offset % 1 !== 0)
  3224. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3225. offset >>>= 0;
  3226. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3227. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3228. }
  3229. if (typeof value === 'number')
  3230. value = Long.fromNumber(value);
  3231. else if (typeof value === 'string')
  3232. value = Long.fromString(value);
  3233. offset += 8;
  3234. var capacity6 = this.buffer.byteLength;
  3235. if (offset > capacity6)
  3236. this.resize((capacity6 *= 2) > offset ? capacity6 : offset);
  3237. offset -= 8;
  3238. var lo = value.low,
  3239. hi = value.high;
  3240. if (this.littleEndian) {
  3241. this.view[offset+3] = (lo >>> 24) & 0xFF;
  3242. this.view[offset+2] = (lo >>> 16) & 0xFF;
  3243. this.view[offset+1] = (lo >>> 8) & 0xFF;
  3244. this.view[offset ] = lo & 0xFF;
  3245. offset += 4;
  3246. this.view[offset+3] = (hi >>> 24) & 0xFF;
  3247. this.view[offset+2] = (hi >>> 16) & 0xFF;
  3248. this.view[offset+1] = (hi >>> 8) & 0xFF;
  3249. this.view[offset ] = hi & 0xFF;
  3250. } else {
  3251. this.view[offset ] = (hi >>> 24) & 0xFF;
  3252. this.view[offset+1] = (hi >>> 16) & 0xFF;
  3253. this.view[offset+2] = (hi >>> 8) & 0xFF;
  3254. this.view[offset+3] = hi & 0xFF;
  3255. offset += 4;
  3256. this.view[offset ] = (lo >>> 24) & 0xFF;
  3257. this.view[offset+1] = (lo >>> 16) & 0xFF;
  3258. this.view[offset+2] = (lo >>> 8) & 0xFF;
  3259. this.view[offset+3] = lo & 0xFF;
  3260. }
  3261. if (relative) this.offset += 8;
  3262. return this;
  3263. };
  3264. /**
  3265. * Writes a 64bit signed integer. This is an alias of {@link ByteBuffer#writeInt64}.
  3266. * @param {number|!Long} value Value to write
  3267. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  3268. * @returns {!ByteBuffer} this
  3269. * @expose
  3270. */
  3271. ByteBufferPrototype.writeLong = ByteBufferPrototype.writeInt64;
  3272. /**
  3273. * Reads a 64bit signed integer.
  3274. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  3275. * @returns {!Long}
  3276. * @expose
  3277. */
  3278. ByteBufferPrototype.readInt64 = function(offset) {
  3279. var relative = typeof offset === 'undefined';
  3280. if (relative) offset = this.offset;
  3281. if (!this.noAssert) {
  3282. if (typeof offset !== 'number' || offset % 1 !== 0)
  3283. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3284. offset >>>= 0;
  3285. if (offset < 0 || offset + 8 > this.buffer.byteLength)
  3286. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
  3287. }
  3288. var lo = 0,
  3289. hi = 0;
  3290. if (this.littleEndian) {
  3291. lo = this.view[offset+2] << 16;
  3292. lo |= this.view[offset+1] << 8;
  3293. lo |= this.view[offset ];
  3294. lo += this.view[offset+3] << 24 >>> 0;
  3295. offset += 4;
  3296. hi = this.view[offset+2] << 16;
  3297. hi |= this.view[offset+1] << 8;
  3298. hi |= this.view[offset ];
  3299. hi += this.view[offset+3] << 24 >>> 0;
  3300. } else {
  3301. hi = this.view[offset+1] << 16;
  3302. hi |= this.view[offset+2] << 8;
  3303. hi |= this.view[offset+3];
  3304. hi += this.view[offset ] << 24 >>> 0;
  3305. offset += 4;
  3306. lo = this.view[offset+1] << 16;
  3307. lo |= this.view[offset+2] << 8;
  3308. lo |= this.view[offset+3];
  3309. lo += this.view[offset ] << 24 >>> 0;
  3310. }
  3311. var value = new Long(lo, hi, false);
  3312. if (relative) this.offset += 8;
  3313. return value;
  3314. };
  3315. /**
  3316. * Reads a 64bit signed integer. This is an alias of {@link ByteBuffer#readInt64}.
  3317. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  3318. * @returns {!Long}
  3319. * @expose
  3320. */
  3321. ByteBufferPrototype.readLong = ByteBufferPrototype.readInt64;
  3322. /**
  3323. * Writes a 64bit unsigned integer.
  3324. * @param {number|!Long} value Value to write
  3325. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  3326. * @returns {!ByteBuffer} this
  3327. * @expose
  3328. */
  3329. ByteBufferPrototype.writeUint64 = function(value, offset) {
  3330. var relative = typeof offset === 'undefined';
  3331. if (relative) offset = this.offset;
  3332. if (!this.noAssert) {
  3333. if (typeof value === 'number')
  3334. value = Long.fromNumber(value);
  3335. else if (typeof value === 'string')
  3336. value = Long.fromString(value);
  3337. else if (!(value && value instanceof Long))
  3338. throw TypeError("Illegal value: "+value+" (not an integer or Long)");
  3339. if (typeof offset !== 'number' || offset % 1 !== 0)
  3340. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3341. offset >>>= 0;
  3342. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3343. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3344. }
  3345. if (typeof value === 'number')
  3346. value = Long.fromNumber(value);
  3347. else if (typeof value === 'string')
  3348. value = Long.fromString(value);
  3349. offset += 8;
  3350. var capacity7 = this.buffer.byteLength;
  3351. if (offset > capacity7)
  3352. this.resize((capacity7 *= 2) > offset ? capacity7 : offset);
  3353. offset -= 8;
  3354. var lo = value.low,
  3355. hi = value.high;
  3356. if (this.littleEndian) {
  3357. this.view[offset+3] = (lo >>> 24) & 0xFF;
  3358. this.view[offset+2] = (lo >>> 16) & 0xFF;
  3359. this.view[offset+1] = (lo >>> 8) & 0xFF;
  3360. this.view[offset ] = lo & 0xFF;
  3361. offset += 4;
  3362. this.view[offset+3] = (hi >>> 24) & 0xFF;
  3363. this.view[offset+2] = (hi >>> 16) & 0xFF;
  3364. this.view[offset+1] = (hi >>> 8) & 0xFF;
  3365. this.view[offset ] = hi & 0xFF;
  3366. } else {
  3367. this.view[offset ] = (hi >>> 24) & 0xFF;
  3368. this.view[offset+1] = (hi >>> 16) & 0xFF;
  3369. this.view[offset+2] = (hi >>> 8) & 0xFF;
  3370. this.view[offset+3] = hi & 0xFF;
  3371. offset += 4;
  3372. this.view[offset ] = (lo >>> 24) & 0xFF;
  3373. this.view[offset+1] = (lo >>> 16) & 0xFF;
  3374. this.view[offset+2] = (lo >>> 8) & 0xFF;
  3375. this.view[offset+3] = lo & 0xFF;
  3376. }
  3377. if (relative) this.offset += 8;
  3378. return this;
  3379. };
  3380. /**
  3381. * Writes a 64bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint64}.
  3382. * @function
  3383. * @param {number|!Long} value Value to write
  3384. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  3385. * @returns {!ByteBuffer} this
  3386. * @expose
  3387. */
  3388. ByteBufferPrototype.writeUInt64 = ByteBufferPrototype.writeUint64;
  3389. /**
  3390. * Reads a 64bit unsigned integer.
  3391. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  3392. * @returns {!Long}
  3393. * @expose
  3394. */
  3395. ByteBufferPrototype.readUint64 = function(offset) {
  3396. var relative = typeof offset === 'undefined';
  3397. if (relative) offset = this.offset;
  3398. if (!this.noAssert) {
  3399. if (typeof offset !== 'number' || offset % 1 !== 0)
  3400. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3401. offset >>>= 0;
  3402. if (offset < 0 || offset + 8 > this.buffer.byteLength)
  3403. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
  3404. }
  3405. var lo = 0,
  3406. hi = 0;
  3407. if (this.littleEndian) {
  3408. lo = this.view[offset+2] << 16;
  3409. lo |= this.view[offset+1] << 8;
  3410. lo |= this.view[offset ];
  3411. lo += this.view[offset+3] << 24 >>> 0;
  3412. offset += 4;
  3413. hi = this.view[offset+2] << 16;
  3414. hi |= this.view[offset+1] << 8;
  3415. hi |= this.view[offset ];
  3416. hi += this.view[offset+3] << 24 >>> 0;
  3417. } else {
  3418. hi = this.view[offset+1] << 16;
  3419. hi |= this.view[offset+2] << 8;
  3420. hi |= this.view[offset+3];
  3421. hi += this.view[offset ] << 24 >>> 0;
  3422. offset += 4;
  3423. lo = this.view[offset+1] << 16;
  3424. lo |= this.view[offset+2] << 8;
  3425. lo |= this.view[offset+3];
  3426. lo += this.view[offset ] << 24 >>> 0;
  3427. }
  3428. var value = new Long(lo, hi, true);
  3429. if (relative) this.offset += 8;
  3430. return value;
  3431. };
  3432. /**
  3433. * Reads a 64bit unsigned integer. This is an alias of {@link ByteBuffer#readUint64}.
  3434. * @function
  3435. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  3436. * @returns {!Long}
  3437. * @expose
  3438. */
  3439. ByteBufferPrototype.readUInt64 = ByteBufferPrototype.readUint64;
  3440. } // Long
  3441. // types/floats/float32
  3442. /*
  3443. ieee754 - https://github.com/feross/ieee754
  3444. The MIT License (MIT)
  3445. Copyright (c) Feross Aboukhadijeh
  3446. Permission is hereby granted, free of charge, to any person obtaining a copy
  3447. of this software and associated documentation files (the "Software"), to deal
  3448. in the Software without restriction, including without limitation the rights
  3449. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  3450. copies of the Software, and to permit persons to whom the Software is
  3451. furnished to do so, subject to the following conditions:
  3452. The above copyright notice and this permission notice shall be included in
  3453. all copies or substantial portions of the Software.
  3454. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  3455. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  3456. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  3457. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  3458. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  3459. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  3460. THE SOFTWARE.
  3461. */
  3462. /**
  3463. * Reads an IEEE754 float from a byte array.
  3464. * @param {!Array} buffer
  3465. * @param {number} offset
  3466. * @param {boolean} isLE
  3467. * @param {number} mLen
  3468. * @param {number} nBytes
  3469. * @returns {number}
  3470. * @inner
  3471. */
  3472. function ieee754_read(buffer, offset, isLE, mLen, nBytes) {
  3473. var e, m,
  3474. eLen = nBytes * 8 - mLen - 1,
  3475. eMax = (1 << eLen) - 1,
  3476. eBias = eMax >> 1,
  3477. nBits = -7,
  3478. i = isLE ? (nBytes - 1) : 0,
  3479. d = isLE ? -1 : 1,
  3480. s = buffer[offset + i];
  3481. i += d;
  3482. e = s & ((1 << (-nBits)) - 1);
  3483. s >>= (-nBits);
  3484. nBits += eLen;
  3485. for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
  3486. m = e & ((1 << (-nBits)) - 1);
  3487. e >>= (-nBits);
  3488. nBits += mLen;
  3489. for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
  3490. if (e === 0) {
  3491. e = 1 - eBias;
  3492. } else if (e === eMax) {
  3493. return m ? NaN : ((s ? -1 : 1) * Infinity);
  3494. } else {
  3495. m = m + Math.pow(2, mLen);
  3496. e = e - eBias;
  3497. }
  3498. return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
  3499. }
  3500. /**
  3501. * Writes an IEEE754 float to a byte array.
  3502. * @param {!Array} buffer
  3503. * @param {number} value
  3504. * @param {number} offset
  3505. * @param {boolean} isLE
  3506. * @param {number} mLen
  3507. * @param {number} nBytes
  3508. * @inner
  3509. */
  3510. function ieee754_write(buffer, value, offset, isLE, mLen, nBytes) {
  3511. var e, m, c,
  3512. eLen = nBytes * 8 - mLen - 1,
  3513. eMax = (1 << eLen) - 1,
  3514. eBias = eMax >> 1,
  3515. rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
  3516. i = isLE ? 0 : (nBytes - 1),
  3517. d = isLE ? 1 : -1,
  3518. s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
  3519. value = Math.abs(value);
  3520. if (isNaN(value) || value === Infinity) {
  3521. m = isNaN(value) ? 1 : 0;
  3522. e = eMax;
  3523. } else {
  3524. e = Math.floor(Math.log(value) / Math.LN2);
  3525. if (value * (c = Math.pow(2, -e)) < 1) {
  3526. e--;
  3527. c *= 2;
  3528. }
  3529. if (e + eBias >= 1) {
  3530. value += rt / c;
  3531. } else {
  3532. value += rt * Math.pow(2, 1 - eBias);
  3533. }
  3534. if (value * c >= 2) {
  3535. e++;
  3536. c /= 2;
  3537. }
  3538. if (e + eBias >= eMax) {
  3539. m = 0;
  3540. e = eMax;
  3541. } else if (e + eBias >= 1) {
  3542. m = (value * c - 1) * Math.pow(2, mLen);
  3543. e = e + eBias;
  3544. } else {
  3545. m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
  3546. e = 0;
  3547. }
  3548. }
  3549. for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
  3550. e = (e << mLen) | m;
  3551. eLen += mLen;
  3552. for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
  3553. buffer[offset + i - d] |= s * 128;
  3554. }
  3555. /**
  3556. * Writes a 32bit float.
  3557. * @param {number} value Value to write
  3558. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  3559. * @returns {!ByteBuffer} this
  3560. * @expose
  3561. */
  3562. ByteBufferPrototype.writeFloat32 = function(value, offset) {
  3563. var relative = typeof offset === 'undefined';
  3564. if (relative) offset = this.offset;
  3565. if (!this.noAssert) {
  3566. if (typeof value !== 'number')
  3567. throw TypeError("Illegal value: "+value+" (not a number)");
  3568. if (typeof offset !== 'number' || offset % 1 !== 0)
  3569. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3570. offset >>>= 0;
  3571. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3572. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3573. }
  3574. offset += 4;
  3575. var capacity8 = this.buffer.byteLength;
  3576. if (offset > capacity8)
  3577. this.resize((capacity8 *= 2) > offset ? capacity8 : offset);
  3578. offset -= 4;
  3579. ieee754_write(this.view, value, offset, this.littleEndian, 23, 4);
  3580. if (relative) this.offset += 4;
  3581. return this;
  3582. };
  3583. /**
  3584. * Writes a 32bit float. This is an alias of {@link ByteBuffer#writeFloat32}.
  3585. * @function
  3586. * @param {number} value Value to write
  3587. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  3588. * @returns {!ByteBuffer} this
  3589. * @expose
  3590. */
  3591. ByteBufferPrototype.writeFloat = ByteBufferPrototype.writeFloat32;
  3592. /**
  3593. * Reads a 32bit float.
  3594. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  3595. * @returns {number}
  3596. * @expose
  3597. */
  3598. ByteBufferPrototype.readFloat32 = function(offset) {
  3599. var relative = typeof offset === 'undefined';
  3600. if (relative) offset = this.offset;
  3601. if (!this.noAssert) {
  3602. if (typeof offset !== 'number' || offset % 1 !== 0)
  3603. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3604. offset >>>= 0;
  3605. if (offset < 0 || offset + 4 > this.buffer.byteLength)
  3606. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
  3607. }
  3608. var value = ieee754_read(this.view, offset, this.littleEndian, 23, 4);
  3609. if (relative) this.offset += 4;
  3610. return value;
  3611. };
  3612. /**
  3613. * Reads a 32bit float. This is an alias of {@link ByteBuffer#readFloat32}.
  3614. * @function
  3615. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  3616. * @returns {number}
  3617. * @expose
  3618. */
  3619. ByteBufferPrototype.readFloat = ByteBufferPrototype.readFloat32;
  3620. // types/floats/float64
  3621. /**
  3622. * Writes a 64bit float.
  3623. * @param {number} value Value to write
  3624. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  3625. * @returns {!ByteBuffer} this
  3626. * @expose
  3627. */
  3628. ByteBufferPrototype.writeFloat64 = function(value, offset) {
  3629. var relative = typeof offset === 'undefined';
  3630. if (relative) offset = this.offset;
  3631. if (!this.noAssert) {
  3632. if (typeof value !== 'number')
  3633. throw TypeError("Illegal value: "+value+" (not a number)");
  3634. if (typeof offset !== 'number' || offset % 1 !== 0)
  3635. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3636. offset >>>= 0;
  3637. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3638. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3639. }
  3640. offset += 8;
  3641. var capacity9 = this.buffer.byteLength;
  3642. if (offset > capacity9)
  3643. this.resize((capacity9 *= 2) > offset ? capacity9 : offset);
  3644. offset -= 8;
  3645. ieee754_write(this.view, value, offset, this.littleEndian, 52, 8);
  3646. if (relative) this.offset += 8;
  3647. return this;
  3648. };
  3649. /**
  3650. * Writes a 64bit float. This is an alias of {@link ByteBuffer#writeFloat64}.
  3651. * @function
  3652. * @param {number} value Value to write
  3653. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  3654. * @returns {!ByteBuffer} this
  3655. * @expose
  3656. */
  3657. ByteBufferPrototype.writeDouble = ByteBufferPrototype.writeFloat64;
  3658. /**
  3659. * Reads a 64bit float.
  3660. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  3661. * @returns {number}
  3662. * @expose
  3663. */
  3664. ByteBufferPrototype.readFloat64 = function(offset) {
  3665. var relative = typeof offset === 'undefined';
  3666. if (relative) offset = this.offset;
  3667. if (!this.noAssert) {
  3668. if (typeof offset !== 'number' || offset % 1 !== 0)
  3669. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3670. offset >>>= 0;
  3671. if (offset < 0 || offset + 8 > this.buffer.byteLength)
  3672. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
  3673. }
  3674. var value = ieee754_read(this.view, offset, this.littleEndian, 52, 8);
  3675. if (relative) this.offset += 8;
  3676. return value;
  3677. };
  3678. /**
  3679. * Reads a 64bit float. This is an alias of {@link ByteBuffer#readFloat64}.
  3680. * @function
  3681. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  3682. * @returns {number}
  3683. * @expose
  3684. */
  3685. ByteBufferPrototype.readDouble = ByteBufferPrototype.readFloat64;
  3686. // types/varints/varint32
  3687. /**
  3688. * Maximum number of bytes required to store a 32bit base 128 variable-length integer.
  3689. * @type {number}
  3690. * @const
  3691. * @expose
  3692. */
  3693. ByteBuffer.MAX_VARINT32_BYTES = 5;
  3694. /**
  3695. * Calculates the actual number of bytes required to store a 32bit base 128 variable-length integer.
  3696. * @param {number} value Value to encode
  3697. * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT32_BYTES}
  3698. * @expose
  3699. */
  3700. ByteBuffer.calculateVarint32 = function(value) {
  3701. // ref: src/google/protobuf/io/coded_stream.cc
  3702. value = value >>> 0;
  3703. if (value < 1 << 7 ) return 1;
  3704. else if (value < 1 << 14) return 2;
  3705. else if (value < 1 << 21) return 3;
  3706. else if (value < 1 << 28) return 4;
  3707. else return 5;
  3708. };
  3709. /**
  3710. * Zigzag encodes a signed 32bit integer so that it can be effectively used with varint encoding.
  3711. * @param {number} n Signed 32bit integer
  3712. * @returns {number} Unsigned zigzag encoded 32bit integer
  3713. * @expose
  3714. */
  3715. ByteBuffer.zigZagEncode32 = function(n) {
  3716. return (((n |= 0) << 1) ^ (n >> 31)) >>> 0; // ref: src/google/protobuf/wire_format_lite.h
  3717. };
  3718. /**
  3719. * Decodes a zigzag encoded signed 32bit integer.
  3720. * @param {number} n Unsigned zigzag encoded 32bit integer
  3721. * @returns {number} Signed 32bit integer
  3722. * @expose
  3723. */
  3724. ByteBuffer.zigZagDecode32 = function(n) {
  3725. return ((n >>> 1) ^ -(n & 1)) | 0; // // ref: src/google/protobuf/wire_format_lite.h
  3726. };
  3727. /**
  3728. * Writes a 32bit base 128 variable-length integer.
  3729. * @param {number} value Value to write
  3730. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  3731. * written if omitted.
  3732. * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written
  3733. * @expose
  3734. */
  3735. ByteBufferPrototype.writeVarint32 = function(value, offset) {
  3736. var relative = typeof offset === 'undefined';
  3737. if (relative) offset = this.offset;
  3738. if (!this.noAssert) {
  3739. if (typeof value !== 'number' || value % 1 !== 0)
  3740. throw TypeError("Illegal value: "+value+" (not an integer)");
  3741. value |= 0;
  3742. if (typeof offset !== 'number' || offset % 1 !== 0)
  3743. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3744. offset >>>= 0;
  3745. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3746. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3747. }
  3748. var size = ByteBuffer.calculateVarint32(value),
  3749. b;
  3750. offset += size;
  3751. var capacity10 = this.buffer.byteLength;
  3752. if (offset > capacity10)
  3753. this.resize((capacity10 *= 2) > offset ? capacity10 : offset);
  3754. offset -= size;
  3755. value >>>= 0;
  3756. while (value >= 0x80) {
  3757. b = (value & 0x7f) | 0x80;
  3758. this.view[offset++] = b;
  3759. value >>>= 7;
  3760. }
  3761. this.view[offset++] = value;
  3762. if (relative) {
  3763. this.offset = offset;
  3764. return this;
  3765. }
  3766. return size;
  3767. };
  3768. /**
  3769. * Writes a zig-zag encoded (signed) 32bit base 128 variable-length integer.
  3770. * @param {number} value Value to write
  3771. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  3772. * written if omitted.
  3773. * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written
  3774. * @expose
  3775. */
  3776. ByteBufferPrototype.writeVarint32ZigZag = function(value, offset) {
  3777. return this.writeVarint32(ByteBuffer.zigZagEncode32(value), offset);
  3778. };
  3779. /**
  3780. * Reads a 32bit base 128 variable-length integer.
  3781. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  3782. * written if omitted.
  3783. * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read
  3784. * and the actual number of bytes read.
  3785. * @throws {Error} If it's not a valid varint. Has a property `truncated = true` if there is not enough data available
  3786. * to fully decode the varint.
  3787. * @expose
  3788. */
  3789. ByteBufferPrototype.readVarint32 = function(offset) {
  3790. var relative = typeof offset === 'undefined';
  3791. if (relative) offset = this.offset;
  3792. if (!this.noAssert) {
  3793. if (typeof offset !== 'number' || offset % 1 !== 0)
  3794. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3795. offset >>>= 0;
  3796. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  3797. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  3798. }
  3799. var c = 0,
  3800. value = 0 >>> 0,
  3801. b;
  3802. do {
  3803. if (!this.noAssert && offset > this.limit) {
  3804. var err = Error("Truncated");
  3805. err['truncated'] = true;
  3806. throw err;
  3807. }
  3808. b = this.view[offset++];
  3809. if (c < 5)
  3810. value |= (b & 0x7f) << (7*c);
  3811. ++c;
  3812. } while ((b & 0x80) !== 0);
  3813. value |= 0;
  3814. if (relative) {
  3815. this.offset = offset;
  3816. return value;
  3817. }
  3818. return {
  3819. "value": value,
  3820. "length": c
  3821. };
  3822. };
  3823. /**
  3824. * Reads a zig-zag encoded (signed) 32bit base 128 variable-length integer.
  3825. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  3826. * written if omitted.
  3827. * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read
  3828. * and the actual number of bytes read.
  3829. * @throws {Error} If it's not a valid varint
  3830. * @expose
  3831. */
  3832. ByteBufferPrototype.readVarint32ZigZag = function(offset) {
  3833. var val = this.readVarint32(offset);
  3834. if (typeof val === 'object')
  3835. val["value"] = ByteBuffer.zigZagDecode32(val["value"]);
  3836. else
  3837. val = ByteBuffer.zigZagDecode32(val);
  3838. return val;
  3839. };
  3840. // types/varints/varint64
  3841. if (Long) {
  3842. /**
  3843. * Maximum number of bytes required to store a 64bit base 128 variable-length integer.
  3844. * @type {number}
  3845. * @const
  3846. * @expose
  3847. */
  3848. ByteBuffer.MAX_VARINT64_BYTES = 10;
  3849. /**
  3850. * Calculates the actual number of bytes required to store a 64bit base 128 variable-length integer.
  3851. * @param {number|!Long} value Value to encode
  3852. * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT64_BYTES}
  3853. * @expose
  3854. */
  3855. ByteBuffer.calculateVarint64 = function(value) {
  3856. if (typeof value === 'number')
  3857. value = Long.fromNumber(value);
  3858. else if (typeof value === 'string')
  3859. value = Long.fromString(value);
  3860. // ref: src/google/protobuf/io/coded_stream.cc
  3861. var part0 = value.toInt() >>> 0,
  3862. part1 = value.shiftRightUnsigned(28).toInt() >>> 0,
  3863. part2 = value.shiftRightUnsigned(56).toInt() >>> 0;
  3864. if (part2 == 0) {
  3865. if (part1 == 0) {
  3866. if (part0 < 1 << 14)
  3867. return part0 < 1 << 7 ? 1 : 2;
  3868. else
  3869. return part0 < 1 << 21 ? 3 : 4;
  3870. } else {
  3871. if (part1 < 1 << 14)
  3872. return part1 < 1 << 7 ? 5 : 6;
  3873. else
  3874. return part1 < 1 << 21 ? 7 : 8;
  3875. }
  3876. } else
  3877. return part2 < 1 << 7 ? 9 : 10;
  3878. };
  3879. /**
  3880. * Zigzag encodes a signed 64bit integer so that it can be effectively used with varint encoding.
  3881. * @param {number|!Long} value Signed long
  3882. * @returns {!Long} Unsigned zigzag encoded long
  3883. * @expose
  3884. */
  3885. ByteBuffer.zigZagEncode64 = function(value) {
  3886. if (typeof value === 'number')
  3887. value = Long.fromNumber(value, false);
  3888. else if (typeof value === 'string')
  3889. value = Long.fromString(value, false);
  3890. else if (value.unsigned !== false) value = value.toSigned();
  3891. // ref: src/google/protobuf/wire_format_lite.h
  3892. return value.shiftLeft(1).xor(value.shiftRight(63)).toUnsigned();
  3893. };
  3894. /**
  3895. * Decodes a zigzag encoded signed 64bit integer.
  3896. * @param {!Long|number} value Unsigned zigzag encoded long or JavaScript number
  3897. * @returns {!Long} Signed long
  3898. * @expose
  3899. */
  3900. ByteBuffer.zigZagDecode64 = function(value) {
  3901. if (typeof value === 'number')
  3902. value = Long.fromNumber(value, false);
  3903. else if (typeof value === 'string')
  3904. value = Long.fromString(value, false);
  3905. else if (value.unsigned !== false) value = value.toSigned();
  3906. // ref: src/google/protobuf/wire_format_lite.h
  3907. return value.shiftRightUnsigned(1).xor(value.and(Long.ONE).toSigned().negate()).toSigned();
  3908. };
  3909. /**
  3910. * Writes a 64bit base 128 variable-length integer.
  3911. * @param {number|Long} value Value to write
  3912. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  3913. * written if omitted.
  3914. * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written.
  3915. * @expose
  3916. */
  3917. ByteBufferPrototype.writeVarint64 = function(value, offset) {
  3918. var relative = typeof offset === 'undefined';
  3919. if (relative) offset = this.offset;
  3920. if (!this.noAssert) {
  3921. if (typeof value === 'number')
  3922. value = Long.fromNumber(value);
  3923. else if (typeof value === 'string')
  3924. value = Long.fromString(value);
  3925. else if (!(value && value instanceof Long))
  3926. throw TypeError("Illegal value: "+value+" (not an integer or Long)");
  3927. if (typeof offset !== 'number' || offset % 1 !== 0)
  3928. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3929. offset >>>= 0;
  3930. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3931. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3932. }
  3933. if (typeof value === 'number')
  3934. value = Long.fromNumber(value, false);
  3935. else if (typeof value === 'string')
  3936. value = Long.fromString(value, false);
  3937. else if (value.unsigned !== false) value = value.toSigned();
  3938. var size = ByteBuffer.calculateVarint64(value),
  3939. part0 = value.toInt() >>> 0,
  3940. part1 = value.shiftRightUnsigned(28).toInt() >>> 0,
  3941. part2 = value.shiftRightUnsigned(56).toInt() >>> 0;
  3942. offset += size;
  3943. var capacity11 = this.buffer.byteLength;
  3944. if (offset > capacity11)
  3945. this.resize((capacity11 *= 2) > offset ? capacity11 : offset);
  3946. offset -= size;
  3947. switch (size) {
  3948. case 10: this.view[offset+9] = (part2 >>> 7) & 0x01;
  3949. case 9 : this.view[offset+8] = size !== 9 ? (part2 ) | 0x80 : (part2 ) & 0x7F;
  3950. case 8 : this.view[offset+7] = size !== 8 ? (part1 >>> 21) | 0x80 : (part1 >>> 21) & 0x7F;
  3951. case 7 : this.view[offset+6] = size !== 7 ? (part1 >>> 14) | 0x80 : (part1 >>> 14) & 0x7F;
  3952. case 6 : this.view[offset+5] = size !== 6 ? (part1 >>> 7) | 0x80 : (part1 >>> 7) & 0x7F;
  3953. case 5 : this.view[offset+4] = size !== 5 ? (part1 ) | 0x80 : (part1 ) & 0x7F;
  3954. case 4 : this.view[offset+3] = size !== 4 ? (part0 >>> 21) | 0x80 : (part0 >>> 21) & 0x7F;
  3955. case 3 : this.view[offset+2] = size !== 3 ? (part0 >>> 14) | 0x80 : (part0 >>> 14) & 0x7F;
  3956. case 2 : this.view[offset+1] = size !== 2 ? (part0 >>> 7) | 0x80 : (part0 >>> 7) & 0x7F;
  3957. case 1 : this.view[offset ] = size !== 1 ? (part0 ) | 0x80 : (part0 ) & 0x7F;
  3958. }
  3959. if (relative) {
  3960. this.offset += size;
  3961. return this;
  3962. } else {
  3963. return size;
  3964. }
  3965. };
  3966. /**
  3967. * Writes a zig-zag encoded 64bit base 128 variable-length integer.
  3968. * @param {number|Long} value Value to write
  3969. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  3970. * written if omitted.
  3971. * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written.
  3972. * @expose
  3973. */
  3974. ByteBufferPrototype.writeVarint64ZigZag = function(value, offset) {
  3975. return this.writeVarint64(ByteBuffer.zigZagEncode64(value), offset);
  3976. };
  3977. /**
  3978. * Reads a 64bit base 128 variable-length integer. Requires Long.js.
  3979. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  3980. * read if omitted.
  3981. * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and
  3982. * the actual number of bytes read.
  3983. * @throws {Error} If it's not a valid varint
  3984. * @expose
  3985. */
  3986. ByteBufferPrototype.readVarint64 = function(offset) {
  3987. var relative = typeof offset === 'undefined';
  3988. if (relative) offset = this.offset;
  3989. if (!this.noAssert) {
  3990. if (typeof offset !== 'number' || offset % 1 !== 0)
  3991. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3992. offset >>>= 0;
  3993. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  3994. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  3995. }
  3996. // ref: src/google/protobuf/io/coded_stream.cc
  3997. var start = offset,
  3998. part0 = 0,
  3999. part1 = 0,
  4000. part2 = 0,
  4001. b = 0;
  4002. b = this.view[offset++]; part0 = (b & 0x7F) ; if ( b & 0x80 ) {
  4003. b = this.view[offset++]; part0 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4004. b = this.view[offset++]; part0 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4005. b = this.view[offset++]; part0 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4006. b = this.view[offset++]; part1 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4007. b = this.view[offset++]; part1 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4008. b = this.view[offset++]; part1 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4009. b = this.view[offset++]; part1 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4010. b = this.view[offset++]; part2 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4011. b = this.view[offset++]; part2 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4012. throw Error("Buffer overrun"); }}}}}}}}}}
  4013. var value = Long.fromBits(part0 | (part1 << 28), (part1 >>> 4) | (part2) << 24, false);
  4014. if (relative) {
  4015. this.offset = offset;
  4016. return value;
  4017. } else {
  4018. return {
  4019. 'value': value,
  4020. 'length': offset-start
  4021. };
  4022. }
  4023. };
  4024. /**
  4025. * Reads a zig-zag encoded 64bit base 128 variable-length integer. Requires Long.js.
  4026. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4027. * read if omitted.
  4028. * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and
  4029. * the actual number of bytes read.
  4030. * @throws {Error} If it's not a valid varint
  4031. * @expose
  4032. */
  4033. ByteBufferPrototype.readVarint64ZigZag = function(offset) {
  4034. var val = this.readVarint64(offset);
  4035. if (val && val['value'] instanceof Long)
  4036. val["value"] = ByteBuffer.zigZagDecode64(val["value"]);
  4037. else
  4038. val = ByteBuffer.zigZagDecode64(val);
  4039. return val;
  4040. };
  4041. } // Long
  4042. // types/strings/cstring
  4043. /**
  4044. * Writes a NULL-terminated UTF8 encoded string. For this to work the specified string must not contain any NULL
  4045. * characters itself.
  4046. * @param {string} str String to write
  4047. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4048. * contained in `str` + 1 if omitted.
  4049. * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written
  4050. * @expose
  4051. */
  4052. ByteBufferPrototype.writeCString = function(str, offset) {
  4053. var relative = typeof offset === 'undefined';
  4054. if (relative) offset = this.offset;
  4055. var i,
  4056. k = str.length;
  4057. if (!this.noAssert) {
  4058. if (typeof str !== 'string')
  4059. throw TypeError("Illegal str: Not a string");
  4060. for (i=0; i<k; ++i) {
  4061. if (str.charCodeAt(i) === 0)
  4062. throw RangeError("Illegal str: Contains NULL-characters");
  4063. }
  4064. if (typeof offset !== 'number' || offset % 1 !== 0)
  4065. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4066. offset >>>= 0;
  4067. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  4068. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  4069. }
  4070. // UTF8 strings do not contain zero bytes in between except for the zero character, so:
  4071. k = utfx.calculateUTF16asUTF8(stringSource(str))[1];
  4072. offset += k+1;
  4073. var capacity12 = this.buffer.byteLength;
  4074. if (offset > capacity12)
  4075. this.resize((capacity12 *= 2) > offset ? capacity12 : offset);
  4076. offset -= k+1;
  4077. utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
  4078. this.view[offset++] = b;
  4079. }.bind(this));
  4080. this.view[offset++] = 0;
  4081. if (relative) {
  4082. this.offset = offset;
  4083. return this;
  4084. }
  4085. return k;
  4086. };
  4087. /**
  4088. * Reads a NULL-terminated UTF8 encoded string. For this to work the string read must not contain any NULL characters
  4089. * itself.
  4090. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4091. * read if omitted.
  4092. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
  4093. * read and the actual number of bytes read.
  4094. * @expose
  4095. */
  4096. ByteBufferPrototype.readCString = function(offset) {
  4097. var relative = typeof offset === 'undefined';
  4098. if (relative) offset = this.offset;
  4099. if (!this.noAssert) {
  4100. if (typeof offset !== 'number' || offset % 1 !== 0)
  4101. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4102. offset >>>= 0;
  4103. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  4104. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  4105. }
  4106. var start = offset;
  4107. // UTF8 strings do not contain zero bytes in between except for the zero character itself, so:
  4108. var sd, b = -1;
  4109. utfx.decodeUTF8toUTF16(function() {
  4110. if (b === 0) return null;
  4111. if (offset >= this.limit)
  4112. throw RangeError("Illegal range: Truncated data, "+offset+" < "+this.limit);
  4113. b = this.view[offset++];
  4114. return b === 0 ? null : b;
  4115. }.bind(this), sd = stringDestination(), true);
  4116. if (relative) {
  4117. this.offset = offset;
  4118. return sd();
  4119. } else {
  4120. return {
  4121. "string": sd(),
  4122. "length": offset - start
  4123. };
  4124. }
  4125. };
  4126. // types/strings/istring
  4127. /**
  4128. * Writes a length as uint32 prefixed UTF8 encoded string.
  4129. * @param {string} str String to write
  4130. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4131. * written if omitted.
  4132. * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written
  4133. * @expose
  4134. * @see ByteBuffer#writeVarint32
  4135. */
  4136. ByteBufferPrototype.writeIString = function(str, offset) {
  4137. var relative = typeof offset === 'undefined';
  4138. if (relative) offset = this.offset;
  4139. if (!this.noAssert) {
  4140. if (typeof str !== 'string')
  4141. throw TypeError("Illegal str: Not a string");
  4142. if (typeof offset !== 'number' || offset % 1 !== 0)
  4143. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4144. offset >>>= 0;
  4145. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  4146. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  4147. }
  4148. var start = offset,
  4149. k;
  4150. k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1];
  4151. offset += 4+k;
  4152. var capacity13 = this.buffer.byteLength;
  4153. if (offset > capacity13)
  4154. this.resize((capacity13 *= 2) > offset ? capacity13 : offset);
  4155. offset -= 4+k;
  4156. if (this.littleEndian) {
  4157. this.view[offset+3] = (k >>> 24) & 0xFF;
  4158. this.view[offset+2] = (k >>> 16) & 0xFF;
  4159. this.view[offset+1] = (k >>> 8) & 0xFF;
  4160. this.view[offset ] = k & 0xFF;
  4161. } else {
  4162. this.view[offset ] = (k >>> 24) & 0xFF;
  4163. this.view[offset+1] = (k >>> 16) & 0xFF;
  4164. this.view[offset+2] = (k >>> 8) & 0xFF;
  4165. this.view[offset+3] = k & 0xFF;
  4166. }
  4167. offset += 4;
  4168. utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
  4169. this.view[offset++] = b;
  4170. }.bind(this));
  4171. if (offset !== start + 4 + k)
  4172. throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+4+k));
  4173. if (relative) {
  4174. this.offset = offset;
  4175. return this;
  4176. }
  4177. return offset - start;
  4178. };
  4179. /**
  4180. * Reads a length as uint32 prefixed UTF8 encoded string.
  4181. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4182. * read if omitted.
  4183. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
  4184. * read and the actual number of bytes read.
  4185. * @expose
  4186. * @see ByteBuffer#readVarint32
  4187. */
  4188. ByteBufferPrototype.readIString = function(offset) {
  4189. var relative = typeof offset === 'undefined';
  4190. if (relative) offset = this.offset;
  4191. if (!this.noAssert) {
  4192. if (typeof offset !== 'number' || offset % 1 !== 0)
  4193. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4194. offset >>>= 0;
  4195. if (offset < 0 || offset + 4 > this.buffer.byteLength)
  4196. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
  4197. }
  4198. var start = offset;
  4199. var len = this.readUint32(offset);
  4200. var str = this.readUTF8String(len, ByteBuffer.METRICS_BYTES, offset += 4);
  4201. offset += str['length'];
  4202. if (relative) {
  4203. this.offset = offset;
  4204. return str['string'];
  4205. } else {
  4206. return {
  4207. 'string': str['string'],
  4208. 'length': offset - start
  4209. };
  4210. }
  4211. };
  4212. // types/strings/utf8string
  4213. /**
  4214. * Metrics representing number of UTF8 characters. Evaluates to `c`.
  4215. * @type {string}
  4216. * @const
  4217. * @expose
  4218. */
  4219. ByteBuffer.METRICS_CHARS = 'c';
  4220. /**
  4221. * Metrics representing number of bytes. Evaluates to `b`.
  4222. * @type {string}
  4223. * @const
  4224. * @expose
  4225. */
  4226. ByteBuffer.METRICS_BYTES = 'b';
  4227. /**
  4228. * Writes an UTF8 encoded string.
  4229. * @param {string} str String to write
  4230. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted.
  4231. * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written.
  4232. * @expose
  4233. */
  4234. ByteBufferPrototype.writeUTF8String = function(str, offset) {
  4235. var relative = typeof offset === 'undefined';
  4236. if (relative) offset = this.offset;
  4237. if (!this.noAssert) {
  4238. if (typeof offset !== 'number' || offset % 1 !== 0)
  4239. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4240. offset >>>= 0;
  4241. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  4242. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  4243. }
  4244. var k;
  4245. var start = offset;
  4246. k = utfx.calculateUTF16asUTF8(stringSource(str))[1];
  4247. offset += k;
  4248. var capacity14 = this.buffer.byteLength;
  4249. if (offset > capacity14)
  4250. this.resize((capacity14 *= 2) > offset ? capacity14 : offset);
  4251. offset -= k;
  4252. utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
  4253. this.view[offset++] = b;
  4254. }.bind(this));
  4255. if (relative) {
  4256. this.offset = offset;
  4257. return this;
  4258. }
  4259. return offset - start;
  4260. };
  4261. /**
  4262. * Writes an UTF8 encoded string. This is an alias of {@link ByteBuffer#writeUTF8String}.
  4263. * @function
  4264. * @param {string} str String to write
  4265. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted.
  4266. * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written.
  4267. * @expose
  4268. */
  4269. ByteBufferPrototype.writeString = ByteBufferPrototype.writeUTF8String;
  4270. /**
  4271. * Calculates the number of UTF8 characters of a string. JavaScript itself uses UTF-16, so that a string's
  4272. * `length` property does not reflect its actual UTF8 size if it contains code points larger than 0xFFFF.
  4273. * @param {string} str String to calculate
  4274. * @returns {number} Number of UTF8 characters
  4275. * @expose
  4276. */
  4277. ByteBuffer.calculateUTF8Chars = function(str) {
  4278. return utfx.calculateUTF16asUTF8(stringSource(str))[0];
  4279. };
  4280. /**
  4281. * Calculates the number of UTF8 bytes of a string.
  4282. * @param {string} str String to calculate
  4283. * @returns {number} Number of UTF8 bytes
  4284. * @expose
  4285. */
  4286. ByteBuffer.calculateUTF8Bytes = function(str) {
  4287. return utfx.calculateUTF16asUTF8(stringSource(str))[1];
  4288. };
  4289. /**
  4290. * Calculates the number of UTF8 bytes of a string. This is an alias of {@link ByteBuffer.calculateUTF8Bytes}.
  4291. * @function
  4292. * @param {string} str String to calculate
  4293. * @returns {number} Number of UTF8 bytes
  4294. * @expose
  4295. */
  4296. ByteBuffer.calculateString = ByteBuffer.calculateUTF8Bytes;
  4297. /**
  4298. * Reads an UTF8 encoded string.
  4299. * @param {number} length Number of characters or bytes to read.
  4300. * @param {string=} metrics Metrics specifying what `length` is meant to count. Defaults to
  4301. * {@link ByteBuffer.METRICS_CHARS}.
  4302. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4303. * read if omitted.
  4304. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
  4305. * read and the actual number of bytes read.
  4306. * @expose
  4307. */
  4308. ByteBufferPrototype.readUTF8String = function(length, metrics, offset) {
  4309. if (typeof metrics === 'number') {
  4310. offset = metrics;
  4311. metrics = undefined;
  4312. }
  4313. var relative = typeof offset === 'undefined';
  4314. if (relative) offset = this.offset;
  4315. if (typeof metrics === 'undefined') metrics = ByteBuffer.METRICS_CHARS;
  4316. if (!this.noAssert) {
  4317. if (typeof length !== 'number' || length % 1 !== 0)
  4318. throw TypeError("Illegal length: "+length+" (not an integer)");
  4319. length |= 0;
  4320. if (typeof offset !== 'number' || offset % 1 !== 0)
  4321. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4322. offset >>>= 0;
  4323. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  4324. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  4325. }
  4326. var i = 0,
  4327. start = offset,
  4328. sd;
  4329. if (metrics === ByteBuffer.METRICS_CHARS) { // The same for node and the browser
  4330. sd = stringDestination();
  4331. utfx.decodeUTF8(function() {
  4332. return i < length && offset < this.limit ? this.view[offset++] : null;
  4333. }.bind(this), function(cp) {
  4334. ++i; utfx.UTF8toUTF16(cp, sd);
  4335. });
  4336. if (i !== length)
  4337. throw RangeError("Illegal range: Truncated data, "+i+" == "+length);
  4338. if (relative) {
  4339. this.offset = offset;
  4340. return sd();
  4341. } else {
  4342. return {
  4343. "string": sd(),
  4344. "length": offset - start
  4345. };
  4346. }
  4347. } else if (metrics === ByteBuffer.METRICS_BYTES) {
  4348. if (!this.noAssert) {
  4349. if (typeof offset !== 'number' || offset % 1 !== 0)
  4350. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4351. offset >>>= 0;
  4352. if (offset < 0 || offset + length > this.buffer.byteLength)
  4353. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength);
  4354. }
  4355. var k = offset + length;
  4356. utfx.decodeUTF8toUTF16(function() {
  4357. return offset < k ? this.view[offset++] : null;
  4358. }.bind(this), sd = stringDestination(), this.noAssert);
  4359. if (offset !== k)
  4360. throw RangeError("Illegal range: Truncated data, "+offset+" == "+k);
  4361. if (relative) {
  4362. this.offset = offset;
  4363. return sd();
  4364. } else {
  4365. return {
  4366. 'string': sd(),
  4367. 'length': offset - start
  4368. };
  4369. }
  4370. } else
  4371. throw TypeError("Unsupported metrics: "+metrics);
  4372. };
  4373. /**
  4374. * Reads an UTF8 encoded string. This is an alias of {@link ByteBuffer#readUTF8String}.
  4375. * @function
  4376. * @param {number} length Number of characters or bytes to read
  4377. * @param {number=} metrics Metrics specifying what `n` is meant to count. Defaults to
  4378. * {@link ByteBuffer.METRICS_CHARS}.
  4379. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4380. * read if omitted.
  4381. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
  4382. * read and the actual number of bytes read.
  4383. * @expose
  4384. */
  4385. ByteBufferPrototype.readString = ByteBufferPrototype.readUTF8String;
  4386. // types/strings/vstring
  4387. /**
  4388. * Writes a length as varint32 prefixed UTF8 encoded string.
  4389. * @param {string} str String to write
  4390. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4391. * written if omitted.
  4392. * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written
  4393. * @expose
  4394. * @see ByteBuffer#writeVarint32
  4395. */
  4396. ByteBufferPrototype.writeVString = function(str, offset) {
  4397. var relative = typeof offset === 'undefined';
  4398. if (relative) offset = this.offset;
  4399. if (!this.noAssert) {
  4400. if (typeof str !== 'string')
  4401. throw TypeError("Illegal str: Not a string");
  4402. if (typeof offset !== 'number' || offset % 1 !== 0)
  4403. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4404. offset >>>= 0;
  4405. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  4406. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  4407. }
  4408. var start = offset,
  4409. k, l;
  4410. k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1];
  4411. l = ByteBuffer.calculateVarint32(k);
  4412. offset += l+k;
  4413. var capacity15 = this.buffer.byteLength;
  4414. if (offset > capacity15)
  4415. this.resize((capacity15 *= 2) > offset ? capacity15 : offset);
  4416. offset -= l+k;
  4417. offset += this.writeVarint32(k, offset);
  4418. utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
  4419. this.view[offset++] = b;
  4420. }.bind(this));
  4421. if (offset !== start+k+l)
  4422. throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+k+l));
  4423. if (relative) {
  4424. this.offset = offset;
  4425. return this;
  4426. }
  4427. return offset - start;
  4428. };
  4429. /**
  4430. * Reads a length as varint32 prefixed UTF8 encoded string.
  4431. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4432. * read if omitted.
  4433. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
  4434. * read and the actual number of bytes read.
  4435. * @expose
  4436. * @see ByteBuffer#readVarint32
  4437. */
  4438. ByteBufferPrototype.readVString = function(offset) {
  4439. var relative = typeof offset === 'undefined';
  4440. if (relative) offset = this.offset;
  4441. if (!this.noAssert) {
  4442. if (typeof offset !== 'number' || offset % 1 !== 0)
  4443. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4444. offset >>>= 0;
  4445. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  4446. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  4447. }
  4448. var start = offset;
  4449. var len = this.readVarint32(offset);
  4450. var str = this.readUTF8String(len['value'], ByteBuffer.METRICS_BYTES, offset += len['length']);
  4451. offset += str['length'];
  4452. if (relative) {
  4453. this.offset = offset;
  4454. return str['string'];
  4455. } else {
  4456. return {
  4457. 'string': str['string'],
  4458. 'length': offset - start
  4459. };
  4460. }
  4461. };
  4462. /**
  4463. * Appends some data to this ByteBuffer. This will overwrite any contents behind the specified offset up to the appended
  4464. * data's length.
  4465. * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to append. If `source` is a ByteBuffer, its offsets
  4466. * will be modified according to the performed read operation.
  4467. * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
  4468. * @param {number=} offset Offset to append at. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4469. * written if omitted.
  4470. * @returns {!ByteBuffer} this
  4471. * @expose
  4472. * @example A relative `<01 02>03.append(<04 05>)` will result in `<01 02 04 05>, 04 05|`
  4473. * @example An absolute `<01 02>03.append(04 05>, 1)` will result in `<01 04>05, 04 05|`
  4474. */
  4475. ByteBufferPrototype.append = function(source, encoding, offset) {
  4476. if (typeof encoding === 'number' || typeof encoding !== 'string') {
  4477. offset = encoding;
  4478. encoding = undefined;
  4479. }
  4480. var relative = typeof offset === 'undefined';
  4481. if (relative) offset = this.offset;
  4482. if (!this.noAssert) {
  4483. if (typeof offset !== 'number' || offset % 1 !== 0)
  4484. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4485. offset >>>= 0;
  4486. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  4487. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  4488. }
  4489. if (!(source instanceof ByteBuffer))
  4490. source = ByteBuffer.wrap(source, encoding);
  4491. var length = source.limit - source.offset;
  4492. if (length <= 0) return this; // Nothing to append
  4493. offset += length;
  4494. var capacity16 = this.buffer.byteLength;
  4495. if (offset > capacity16)
  4496. this.resize((capacity16 *= 2) > offset ? capacity16 : offset);
  4497. offset -= length;
  4498. this.view.set(source.view.subarray(source.offset, source.limit), offset);
  4499. source.offset += length;
  4500. if (relative) this.offset += length;
  4501. return this;
  4502. };
  4503. /**
  4504. * Appends this ByteBuffer's contents to another ByteBuffer. This will overwrite any contents at and after the
  4505. specified offset up to the length of this ByteBuffer's data.
  4506. * @param {!ByteBuffer} target Target ByteBuffer
  4507. * @param {number=} offset Offset to append to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4508. * read if omitted.
  4509. * @returns {!ByteBuffer} this
  4510. * @expose
  4511. * @see ByteBuffer#append
  4512. */
  4513. ByteBufferPrototype.appendTo = function(target, offset) {
  4514. target.append(this, offset);
  4515. return this;
  4516. };
  4517. /**
  4518. * Enables or disables assertions of argument types and offsets. Assertions are enabled by default but you can opt to
  4519. * disable them if your code already makes sure that everything is valid.
  4520. * @param {boolean} assert `true` to enable assertions, otherwise `false`
  4521. * @returns {!ByteBuffer} this
  4522. * @expose
  4523. */
  4524. ByteBufferPrototype.assert = function(assert) {
  4525. this.noAssert = !assert;
  4526. return this;
  4527. };
  4528. /**
  4529. * Gets the capacity of this ByteBuffer's backing buffer.
  4530. * @returns {number} Capacity of the backing buffer
  4531. * @expose
  4532. */
  4533. ByteBufferPrototype.capacity = function() {
  4534. return this.buffer.byteLength;
  4535. };
  4536. /**
  4537. * Clears this ByteBuffer's offsets by setting {@link ByteBuffer#offset} to `0` and {@link ByteBuffer#limit} to the
  4538. * backing buffer's capacity. Discards {@link ByteBuffer#markedOffset}.
  4539. * @returns {!ByteBuffer} this
  4540. * @expose
  4541. */
  4542. ByteBufferPrototype.clear = function() {
  4543. this.offset = 0;
  4544. this.limit = this.buffer.byteLength;
  4545. this.markedOffset = -1;
  4546. return this;
  4547. };
  4548. /**
  4549. * Creates a cloned instance of this ByteBuffer, preset with this ByteBuffer's values for {@link ByteBuffer#offset},
  4550. * {@link ByteBuffer#markedOffset} and {@link ByteBuffer#limit}.
  4551. * @param {boolean=} copy Whether to copy the backing buffer or to return another view on the same, defaults to `false`
  4552. * @returns {!ByteBuffer} Cloned instance
  4553. * @expose
  4554. */
  4555. ByteBufferPrototype.clone = function(copy) {
  4556. var bb = new ByteBuffer(0, this.littleEndian, this.noAssert);
  4557. if (copy) {
  4558. bb.buffer = new ArrayBuffer(this.buffer.byteLength);
  4559. bb.view = new Uint8Array(bb.buffer);
  4560. } else {
  4561. bb.buffer = this.buffer;
  4562. bb.view = this.view;
  4563. }
  4564. bb.offset = this.offset;
  4565. bb.markedOffset = this.markedOffset;
  4566. bb.limit = this.limit;
  4567. return bb;
  4568. };
  4569. /**
  4570. * Compacts this ByteBuffer to be backed by a {@link ByteBuffer#buffer} of its contents' length. Contents are the bytes
  4571. * between {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. Will set `offset = 0` and `limit = capacity` and
  4572. * adapt {@link ByteBuffer#markedOffset} to the same relative position if set.
  4573. * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
  4574. * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
  4575. * @returns {!ByteBuffer} this
  4576. * @expose
  4577. */
  4578. ByteBufferPrototype.compact = function(begin, end) {
  4579. if (typeof begin === 'undefined') begin = this.offset;
  4580. if (typeof end === 'undefined') end = this.limit;
  4581. if (!this.noAssert) {
  4582. if (typeof begin !== 'number' || begin % 1 !== 0)
  4583. throw TypeError("Illegal begin: Not an integer");
  4584. begin >>>= 0;
  4585. if (typeof end !== 'number' || end % 1 !== 0)
  4586. throw TypeError("Illegal end: Not an integer");
  4587. end >>>= 0;
  4588. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  4589. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  4590. }
  4591. if (begin === 0 && end === this.buffer.byteLength)
  4592. return this; // Already compacted
  4593. var len = end - begin;
  4594. if (len === 0) {
  4595. this.buffer = EMPTY_BUFFER;
  4596. this.view = null;
  4597. if (this.markedOffset >= 0) this.markedOffset -= begin;
  4598. this.offset = 0;
  4599. this.limit = 0;
  4600. return this;
  4601. }
  4602. var buffer = new ArrayBuffer(len);
  4603. var view = new Uint8Array(buffer);
  4604. view.set(this.view.subarray(begin, end));
  4605. this.buffer = buffer;
  4606. this.view = view;
  4607. if (this.markedOffset >= 0) this.markedOffset -= begin;
  4608. this.offset = 0;
  4609. this.limit = len;
  4610. return this;
  4611. };
  4612. /**
  4613. * Creates a copy of this ByteBuffer's contents. Contents are the bytes between {@link ByteBuffer#offset} and
  4614. * {@link ByteBuffer#limit}.
  4615. * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
  4616. * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
  4617. * @returns {!ByteBuffer} Copy
  4618. * @expose
  4619. */
  4620. ByteBufferPrototype.copy = function(begin, end) {
  4621. if (typeof begin === 'undefined') begin = this.offset;
  4622. if (typeof end === 'undefined') end = this.limit;
  4623. if (!this.noAssert) {
  4624. if (typeof begin !== 'number' || begin % 1 !== 0)
  4625. throw TypeError("Illegal begin: Not an integer");
  4626. begin >>>= 0;
  4627. if (typeof end !== 'number' || end % 1 !== 0)
  4628. throw TypeError("Illegal end: Not an integer");
  4629. end >>>= 0;
  4630. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  4631. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  4632. }
  4633. if (begin === end)
  4634. return new ByteBuffer(0, this.littleEndian, this.noAssert);
  4635. var capacity = end - begin,
  4636. bb = new ByteBuffer(capacity, this.littleEndian, this.noAssert);
  4637. bb.offset = 0;
  4638. bb.limit = capacity;
  4639. if (bb.markedOffset >= 0) bb.markedOffset -= begin;
  4640. this.copyTo(bb, 0, begin, end);
  4641. return bb;
  4642. };
  4643. /**
  4644. * Copies this ByteBuffer's contents to another ByteBuffer. Contents are the bytes between {@link ByteBuffer#offset} and
  4645. * {@link ByteBuffer#limit}.
  4646. * @param {!ByteBuffer} target Target ByteBuffer
  4647. * @param {number=} targetOffset Offset to copy to. Will use and increase the target's {@link ByteBuffer#offset}
  4648. * by the number of bytes copied if omitted.
  4649. * @param {number=} sourceOffset Offset to start copying from. Will use and increase {@link ByteBuffer#offset} by the
  4650. * number of bytes copied if omitted.
  4651. * @param {number=} sourceLimit Offset to end copying from, defaults to {@link ByteBuffer#limit}
  4652. * @returns {!ByteBuffer} this
  4653. * @expose
  4654. */
  4655. ByteBufferPrototype.copyTo = function(target, targetOffset, sourceOffset, sourceLimit) {
  4656. var relative,
  4657. targetRelative;
  4658. if (!this.noAssert) {
  4659. if (!ByteBuffer.isByteBuffer(target))
  4660. throw TypeError("Illegal target: Not a ByteBuffer");
  4661. }
  4662. targetOffset = (targetRelative = typeof targetOffset === 'undefined') ? target.offset : targetOffset | 0;
  4663. sourceOffset = (relative = typeof sourceOffset === 'undefined') ? this.offset : sourceOffset | 0;
  4664. sourceLimit = typeof sourceLimit === 'undefined' ? this.limit : sourceLimit | 0;
  4665. if (targetOffset < 0 || targetOffset > target.buffer.byteLength)
  4666. throw RangeError("Illegal target range: 0 <= "+targetOffset+" <= "+target.buffer.byteLength);
  4667. if (sourceOffset < 0 || sourceLimit > this.buffer.byteLength)
  4668. throw RangeError("Illegal source range: 0 <= "+sourceOffset+" <= "+this.buffer.byteLength);
  4669. var len = sourceLimit - sourceOffset;
  4670. if (len === 0)
  4671. return target; // Nothing to copy
  4672. target.ensureCapacity(targetOffset + len);
  4673. target.view.set(this.view.subarray(sourceOffset, sourceLimit), targetOffset);
  4674. if (relative) this.offset += len;
  4675. if (targetRelative) target.offset += len;
  4676. return this;
  4677. };
  4678. /**
  4679. * Makes sure that this ByteBuffer is backed by a {@link ByteBuffer#buffer} of at least the specified capacity. If the
  4680. * current capacity is exceeded, it will be doubled. If double the current capacity is less than the required capacity,
  4681. * the required capacity will be used instead.
  4682. * @param {number} capacity Required capacity
  4683. * @returns {!ByteBuffer} this
  4684. * @expose
  4685. */
  4686. ByteBufferPrototype.ensureCapacity = function(capacity) {
  4687. var current = this.buffer.byteLength;
  4688. if (current < capacity)
  4689. return this.resize((current *= 2) > capacity ? current : capacity);
  4690. return this;
  4691. };
  4692. /**
  4693. * Overwrites this ByteBuffer's contents with the specified value. Contents are the bytes between
  4694. * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
  4695. * @param {number|string} value Byte value to fill with. If given as a string, the first character is used.
  4696. * @param {number=} begin Begin offset. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4697. * written if omitted. defaults to {@link ByteBuffer#offset}.
  4698. * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
  4699. * @returns {!ByteBuffer} this
  4700. * @expose
  4701. * @example `someByteBuffer.clear().fill(0)` fills the entire backing buffer with zeroes
  4702. */
  4703. ByteBufferPrototype.fill = function(value, begin, end) {
  4704. var relative = typeof begin === 'undefined';
  4705. if (relative) begin = this.offset;
  4706. if (typeof value === 'string' && value.length > 0)
  4707. value = value.charCodeAt(0);
  4708. if (typeof begin === 'undefined') begin = this.offset;
  4709. if (typeof end === 'undefined') end = this.limit;
  4710. if (!this.noAssert) {
  4711. if (typeof value !== 'number' || value % 1 !== 0)
  4712. throw TypeError("Illegal value: "+value+" (not an integer)");
  4713. value |= 0;
  4714. if (typeof begin !== 'number' || begin % 1 !== 0)
  4715. throw TypeError("Illegal begin: Not an integer");
  4716. begin >>>= 0;
  4717. if (typeof end !== 'number' || end % 1 !== 0)
  4718. throw TypeError("Illegal end: Not an integer");
  4719. end >>>= 0;
  4720. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  4721. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  4722. }
  4723. if (begin >= end)
  4724. return this; // Nothing to fill
  4725. while (begin < end) this.view[begin++] = value;
  4726. if (relative) this.offset = begin;
  4727. return this;
  4728. };
  4729. /**
  4730. * Makes this ByteBuffer ready for a new sequence of write or relative read operations. Sets `limit = offset` and
  4731. * `offset = 0`. Make sure always to flip a ByteBuffer when all relative read or write operations are complete.
  4732. * @returns {!ByteBuffer} this
  4733. * @expose
  4734. */
  4735. ByteBufferPrototype.flip = function() {
  4736. this.limit = this.offset;
  4737. this.offset = 0;
  4738. return this;
  4739. };
  4740. /**
  4741. * Marks an offset on this ByteBuffer to be used later.
  4742. * @param {number=} offset Offset to mark. Defaults to {@link ByteBuffer#offset}.
  4743. * @returns {!ByteBuffer} this
  4744. * @throws {TypeError} If `offset` is not a valid number
  4745. * @throws {RangeError} If `offset` is out of bounds
  4746. * @see ByteBuffer#reset
  4747. * @expose
  4748. */
  4749. ByteBufferPrototype.mark = function(offset) {
  4750. offset = typeof offset === 'undefined' ? this.offset : offset;
  4751. if (!this.noAssert) {
  4752. if (typeof offset !== 'number' || offset % 1 !== 0)
  4753. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4754. offset >>>= 0;
  4755. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  4756. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  4757. }
  4758. this.markedOffset = offset;
  4759. return this;
  4760. };
  4761. /**
  4762. * Sets the byte order.
  4763. * @param {boolean} littleEndian `true` for little endian byte order, `false` for big endian
  4764. * @returns {!ByteBuffer} this
  4765. * @expose
  4766. */
  4767. ByteBufferPrototype.order = function(littleEndian) {
  4768. if (!this.noAssert) {
  4769. if (typeof littleEndian !== 'boolean')
  4770. throw TypeError("Illegal littleEndian: Not a boolean");
  4771. }
  4772. this.littleEndian = !!littleEndian;
  4773. return this;
  4774. };
  4775. /**
  4776. * Switches (to) little endian byte order.
  4777. * @param {boolean=} littleEndian Defaults to `true`, otherwise uses big endian
  4778. * @returns {!ByteBuffer} this
  4779. * @expose
  4780. */
  4781. ByteBufferPrototype.LE = function(littleEndian) {
  4782. this.littleEndian = typeof littleEndian !== 'undefined' ? !!littleEndian : true;
  4783. return this;
  4784. };
  4785. /**
  4786. * Switches (to) big endian byte order.
  4787. * @param {boolean=} bigEndian Defaults to `true`, otherwise uses little endian
  4788. * @returns {!ByteBuffer} this
  4789. * @expose
  4790. */
  4791. ByteBufferPrototype.BE = function(bigEndian) {
  4792. this.littleEndian = typeof bigEndian !== 'undefined' ? !bigEndian : false;
  4793. return this;
  4794. };
  4795. /**
  4796. * Prepends some data to this ByteBuffer. This will overwrite any contents before the specified offset up to the
  4797. * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
  4798. * will be resized and its contents moved accordingly.
  4799. * @param {!ByteBuffer|string|!ArrayBuffer} source Data to prepend. If `source` is a ByteBuffer, its offset will be
  4800. * modified according to the performed read operation.
  4801. * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
  4802. * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
  4803. * prepended if omitted.
  4804. * @returns {!ByteBuffer} this
  4805. * @expose
  4806. * @example A relative `00<01 02 03>.prepend(<04 05>)` results in `<04 05 01 02 03>, 04 05|`
  4807. * @example An absolute `00<01 02 03>.prepend(<04 05>, 2)` results in `04<05 02 03>, 04 05|`
  4808. */
  4809. ByteBufferPrototype.prepend = function(source, encoding, offset) {
  4810. if (typeof encoding === 'number' || typeof encoding !== 'string') {
  4811. offset = encoding;
  4812. encoding = undefined;
  4813. }
  4814. var relative = typeof offset === 'undefined';
  4815. if (relative) offset = this.offset;
  4816. if (!this.noAssert) {
  4817. if (typeof offset !== 'number' || offset % 1 !== 0)
  4818. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4819. offset >>>= 0;
  4820. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  4821. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  4822. }
  4823. if (!(source instanceof ByteBuffer))
  4824. source = ByteBuffer.wrap(source, encoding);
  4825. var len = source.limit - source.offset;
  4826. if (len <= 0) return this; // Nothing to prepend
  4827. var diff = len - offset;
  4828. if (diff > 0) { // Not enough space before offset, so resize + move
  4829. var buffer = new ArrayBuffer(this.buffer.byteLength + diff);
  4830. var view = new Uint8Array(buffer);
  4831. view.set(this.view.subarray(offset, this.buffer.byteLength), len);
  4832. this.buffer = buffer;
  4833. this.view = view;
  4834. this.offset += diff;
  4835. if (this.markedOffset >= 0) this.markedOffset += diff;
  4836. this.limit += diff;
  4837. offset += diff;
  4838. } else {
  4839. var arrayView = new Uint8Array(this.buffer);
  4840. }
  4841. this.view.set(source.view.subarray(source.offset, source.limit), offset - len);
  4842. source.offset = source.limit;
  4843. if (relative)
  4844. this.offset -= len;
  4845. return this;
  4846. };
  4847. /**
  4848. * Prepends this ByteBuffer to another ByteBuffer. This will overwrite any contents before the specified offset up to the
  4849. * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
  4850. * will be resized and its contents moved accordingly.
  4851. * @param {!ByteBuffer} target Target ByteBuffer
  4852. * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
  4853. * prepended if omitted.
  4854. * @returns {!ByteBuffer} this
  4855. * @expose
  4856. * @see ByteBuffer#prepend
  4857. */
  4858. ByteBufferPrototype.prependTo = function(target, offset) {
  4859. target.prepend(this, offset);
  4860. return this;
  4861. };
  4862. /**
  4863. * Prints debug information about this ByteBuffer's contents.
  4864. * @param {function(string)=} out Output function to call, defaults to console.log
  4865. * @expose
  4866. */
  4867. ByteBufferPrototype.printDebug = function(out) {
  4868. if (typeof out !== 'function') out = console.log.bind(console);
  4869. out(
  4870. this.toString()+"\n"+
  4871. "-------------------------------------------------------------------\n"+
  4872. this.toDebug(/* columns */ true)
  4873. );
  4874. };
  4875. /**
  4876. * Gets the number of remaining readable bytes. Contents are the bytes between {@link ByteBuffer#offset} and
  4877. * {@link ByteBuffer#limit}, so this returns `limit - offset`.
  4878. * @returns {number} Remaining readable bytes. May be negative if `offset > limit`.
  4879. * @expose
  4880. */
  4881. ByteBufferPrototype.remaining = function() {
  4882. return this.limit - this.offset;
  4883. };
  4884. /**
  4885. * Resets this ByteBuffer's {@link ByteBuffer#offset}. If an offset has been marked through {@link ByteBuffer#mark}
  4886. * before, `offset` will be set to {@link ByteBuffer#markedOffset}, which will then be discarded. If no offset has been
  4887. * marked, sets `offset = 0`.
  4888. * @returns {!ByteBuffer} this
  4889. * @see ByteBuffer#mark
  4890. * @expose
  4891. */
  4892. ByteBufferPrototype.reset = function() {
  4893. if (this.markedOffset >= 0) {
  4894. this.offset = this.markedOffset;
  4895. this.markedOffset = -1;
  4896. } else {
  4897. this.offset = 0;
  4898. }
  4899. return this;
  4900. };
  4901. /**
  4902. * Resizes this ByteBuffer to be backed by a buffer of at least the given capacity. Will do nothing if already that
  4903. * large or larger.
  4904. * @param {number} capacity Capacity required
  4905. * @returns {!ByteBuffer} this
  4906. * @throws {TypeError} If `capacity` is not a number
  4907. * @throws {RangeError} If `capacity < 0`
  4908. * @expose
  4909. */
  4910. ByteBufferPrototype.resize = function(capacity) {
  4911. if (!this.noAssert) {
  4912. if (typeof capacity !== 'number' || capacity % 1 !== 0)
  4913. throw TypeError("Illegal capacity: "+capacity+" (not an integer)");
  4914. capacity |= 0;
  4915. if (capacity < 0)
  4916. throw RangeError("Illegal capacity: 0 <= "+capacity);
  4917. }
  4918. if (this.buffer.byteLength < capacity) {
  4919. var buffer = new ArrayBuffer(capacity);
  4920. var view = new Uint8Array(buffer);
  4921. view.set(this.view);
  4922. this.buffer = buffer;
  4923. this.view = view;
  4924. }
  4925. return this;
  4926. };
  4927. /**
  4928. * Reverses this ByteBuffer's contents.
  4929. * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
  4930. * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
  4931. * @returns {!ByteBuffer} this
  4932. * @expose
  4933. */
  4934. ByteBufferPrototype.reverse = function(begin, end) {
  4935. if (typeof begin === 'undefined') begin = this.offset;
  4936. if (typeof end === 'undefined') end = this.limit;
  4937. if (!this.noAssert) {
  4938. if (typeof begin !== 'number' || begin % 1 !== 0)
  4939. throw TypeError("Illegal begin: Not an integer");
  4940. begin >>>= 0;
  4941. if (typeof end !== 'number' || end % 1 !== 0)
  4942. throw TypeError("Illegal end: Not an integer");
  4943. end >>>= 0;
  4944. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  4945. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  4946. }
  4947. if (begin === end)
  4948. return this; // Nothing to reverse
  4949. Array.prototype.reverse.call(this.view.subarray(begin, end));
  4950. return this;
  4951. };
  4952. /**
  4953. * Skips the next `length` bytes. This will just advance
  4954. * @param {number} length Number of bytes to skip. May also be negative to move the offset back.
  4955. * @returns {!ByteBuffer} this
  4956. * @expose
  4957. */
  4958. ByteBufferPrototype.skip = function(length) {
  4959. if (!this.noAssert) {
  4960. if (typeof length !== 'number' || length % 1 !== 0)
  4961. throw TypeError("Illegal length: "+length+" (not an integer)");
  4962. length |= 0;
  4963. }
  4964. var offset = this.offset + length;
  4965. if (!this.noAssert) {
  4966. if (offset < 0 || offset > this.buffer.byteLength)
  4967. throw RangeError("Illegal length: 0 <= "+this.offset+" + "+length+" <= "+this.buffer.byteLength);
  4968. }
  4969. this.offset = offset;
  4970. return this;
  4971. };
  4972. /**
  4973. * Slices this ByteBuffer by creating a cloned instance with `offset = begin` and `limit = end`.
  4974. * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
  4975. * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
  4976. * @returns {!ByteBuffer} Clone of this ByteBuffer with slicing applied, backed by the same {@link ByteBuffer#buffer}
  4977. * @expose
  4978. */
  4979. ByteBufferPrototype.slice = function(begin, end) {
  4980. if (typeof begin === 'undefined') begin = this.offset;
  4981. if (typeof end === 'undefined') end = this.limit;
  4982. if (!this.noAssert) {
  4983. if (typeof begin !== 'number' || begin % 1 !== 0)
  4984. throw TypeError("Illegal begin: Not an integer");
  4985. begin >>>= 0;
  4986. if (typeof end !== 'number' || end % 1 !== 0)
  4987. throw TypeError("Illegal end: Not an integer");
  4988. end >>>= 0;
  4989. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  4990. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  4991. }
  4992. var bb = this.clone();
  4993. bb.offset = begin;
  4994. bb.limit = end;
  4995. return bb;
  4996. };
  4997. /**
  4998. * Returns a copy of the backing buffer that contains this ByteBuffer's contents. Contents are the bytes between
  4999. * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
  5000. * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory if
  5001. * possible. Defaults to `false`
  5002. * @returns {!ArrayBuffer} Contents as an ArrayBuffer
  5003. * @expose
  5004. */
  5005. ByteBufferPrototype.toBuffer = function(forceCopy) {
  5006. var offset = this.offset,
  5007. limit = this.limit;
  5008. if (!this.noAssert) {
  5009. if (typeof offset !== 'number' || offset % 1 !== 0)
  5010. throw TypeError("Illegal offset: Not an integer");
  5011. offset >>>= 0;
  5012. if (typeof limit !== 'number' || limit % 1 !== 0)
  5013. throw TypeError("Illegal limit: Not an integer");
  5014. limit >>>= 0;
  5015. if (offset < 0 || offset > limit || limit > this.buffer.byteLength)
  5016. throw RangeError("Illegal range: 0 <= "+offset+" <= "+limit+" <= "+this.buffer.byteLength);
  5017. }
  5018. // NOTE: It's not possible to have another ArrayBuffer reference the same memory as the backing buffer. This is
  5019. // possible with Uint8Array#subarray only, but we have to return an ArrayBuffer by contract. So:
  5020. if (!forceCopy && offset === 0 && limit === this.buffer.byteLength)
  5021. return this.buffer;
  5022. if (offset === limit)
  5023. return EMPTY_BUFFER;
  5024. var buffer = new ArrayBuffer(limit - offset);
  5025. new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(offset, limit), 0);
  5026. return buffer;
  5027. };
  5028. /**
  5029. * Returns a raw buffer compacted to contain this ByteBuffer's contents. Contents are the bytes between
  5030. * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. This is an alias of {@link ByteBuffer#toBuffer}.
  5031. * @function
  5032. * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory.
  5033. * Defaults to `false`
  5034. * @returns {!ArrayBuffer} Contents as an ArrayBuffer
  5035. * @expose
  5036. */
  5037. ByteBufferPrototype.toArrayBuffer = ByteBufferPrototype.toBuffer;
  5038. /**
  5039. * Converts the ByteBuffer's contents to a string.
  5040. * @param {string=} encoding Output encoding. Returns an informative string representation if omitted but also allows
  5041. * direct conversion to "utf8", "hex", "base64" and "binary" encoding. "debug" returns a hex representation with
  5042. * highlighted offsets.
  5043. * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}
  5044. * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
  5045. * @returns {string} String representation
  5046. * @throws {Error} If `encoding` is invalid
  5047. * @expose
  5048. */
  5049. ByteBufferPrototype.toString = function(encoding, begin, end) {
  5050. if (typeof encoding === 'undefined')
  5051. return "ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")";
  5052. if (typeof encoding === 'number')
  5053. encoding = "utf8",
  5054. begin = encoding,
  5055. end = begin;
  5056. switch (encoding) {
  5057. case "utf8":
  5058. return this.toUTF8(begin, end);
  5059. case "base64":
  5060. return this.toBase64(begin, end);
  5061. case "hex":
  5062. return this.toHex(begin, end);
  5063. case "binary":
  5064. return this.toBinary(begin, end);
  5065. case "debug":
  5066. return this.toDebug();
  5067. case "columns":
  5068. return this.toColumns();
  5069. default:
  5070. throw Error("Unsupported encoding: "+encoding);
  5071. }
  5072. };
  5073. // lxiv-embeddable
  5074. /**
  5075. * lxiv-embeddable (c) 2014 Daniel Wirtz <dcode@dcode.io>
  5076. * Released under the Apache License, Version 2.0
  5077. * see: https://github.com/dcodeIO/lxiv for details
  5078. */
  5079. var lxiv = function() {
  5080. /**
  5081. * lxiv namespace.
  5082. * @type {!Object.<string,*>}
  5083. * @exports lxiv
  5084. */
  5085. var lxiv = {};
  5086. /**
  5087. * Character codes for output.
  5088. * @type {!Array.<number>}
  5089. * @inner
  5090. */
  5091. var aout = [
  5092. 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
  5093. 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102,
  5094. 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
  5095. 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47
  5096. ];
  5097. /**
  5098. * Character codes for input.
  5099. * @type {!Array.<number>}
  5100. * @inner
  5101. */
  5102. var ain = [];
  5103. for (var i=0, k=aout.length; i<k; ++i)
  5104. ain[aout[i]] = i;
  5105. /**
  5106. * Encodes bytes to base64 char codes.
  5107. * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if
  5108. * there are no more bytes left.
  5109. * @param {!function(number)} dst Characters destination as a function successively called with each encoded char
  5110. * code.
  5111. */
  5112. lxiv.encode = function(src, dst) {
  5113. var b, t;
  5114. while ((b = src()) !== null) {
  5115. dst(aout[(b>>2)&0x3f]);
  5116. t = (b&0x3)<<4;
  5117. if ((b = src()) !== null) {
  5118. t |= (b>>4)&0xf;
  5119. dst(aout[(t|((b>>4)&0xf))&0x3f]);
  5120. t = (b&0xf)<<2;
  5121. if ((b = src()) !== null)
  5122. dst(aout[(t|((b>>6)&0x3))&0x3f]),
  5123. dst(aout[b&0x3f]);
  5124. else
  5125. dst(aout[t&0x3f]),
  5126. dst(61);
  5127. } else
  5128. dst(aout[t&0x3f]),
  5129. dst(61),
  5130. dst(61);
  5131. }
  5132. };
  5133. /**
  5134. * Decodes base64 char codes to bytes.
  5135. * @param {!function():number|null} src Characters source as a function returning the next char code respectively
  5136. * `null` if there are no more characters left.
  5137. * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
  5138. * @throws {Error} If a character code is invalid
  5139. */
  5140. lxiv.decode = function(src, dst) {
  5141. var c, t1, t2;
  5142. function fail(c) {
  5143. throw Error("Illegal character code: "+c);
  5144. }
  5145. while ((c = src()) !== null) {
  5146. t1 = ain[c];
  5147. if (typeof t1 === 'undefined') fail(c);
  5148. if ((c = src()) !== null) {
  5149. t2 = ain[c];
  5150. if (typeof t2 === 'undefined') fail(c);
  5151. dst((t1<<2)>>>0|(t2&0x30)>>4);
  5152. if ((c = src()) !== null) {
  5153. t1 = ain[c];
  5154. if (typeof t1 === 'undefined')
  5155. if (c === 61) break; else fail(c);
  5156. dst(((t2&0xf)<<4)>>>0|(t1&0x3c)>>2);
  5157. if ((c = src()) !== null) {
  5158. t2 = ain[c];
  5159. if (typeof t2 === 'undefined')
  5160. if (c === 61) break; else fail(c);
  5161. dst(((t1&0x3)<<6)>>>0|t2);
  5162. }
  5163. }
  5164. }
  5165. }
  5166. };
  5167. /**
  5168. * Tests if a string is valid base64.
  5169. * @param {string} str String to test
  5170. * @returns {boolean} `true` if valid, otherwise `false`
  5171. */
  5172. lxiv.test = function(str) {
  5173. return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(str);
  5174. };
  5175. return lxiv;
  5176. }();
  5177. // encodings/base64
  5178. /**
  5179. * Encodes this ByteBuffer's contents to a base64 encoded string.
  5180. * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}.
  5181. * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}.
  5182. * @returns {string} Base64 encoded string
  5183. * @throws {RangeError} If `begin` or `end` is out of bounds
  5184. * @expose
  5185. */
  5186. ByteBufferPrototype.toBase64 = function(begin, end) {
  5187. if (typeof begin === 'undefined')
  5188. begin = this.offset;
  5189. if (typeof end === 'undefined')
  5190. end = this.limit;
  5191. begin = begin | 0; end = end | 0;
  5192. if (begin < 0 || end > this.capacity || begin > end)
  5193. throw RangeError("begin, end");
  5194. var sd; lxiv.encode(function() {
  5195. return begin < end ? this.view[begin++] : null;
  5196. }.bind(this), sd = stringDestination());
  5197. return sd();
  5198. };
  5199. /**
  5200. * Decodes a base64 encoded string to a ByteBuffer.
  5201. * @param {string} str String to decode
  5202. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  5203. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  5204. * @returns {!ByteBuffer} ByteBuffer
  5205. * @expose
  5206. */
  5207. ByteBuffer.fromBase64 = function(str, littleEndian) {
  5208. if (typeof str !== 'string')
  5209. throw TypeError("str");
  5210. var bb = new ByteBuffer(str.length/4*3, littleEndian),
  5211. i = 0;
  5212. lxiv.decode(stringSource(str), function(b) {
  5213. bb.view[i++] = b;
  5214. });
  5215. bb.limit = i;
  5216. return bb;
  5217. };
  5218. /**
  5219. * Encodes a binary string to base64 like `window.btoa` does.
  5220. * @param {string} str Binary string
  5221. * @returns {string} Base64 encoded string
  5222. * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.btoa
  5223. * @expose
  5224. */
  5225. ByteBuffer.btoa = function(str) {
  5226. return ByteBuffer.fromBinary(str).toBase64();
  5227. };
  5228. /**
  5229. * Decodes a base64 encoded string to binary like `window.atob` does.
  5230. * @param {string} b64 Base64 encoded string
  5231. * @returns {string} Binary string
  5232. * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.atob
  5233. * @expose
  5234. */
  5235. ByteBuffer.atob = function(b64) {
  5236. return ByteBuffer.fromBase64(b64).toBinary();
  5237. };
  5238. // encodings/binary
  5239. /**
  5240. * Encodes this ByteBuffer to a binary encoded string, that is using only characters 0x00-0xFF as bytes.
  5241. * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}.
  5242. * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}.
  5243. * @returns {string} Binary encoded string
  5244. * @throws {RangeError} If `offset > limit`
  5245. * @expose
  5246. */
  5247. ByteBufferPrototype.toBinary = function(begin, end) {
  5248. if (typeof begin === 'undefined')
  5249. begin = this.offset;
  5250. if (typeof end === 'undefined')
  5251. end = this.limit;
  5252. begin |= 0; end |= 0;
  5253. if (begin < 0 || end > this.capacity() || begin > end)
  5254. throw RangeError("begin, end");
  5255. if (begin === end)
  5256. return "";
  5257. var chars = [],
  5258. parts = [];
  5259. while (begin < end) {
  5260. chars.push(this.view[begin++]);
  5261. if (chars.length >= 1024)
  5262. parts.push(String.fromCharCode.apply(String, chars)),
  5263. chars = [];
  5264. }
  5265. return parts.join('') + String.fromCharCode.apply(String, chars);
  5266. };
  5267. /**
  5268. * Decodes a binary encoded string, that is using only characters 0x00-0xFF as bytes, to a ByteBuffer.
  5269. * @param {string} str String to decode
  5270. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  5271. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  5272. * @returns {!ByteBuffer} ByteBuffer
  5273. * @expose
  5274. */
  5275. ByteBuffer.fromBinary = function(str, littleEndian) {
  5276. if (typeof str !== 'string')
  5277. throw TypeError("str");
  5278. var i = 0,
  5279. k = str.length,
  5280. charCode,
  5281. bb = new ByteBuffer(k, littleEndian);
  5282. while (i<k) {
  5283. charCode = str.charCodeAt(i);
  5284. if (charCode > 0xff)
  5285. throw RangeError("illegal char code: "+charCode);
  5286. bb.view[i++] = charCode;
  5287. }
  5288. bb.limit = k;
  5289. return bb;
  5290. };
  5291. // encodings/debug
  5292. /**
  5293. * Encodes this ByteBuffer to a hex encoded string with marked offsets. Offset symbols are:
  5294. * * `<` : offset,
  5295. * * `'` : markedOffset,
  5296. * * `>` : limit,
  5297. * * `|` : offset and limit,
  5298. * * `[` : offset and markedOffset,
  5299. * * `]` : markedOffset and limit,
  5300. * * `!` : offset, markedOffset and limit
  5301. * @param {boolean=} columns If `true` returns two columns hex + ascii, defaults to `false`
  5302. * @returns {string|!Array.<string>} Debug string or array of lines if `asArray = true`
  5303. * @expose
  5304. * @example `>00'01 02<03` contains four bytes with `limit=0, markedOffset=1, offset=3`
  5305. * @example `00[01 02 03>` contains four bytes with `offset=markedOffset=1, limit=4`
  5306. * @example `00|01 02 03` contains four bytes with `offset=limit=1, markedOffset=-1`
  5307. * @example `|` contains zero bytes with `offset=limit=0, markedOffset=-1`
  5308. */
  5309. ByteBufferPrototype.toDebug = function(columns) {
  5310. var i = -1,
  5311. k = this.buffer.byteLength,
  5312. b,
  5313. hex = "",
  5314. asc = "",
  5315. out = "";
  5316. while (i<k) {
  5317. if (i !== -1) {
  5318. b = this.view[i];
  5319. if (b < 0x10) hex += "0"+b.toString(16).toUpperCase();
  5320. else hex += b.toString(16).toUpperCase();
  5321. if (columns)
  5322. asc += b > 32 && b < 127 ? String.fromCharCode(b) : '.';
  5323. }
  5324. ++i;
  5325. if (columns) {
  5326. if (i > 0 && i % 16 === 0 && i !== k) {
  5327. while (hex.length < 3*16+3) hex += " ";
  5328. out += hex+asc+"\n";
  5329. hex = asc = "";
  5330. }
  5331. }
  5332. if (i === this.offset && i === this.limit)
  5333. hex += i === this.markedOffset ? "!" : "|";
  5334. else if (i === this.offset)
  5335. hex += i === this.markedOffset ? "[" : "<";
  5336. else if (i === this.limit)
  5337. hex += i === this.markedOffset ? "]" : ">";
  5338. else
  5339. hex += i === this.markedOffset ? "'" : (columns || (i !== 0 && i !== k) ? " " : "");
  5340. }
  5341. if (columns && hex !== " ") {
  5342. while (hex.length < 3*16+3)
  5343. hex += " ";
  5344. out += hex + asc + "\n";
  5345. }
  5346. return columns ? out : hex;
  5347. };
  5348. /**
  5349. * Decodes a hex encoded string with marked offsets to a ByteBuffer.
  5350. * @param {string} str Debug string to decode (not be generated with `columns = true`)
  5351. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  5352. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  5353. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  5354. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  5355. * @returns {!ByteBuffer} ByteBuffer
  5356. * @expose
  5357. * @see ByteBuffer#toDebug
  5358. */
  5359. ByteBuffer.fromDebug = function(str, littleEndian, noAssert) {
  5360. var k = str.length,
  5361. bb = new ByteBuffer(((k+1)/3)|0, littleEndian, noAssert);
  5362. var i = 0, j = 0, ch, b,
  5363. rs = false, // Require symbol next
  5364. ho = false, hm = false, hl = false, // Already has offset (ho), markedOffset (hm), limit (hl)?
  5365. fail = false;
  5366. while (i<k) {
  5367. switch (ch = str.charAt(i++)) {
  5368. case '!':
  5369. if (!noAssert) {
  5370. if (ho || hm || hl) {
  5371. fail = true;
  5372. break;
  5373. }
  5374. ho = hm = hl = true;
  5375. }
  5376. bb.offset = bb.markedOffset = bb.limit = j;
  5377. rs = false;
  5378. break;
  5379. case '|':
  5380. if (!noAssert) {
  5381. if (ho || hl) {
  5382. fail = true;
  5383. break;
  5384. }
  5385. ho = hl = true;
  5386. }
  5387. bb.offset = bb.limit = j;
  5388. rs = false;
  5389. break;
  5390. case '[':
  5391. if (!noAssert) {
  5392. if (ho || hm) {
  5393. fail = true;
  5394. break;
  5395. }
  5396. ho = hm = true;
  5397. }
  5398. bb.offset = bb.markedOffset = j;
  5399. rs = false;
  5400. break;
  5401. case '<':
  5402. if (!noAssert) {
  5403. if (ho) {
  5404. fail = true;
  5405. break;
  5406. }
  5407. ho = true;
  5408. }
  5409. bb.offset = j;
  5410. rs = false;
  5411. break;
  5412. case ']':
  5413. if (!noAssert) {
  5414. if (hl || hm) {
  5415. fail = true;
  5416. break;
  5417. }
  5418. hl = hm = true;
  5419. }
  5420. bb.limit = bb.markedOffset = j;
  5421. rs = false;
  5422. break;
  5423. case '>':
  5424. if (!noAssert) {
  5425. if (hl) {
  5426. fail = true;
  5427. break;
  5428. }
  5429. hl = true;
  5430. }
  5431. bb.limit = j;
  5432. rs = false;
  5433. break;
  5434. case "'":
  5435. if (!noAssert) {
  5436. if (hm) {
  5437. fail = true;
  5438. break;
  5439. }
  5440. hm = true;
  5441. }
  5442. bb.markedOffset = j;
  5443. rs = false;
  5444. break;
  5445. case ' ':
  5446. rs = false;
  5447. break;
  5448. default:
  5449. if (!noAssert) {
  5450. if (rs) {
  5451. fail = true;
  5452. break;
  5453. }
  5454. }
  5455. b = parseInt(ch+str.charAt(i++), 16);
  5456. if (!noAssert) {
  5457. if (isNaN(b) || b < 0 || b > 255)
  5458. throw TypeError("Illegal str: Not a debug encoded string");
  5459. }
  5460. bb.view[j++] = b;
  5461. rs = true;
  5462. }
  5463. if (fail)
  5464. throw TypeError("Illegal str: Invalid symbol at "+i);
  5465. }
  5466. if (!noAssert) {
  5467. if (!ho || !hl)
  5468. throw TypeError("Illegal str: Missing offset or limit");
  5469. if (j<bb.buffer.byteLength)
  5470. throw TypeError("Illegal str: Not a debug encoded string (is it hex?) "+j+" < "+k);
  5471. }
  5472. return bb;
  5473. };
  5474. // encodings/hex
  5475. /**
  5476. * Encodes this ByteBuffer's contents to a hex encoded string.
  5477. * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}.
  5478. * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}.
  5479. * @returns {string} Hex encoded string
  5480. * @expose
  5481. */
  5482. ByteBufferPrototype.toHex = function(begin, end) {
  5483. begin = typeof begin === 'undefined' ? this.offset : begin;
  5484. end = typeof end === 'undefined' ? this.limit : end;
  5485. if (!this.noAssert) {
  5486. if (typeof begin !== 'number' || begin % 1 !== 0)
  5487. throw TypeError("Illegal begin: Not an integer");
  5488. begin >>>= 0;
  5489. if (typeof end !== 'number' || end % 1 !== 0)
  5490. throw TypeError("Illegal end: Not an integer");
  5491. end >>>= 0;
  5492. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  5493. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  5494. }
  5495. var out = new Array(end - begin),
  5496. b;
  5497. while (begin < end) {
  5498. b = this.view[begin++];
  5499. if (b < 0x10)
  5500. out.push("0", b.toString(16));
  5501. else out.push(b.toString(16));
  5502. }
  5503. return out.join('');
  5504. };
  5505. /**
  5506. * Decodes a hex encoded string to a ByteBuffer.
  5507. * @param {string} str String to decode
  5508. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  5509. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  5510. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  5511. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  5512. * @returns {!ByteBuffer} ByteBuffer
  5513. * @expose
  5514. */
  5515. ByteBuffer.fromHex = function(str, littleEndian, noAssert) {
  5516. if (!noAssert) {
  5517. if (typeof str !== 'string')
  5518. throw TypeError("Illegal str: Not a string");
  5519. if (str.length % 2 !== 0)
  5520. throw TypeError("Illegal str: Length not a multiple of 2");
  5521. }
  5522. var k = str.length,
  5523. bb = new ByteBuffer((k / 2) | 0, littleEndian),
  5524. b;
  5525. for (var i=0, j=0; i<k; i+=2) {
  5526. b = parseInt(str.substring(i, i+2), 16);
  5527. if (!noAssert)
  5528. if (!isFinite(b) || b < 0 || b > 255)
  5529. throw TypeError("Illegal str: Contains non-hex characters");
  5530. bb.view[j++] = b;
  5531. }
  5532. bb.limit = j;
  5533. return bb;
  5534. };
  5535. // utfx-embeddable
  5536. /**
  5537. * utfx-embeddable (c) 2014 Daniel Wirtz <dcode@dcode.io>
  5538. * Released under the Apache License, Version 2.0
  5539. * see: https://github.com/dcodeIO/utfx for details
  5540. */
  5541. var utfx = function() {
  5542. /**
  5543. * utfx namespace.
  5544. * @inner
  5545. * @type {!Object.<string,*>}
  5546. */
  5547. var utfx = {};
  5548. /**
  5549. * Maximum valid code point.
  5550. * @type {number}
  5551. * @const
  5552. */
  5553. utfx.MAX_CODEPOINT = 0x10FFFF;
  5554. /**
  5555. * Encodes UTF8 code points to UTF8 bytes.
  5556. * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
  5557. * respectively `null` if there are no more code points left or a single numeric code point.
  5558. * @param {!function(number)} dst Bytes destination as a function successively called with the next byte
  5559. */
  5560. utfx.encodeUTF8 = function(src, dst) {
  5561. var cp = null;
  5562. if (typeof src === 'number')
  5563. cp = src,
  5564. src = function() { return null; };
  5565. while (cp !== null || (cp = src()) !== null) {
  5566. if (cp < 0x80)
  5567. dst(cp&0x7F);
  5568. else if (cp < 0x800)
  5569. dst(((cp>>6)&0x1F)|0xC0),
  5570. dst((cp&0x3F)|0x80);
  5571. else if (cp < 0x10000)
  5572. dst(((cp>>12)&0x0F)|0xE0),
  5573. dst(((cp>>6)&0x3F)|0x80),
  5574. dst((cp&0x3F)|0x80);
  5575. else
  5576. dst(((cp>>18)&0x07)|0xF0),
  5577. dst(((cp>>12)&0x3F)|0x80),
  5578. dst(((cp>>6)&0x3F)|0x80),
  5579. dst((cp&0x3F)|0x80);
  5580. cp = null;
  5581. }
  5582. };
  5583. /**
  5584. * Decodes UTF8 bytes to UTF8 code points.
  5585. * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
  5586. * are no more bytes left.
  5587. * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point.
  5588. * @throws {RangeError} If a starting byte is invalid in UTF8
  5589. * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the
  5590. * remaining bytes.
  5591. */
  5592. utfx.decodeUTF8 = function(src, dst) {
  5593. var a, b, c, d, fail = function(b) {
  5594. b = b.slice(0, b.indexOf(null));
  5595. var err = Error(b.toString());
  5596. err.name = "TruncatedError";
  5597. err['bytes'] = b;
  5598. throw err;
  5599. };
  5600. while ((a = src()) !== null) {
  5601. if ((a&0x80) === 0)
  5602. dst(a);
  5603. else if ((a&0xE0) === 0xC0)
  5604. ((b = src()) === null) && fail([a, b]),
  5605. dst(((a&0x1F)<<6) | (b&0x3F));
  5606. else if ((a&0xF0) === 0xE0)
  5607. ((b=src()) === null || (c=src()) === null) && fail([a, b, c]),
  5608. dst(((a&0x0F)<<12) | ((b&0x3F)<<6) | (c&0x3F));
  5609. else if ((a&0xF8) === 0xF0)
  5610. ((b=src()) === null || (c=src()) === null || (d=src()) === null) && fail([a, b, c ,d]),
  5611. dst(((a&0x07)<<18) | ((b&0x3F)<<12) | ((c&0x3F)<<6) | (d&0x3F));
  5612. else throw RangeError("Illegal starting byte: "+a);
  5613. }
  5614. };
  5615. /**
  5616. * Converts UTF16 characters to UTF8 code points.
  5617. * @param {!function():number|null} src Characters source as a function returning the next char code respectively
  5618. * `null` if there are no more characters left.
  5619. * @param {!function(number)} dst Code points destination as a function successively called with each converted code
  5620. * point.
  5621. */
  5622. utfx.UTF16toUTF8 = function(src, dst) {
  5623. var c1, c2 = null;
  5624. while (true) {
  5625. if ((c1 = c2 !== null ? c2 : src()) === null)
  5626. break;
  5627. if (c1 >= 0xD800 && c1 <= 0xDFFF) {
  5628. if ((c2 = src()) !== null) {
  5629. if (c2 >= 0xDC00 && c2 <= 0xDFFF) {
  5630. dst((c1-0xD800)*0x400+c2-0xDC00+0x10000);
  5631. c2 = null; continue;
  5632. }
  5633. }
  5634. }
  5635. dst(c1);
  5636. }
  5637. if (c2 !== null) dst(c2);
  5638. };
  5639. /**
  5640. * Converts UTF8 code points to UTF16 characters.
  5641. * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
  5642. * respectively `null` if there are no more code points left or a single numeric code point.
  5643. * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
  5644. * @throws {RangeError} If a code point is out of range
  5645. */
  5646. utfx.UTF8toUTF16 = function(src, dst) {
  5647. var cp = null;
  5648. if (typeof src === 'number')
  5649. cp = src, src = function() { return null; };
  5650. while (cp !== null || (cp = src()) !== null) {
  5651. if (cp <= 0xFFFF)
  5652. dst(cp);
  5653. else
  5654. cp -= 0x10000,
  5655. dst((cp>>10)+0xD800),
  5656. dst((cp%0x400)+0xDC00);
  5657. cp = null;
  5658. }
  5659. };
  5660. /**
  5661. * Converts and encodes UTF16 characters to UTF8 bytes.
  5662. * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null`
  5663. * if there are no more characters left.
  5664. * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
  5665. */
  5666. utfx.encodeUTF16toUTF8 = function(src, dst) {
  5667. utfx.UTF16toUTF8(src, function(cp) {
  5668. utfx.encodeUTF8(cp, dst);
  5669. });
  5670. };
  5671. /**
  5672. * Decodes and converts UTF8 bytes to UTF16 characters.
  5673. * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
  5674. * are no more bytes left.
  5675. * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
  5676. * @throws {RangeError} If a starting byte is invalid in UTF8
  5677. * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes.
  5678. */
  5679. utfx.decodeUTF8toUTF16 = function(src, dst) {
  5680. utfx.decodeUTF8(src, function(cp) {
  5681. utfx.UTF8toUTF16(cp, dst);
  5682. });
  5683. };
  5684. /**
  5685. * Calculates the byte length of an UTF8 code point.
  5686. * @param {number} cp UTF8 code point
  5687. * @returns {number} Byte length
  5688. */
  5689. utfx.calculateCodePoint = function(cp) {
  5690. return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
  5691. };
  5692. /**
  5693. * Calculates the number of UTF8 bytes required to store UTF8 code points.
  5694. * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively
  5695. * `null` if there are no more code points left.
  5696. * @returns {number} The number of UTF8 bytes required
  5697. */
  5698. utfx.calculateUTF8 = function(src) {
  5699. var cp, l=0;
  5700. while ((cp = src()) !== null)
  5701. l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
  5702. return l;
  5703. };
  5704. /**
  5705. * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes.
  5706. * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively
  5707. * `null` if there are no more characters left.
  5708. * @returns {!Array.<number>} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1.
  5709. */
  5710. utfx.calculateUTF16asUTF8 = function(src) {
  5711. var n=0, l=0;
  5712. utfx.UTF16toUTF8(src, function(cp) {
  5713. ++n; l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
  5714. });
  5715. return [n,l];
  5716. };
  5717. return utfx;
  5718. }();
  5719. // encodings/utf8
  5720. /**
  5721. * Encodes this ByteBuffer's contents between {@link ByteBuffer#offset} and {@link ByteBuffer#limit} to an UTF8 encoded
  5722. * string.
  5723. * @returns {string} Hex encoded string
  5724. * @throws {RangeError} If `offset > limit`
  5725. * @expose
  5726. */
  5727. ByteBufferPrototype.toUTF8 = function(begin, end) {
  5728. if (typeof begin === 'undefined') begin = this.offset;
  5729. if (typeof end === 'undefined') end = this.limit;
  5730. if (!this.noAssert) {
  5731. if (typeof begin !== 'number' || begin % 1 !== 0)
  5732. throw TypeError("Illegal begin: Not an integer");
  5733. begin >>>= 0;
  5734. if (typeof end !== 'number' || end % 1 !== 0)
  5735. throw TypeError("Illegal end: Not an integer");
  5736. end >>>= 0;
  5737. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  5738. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  5739. }
  5740. var sd; try {
  5741. utfx.decodeUTF8toUTF16(function() {
  5742. return begin < end ? this.view[begin++] : null;
  5743. }.bind(this), sd = stringDestination());
  5744. } catch (e) {
  5745. if (begin !== end)
  5746. throw RangeError("Illegal range: Truncated data, "+begin+" != "+end);
  5747. }
  5748. return sd();
  5749. };
  5750. /**
  5751. * Decodes an UTF8 encoded string to a ByteBuffer.
  5752. * @param {string} str String to decode
  5753. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  5754. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  5755. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  5756. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  5757. * @returns {!ByteBuffer} ByteBuffer
  5758. * @expose
  5759. */
  5760. ByteBuffer.fromUTF8 = function(str, littleEndian, noAssert) {
  5761. if (!noAssert)
  5762. if (typeof str !== 'string')
  5763. throw TypeError("Illegal str: Not a string");
  5764. var bb = new ByteBuffer(utfx.calculateUTF16asUTF8(stringSource(str), true)[1], littleEndian, noAssert),
  5765. i = 0;
  5766. utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
  5767. bb.view[i++] = b;
  5768. });
  5769. bb.limit = i;
  5770. return bb;
  5771. };
  5772. return ByteBuffer;
  5773. });
  5774. });
  5775. var _nodeResolve_empty = {};
  5776. var _nodeResolve_empty$1 = /*#__PURE__*/Object.freeze({
  5777. __proto__: null,
  5778. 'default': _nodeResolve_empty
  5779. });
  5780. var require$$2 = getCjsExportFromNamespace(_nodeResolve_empty$1);
  5781. var protobufLight = createCommonjsModule(function (module) {
  5782. /*
  5783. Copyright 2013 Daniel Wirtz <dcode@dcode.io>
  5784. Licensed under the Apache License, Version 2.0 (the "License");
  5785. you may not use this file except in compliance with the License.
  5786. You may obtain a copy of the License at
  5787. http://www.apache.org/licenses/LICENSE-2.0
  5788. Unless required by applicable law or agreed to in writing, software
  5789. distributed under the License is distributed on an "AS IS" BASIS,
  5790. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  5791. See the License for the specific language governing permissions and
  5792. limitations under the License.
  5793. */
  5794. /**
  5795. * @license protobuf.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
  5796. * Released under the Apache License, Version 2.0
  5797. * see: https://github.com/dcodeIO/protobuf.js for details
  5798. */
  5799. (function(global, factory) {
  5800. /* AMD */ if (typeof commonjsRequire === "function" && 'object' === "object" && module && module["exports"])
  5801. module["exports"] = factory(bytebuffer, true);
  5802. /* Global */ else
  5803. (global["dcodeIO"] = global["dcodeIO"] || {})["ProtoBuf"] = factory(global["dcodeIO"]["ByteBuffer"]);
  5804. })(commonjsGlobal, function(ByteBuffer, isCommonJS) {
  5805. /**
  5806. * The ProtoBuf namespace.
  5807. * @exports ProtoBuf
  5808. * @namespace
  5809. * @expose
  5810. */
  5811. var ProtoBuf = {};
  5812. /**
  5813. * @type {!function(new: ByteBuffer, ...[*])}
  5814. * @expose
  5815. */
  5816. ProtoBuf.ByteBuffer = ByteBuffer;
  5817. /**
  5818. * @type {?function(new: Long, ...[*])}
  5819. * @expose
  5820. */
  5821. ProtoBuf.Long = ByteBuffer.Long || null;
  5822. /**
  5823. * ProtoBuf.js version.
  5824. * @type {string}
  5825. * @const
  5826. * @expose
  5827. */
  5828. ProtoBuf.VERSION = "5.0.3";
  5829. /**
  5830. * Wire types.
  5831. * @type {Object.<string,number>}
  5832. * @const
  5833. * @expose
  5834. */
  5835. ProtoBuf.WIRE_TYPES = {};
  5836. /**
  5837. * Varint wire type.
  5838. * @type {number}
  5839. * @expose
  5840. */
  5841. ProtoBuf.WIRE_TYPES.VARINT = 0;
  5842. /**
  5843. * Fixed 64 bits wire type.
  5844. * @type {number}
  5845. * @const
  5846. * @expose
  5847. */
  5848. ProtoBuf.WIRE_TYPES.BITS64 = 1;
  5849. /**
  5850. * Length delimited wire type.
  5851. * @type {number}
  5852. * @const
  5853. * @expose
  5854. */
  5855. ProtoBuf.WIRE_TYPES.LDELIM = 2;
  5856. /**
  5857. * Start group wire type.
  5858. * @type {number}
  5859. * @const
  5860. * @expose
  5861. */
  5862. ProtoBuf.WIRE_TYPES.STARTGROUP = 3;
  5863. /**
  5864. * End group wire type.
  5865. * @type {number}
  5866. * @const
  5867. * @expose
  5868. */
  5869. ProtoBuf.WIRE_TYPES.ENDGROUP = 4;
  5870. /**
  5871. * Fixed 32 bits wire type.
  5872. * @type {number}
  5873. * @const
  5874. * @expose
  5875. */
  5876. ProtoBuf.WIRE_TYPES.BITS32 = 5;
  5877. /**
  5878. * Packable wire types.
  5879. * @type {!Array.<number>}
  5880. * @const
  5881. * @expose
  5882. */
  5883. ProtoBuf.PACKABLE_WIRE_TYPES = [
  5884. ProtoBuf.WIRE_TYPES.VARINT,
  5885. ProtoBuf.WIRE_TYPES.BITS64,
  5886. ProtoBuf.WIRE_TYPES.BITS32
  5887. ];
  5888. /**
  5889. * Types.
  5890. * @dict
  5891. * @type {!Object.<string,{name: string, wireType: number, defaultValue: *}>}
  5892. * @const
  5893. * @expose
  5894. */
  5895. ProtoBuf.TYPES = {
  5896. // According to the protobuf spec.
  5897. "int32": {
  5898. name: "int32",
  5899. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  5900. defaultValue: 0
  5901. },
  5902. "uint32": {
  5903. name: "uint32",
  5904. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  5905. defaultValue: 0
  5906. },
  5907. "sint32": {
  5908. name: "sint32",
  5909. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  5910. defaultValue: 0
  5911. },
  5912. "int64": {
  5913. name: "int64",
  5914. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  5915. defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined
  5916. },
  5917. "uint64": {
  5918. name: "uint64",
  5919. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  5920. defaultValue: ProtoBuf.Long ? ProtoBuf.Long.UZERO : undefined
  5921. },
  5922. "sint64": {
  5923. name: "sint64",
  5924. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  5925. defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined
  5926. },
  5927. "bool": {
  5928. name: "bool",
  5929. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  5930. defaultValue: false
  5931. },
  5932. "double": {
  5933. name: "double",
  5934. wireType: ProtoBuf.WIRE_TYPES.BITS64,
  5935. defaultValue: 0
  5936. },
  5937. "string": {
  5938. name: "string",
  5939. wireType: ProtoBuf.WIRE_TYPES.LDELIM,
  5940. defaultValue: ""
  5941. },
  5942. "bytes": {
  5943. name: "bytes",
  5944. wireType: ProtoBuf.WIRE_TYPES.LDELIM,
  5945. defaultValue: null // overridden in the code, must be a unique instance
  5946. },
  5947. "fixed32": {
  5948. name: "fixed32",
  5949. wireType: ProtoBuf.WIRE_TYPES.BITS32,
  5950. defaultValue: 0
  5951. },
  5952. "sfixed32": {
  5953. name: "sfixed32",
  5954. wireType: ProtoBuf.WIRE_TYPES.BITS32,
  5955. defaultValue: 0
  5956. },
  5957. "fixed64": {
  5958. name: "fixed64",
  5959. wireType: ProtoBuf.WIRE_TYPES.BITS64,
  5960. defaultValue: ProtoBuf.Long ? ProtoBuf.Long.UZERO : undefined
  5961. },
  5962. "sfixed64": {
  5963. name: "sfixed64",
  5964. wireType: ProtoBuf.WIRE_TYPES.BITS64,
  5965. defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined
  5966. },
  5967. "float": {
  5968. name: "float",
  5969. wireType: ProtoBuf.WIRE_TYPES.BITS32,
  5970. defaultValue: 0
  5971. },
  5972. "enum": {
  5973. name: "enum",
  5974. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  5975. defaultValue: 0
  5976. },
  5977. "message": {
  5978. name: "message",
  5979. wireType: ProtoBuf.WIRE_TYPES.LDELIM,
  5980. defaultValue: null
  5981. },
  5982. "group": {
  5983. name: "group",
  5984. wireType: ProtoBuf.WIRE_TYPES.STARTGROUP,
  5985. defaultValue: null
  5986. }
  5987. };
  5988. /**
  5989. * Valid map key types.
  5990. * @type {!Array.<!Object.<string,{name: string, wireType: number, defaultValue: *}>>}
  5991. * @const
  5992. * @expose
  5993. */
  5994. ProtoBuf.MAP_KEY_TYPES = [
  5995. ProtoBuf.TYPES["int32"],
  5996. ProtoBuf.TYPES["sint32"],
  5997. ProtoBuf.TYPES["sfixed32"],
  5998. ProtoBuf.TYPES["uint32"],
  5999. ProtoBuf.TYPES["fixed32"],
  6000. ProtoBuf.TYPES["int64"],
  6001. ProtoBuf.TYPES["sint64"],
  6002. ProtoBuf.TYPES["sfixed64"],
  6003. ProtoBuf.TYPES["uint64"],
  6004. ProtoBuf.TYPES["fixed64"],
  6005. ProtoBuf.TYPES["bool"],
  6006. ProtoBuf.TYPES["string"],
  6007. ProtoBuf.TYPES["bytes"]
  6008. ];
  6009. /**
  6010. * Minimum field id.
  6011. * @type {number}
  6012. * @const
  6013. * @expose
  6014. */
  6015. ProtoBuf.ID_MIN = 1;
  6016. /**
  6017. * Maximum field id.
  6018. * @type {number}
  6019. * @const
  6020. * @expose
  6021. */
  6022. ProtoBuf.ID_MAX = 0x1FFFFFFF;
  6023. /**
  6024. * If set to `true`, field names will be converted from underscore notation to camel case. Defaults to `false`.
  6025. * Must be set prior to parsing.
  6026. * @type {boolean}
  6027. * @expose
  6028. */
  6029. ProtoBuf.convertFieldsToCamelCase = false;
  6030. /**
  6031. * By default, messages are populated with (setX, set_x) accessors for each field. This can be disabled by
  6032. * setting this to `false` prior to building messages.
  6033. * @type {boolean}
  6034. * @expose
  6035. */
  6036. ProtoBuf.populateAccessors = true;
  6037. /**
  6038. * By default, messages are populated with default values if a field is not present on the wire. To disable
  6039. * this behavior, set this setting to `false`.
  6040. * @type {boolean}
  6041. * @expose
  6042. */
  6043. ProtoBuf.populateDefaults = true;
  6044. /**
  6045. * @alias ProtoBuf.Util
  6046. * @expose
  6047. */
  6048. ProtoBuf.Util = (function() {
  6049. /**
  6050. * ProtoBuf utilities.
  6051. * @exports ProtoBuf.Util
  6052. * @namespace
  6053. */
  6054. var Util = {};
  6055. /**
  6056. * Flag if running in node or not.
  6057. * @type {boolean}
  6058. * @const
  6059. * @expose
  6060. */
  6061. Util.IS_NODE = !!(
  6062. typeof process === 'object' && process+'' === '[object process]' && !process['browser']
  6063. );
  6064. /**
  6065. * Constructs a XMLHttpRequest object.
  6066. * @return {XMLHttpRequest}
  6067. * @throws {Error} If XMLHttpRequest is not supported
  6068. * @expose
  6069. */
  6070. Util.XHR = function() {
  6071. // No dependencies please, ref: http://www.quirksmode.org/js/xmlhttp.html
  6072. var XMLHttpFactories = [
  6073. function () {return new XMLHttpRequest()},
  6074. function () {return new ActiveXObject("Msxml2.XMLHTTP")},
  6075. function () {return new ActiveXObject("Msxml3.XMLHTTP")},
  6076. function () {return new ActiveXObject("Microsoft.XMLHTTP")}
  6077. ];
  6078. /** @type {?XMLHttpRequest} */
  6079. var xhr = null;
  6080. for (var i=0;i<XMLHttpFactories.length;i++) {
  6081. try { xhr = XMLHttpFactories[i](); }
  6082. catch (e) { continue; }
  6083. break;
  6084. }
  6085. if (!xhr)
  6086. throw Error("XMLHttpRequest is not supported");
  6087. return xhr;
  6088. };
  6089. /**
  6090. * Fetches a resource.
  6091. * @param {string} path Resource path
  6092. * @param {function(?string)=} callback Callback receiving the resource's contents. If omitted the resource will
  6093. * be fetched synchronously. If the request failed, contents will be null.
  6094. * @return {?string|undefined} Resource contents if callback is omitted (null if the request failed), else undefined.
  6095. * @expose
  6096. */
  6097. Util.fetch = function(path, callback) {
  6098. if (callback && typeof callback != 'function')
  6099. callback = null;
  6100. if (Util.IS_NODE) {
  6101. var fs = require$$2;
  6102. if (callback) {
  6103. fs.readFile(path, function(err, data) {
  6104. if (err)
  6105. callback(null);
  6106. else
  6107. callback(""+data);
  6108. });
  6109. } else
  6110. try {
  6111. return fs.readFileSync(path);
  6112. } catch (e) {
  6113. return null;
  6114. }
  6115. } else {
  6116. var xhr = Util.XHR();
  6117. xhr.open('GET', path, callback ? true : false);
  6118. // xhr.setRequestHeader('User-Agent', 'XMLHTTP/1.0');
  6119. xhr.setRequestHeader('Accept', 'text/plain');
  6120. if (typeof xhr.overrideMimeType === 'function') xhr.overrideMimeType('text/plain');
  6121. if (callback) {
  6122. xhr.onreadystatechange = function() {
  6123. if (xhr.readyState != 4) return;
  6124. if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
  6125. callback(xhr.responseText);
  6126. else
  6127. callback(null);
  6128. };
  6129. if (xhr.readyState == 4)
  6130. return;
  6131. xhr.send(null);
  6132. } else {
  6133. xhr.send(null);
  6134. if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
  6135. return xhr.responseText;
  6136. return null;
  6137. }
  6138. }
  6139. };
  6140. /**
  6141. * Converts a string to camel case.
  6142. * @param {string} str
  6143. * @returns {string}
  6144. * @expose
  6145. */
  6146. Util.toCamelCase = function(str) {
  6147. return str.replace(/_([a-zA-Z])/g, function ($0, $1) {
  6148. return $1.toUpperCase();
  6149. });
  6150. };
  6151. return Util;
  6152. })();
  6153. /**
  6154. * Language expressions.
  6155. * @type {!Object.<string,!RegExp>}
  6156. * @expose
  6157. */
  6158. ProtoBuf.Lang = {
  6159. // Characters always ending a statement
  6160. DELIM: /[\s\{\}=;:\[\],'"\(\)<>]/g,
  6161. // Field rules
  6162. RULE: /^(?:required|optional|repeated|map)$/,
  6163. // Field types
  6164. TYPE: /^(?:double|float|int32|uint32|sint32|int64|uint64|sint64|fixed32|sfixed32|fixed64|sfixed64|bool|string|bytes)$/,
  6165. // Names
  6166. NAME: /^[a-zA-Z_][a-zA-Z_0-9]*$/,
  6167. // Type definitions
  6168. TYPEDEF: /^[a-zA-Z][a-zA-Z_0-9]*$/,
  6169. // Type references
  6170. TYPEREF: /^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/,
  6171. // Fully qualified type references
  6172. FQTYPEREF: /^(?:\.[a-zA-Z_][a-zA-Z_0-9]*)+$/,
  6173. // All numbers
  6174. NUMBER: /^-?(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+|([0-9]*(\.[0-9]*)?([Ee][+-]?[0-9]+)?)|inf|nan)$/,
  6175. // Decimal numbers
  6176. NUMBER_DEC: /^(?:[1-9][0-9]*|0)$/,
  6177. // Hexadecimal numbers
  6178. NUMBER_HEX: /^0[xX][0-9a-fA-F]+$/,
  6179. // Octal numbers
  6180. NUMBER_OCT: /^0[0-7]+$/,
  6181. // Floating point numbers
  6182. NUMBER_FLT: /^([0-9]*(\.[0-9]*)?([Ee][+-]?[0-9]+)?|inf|nan)$/,
  6183. // Booleans
  6184. BOOL: /^(?:true|false)$/i,
  6185. // Id numbers
  6186. ID: /^(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+)$/,
  6187. // Negative id numbers (enum values)
  6188. NEGID: /^\-?(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+)$/,
  6189. // Whitespaces
  6190. WHITESPACE: /\s/,
  6191. // All strings
  6192. STRING: /(?:"([^"\\]*(?:\\.[^"\\]*)*)")|(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g,
  6193. // Double quoted strings
  6194. STRING_DQ: /(?:"([^"\\]*(?:\\.[^"\\]*)*)")/g,
  6195. // Single quoted strings
  6196. STRING_SQ: /(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g
  6197. };
  6198. /**
  6199. * @alias ProtoBuf.Reflect
  6200. * @expose
  6201. */
  6202. ProtoBuf.Reflect = (function(ProtoBuf) {
  6203. /**
  6204. * Reflection types.
  6205. * @exports ProtoBuf.Reflect
  6206. * @namespace
  6207. */
  6208. var Reflect = {};
  6209. /**
  6210. * Constructs a Reflect base class.
  6211. * @exports ProtoBuf.Reflect.T
  6212. * @constructor
  6213. * @abstract
  6214. * @param {!ProtoBuf.Builder} builder Builder reference
  6215. * @param {?ProtoBuf.Reflect.T} parent Parent object
  6216. * @param {string} name Object name
  6217. */
  6218. var T = function(builder, parent, name) {
  6219. /**
  6220. * Builder reference.
  6221. * @type {!ProtoBuf.Builder}
  6222. * @expose
  6223. */
  6224. this.builder = builder;
  6225. /**
  6226. * Parent object.
  6227. * @type {?ProtoBuf.Reflect.T}
  6228. * @expose
  6229. */
  6230. this.parent = parent;
  6231. /**
  6232. * Object name in namespace.
  6233. * @type {string}
  6234. * @expose
  6235. */
  6236. this.name = name;
  6237. /**
  6238. * Fully qualified class name
  6239. * @type {string}
  6240. * @expose
  6241. */
  6242. this.className;
  6243. };
  6244. /**
  6245. * @alias ProtoBuf.Reflect.T.prototype
  6246. * @inner
  6247. */
  6248. var TPrototype = T.prototype;
  6249. /**
  6250. * Returns the fully qualified name of this object.
  6251. * @returns {string} Fully qualified name as of ".PATH.TO.THIS"
  6252. * @expose
  6253. */
  6254. TPrototype.fqn = function() {
  6255. var name = this.name,
  6256. ptr = this;
  6257. do {
  6258. ptr = ptr.parent;
  6259. if (ptr == null)
  6260. break;
  6261. name = ptr.name+"."+name;
  6262. } while (true);
  6263. return name;
  6264. };
  6265. /**
  6266. * Returns a string representation of this Reflect object (its fully qualified name).
  6267. * @param {boolean=} includeClass Set to true to include the class name. Defaults to false.
  6268. * @return String representation
  6269. * @expose
  6270. */
  6271. TPrototype.toString = function(includeClass) {
  6272. return (includeClass ? this.className + " " : "") + this.fqn();
  6273. };
  6274. /**
  6275. * Builds this type.
  6276. * @throws {Error} If this type cannot be built directly
  6277. * @expose
  6278. */
  6279. TPrototype.build = function() {
  6280. throw Error(this.toString(true)+" cannot be built directly");
  6281. };
  6282. /**
  6283. * @alias ProtoBuf.Reflect.T
  6284. * @expose
  6285. */
  6286. Reflect.T = T;
  6287. /**
  6288. * Constructs a new Namespace.
  6289. * @exports ProtoBuf.Reflect.Namespace
  6290. * @param {!ProtoBuf.Builder} builder Builder reference
  6291. * @param {?ProtoBuf.Reflect.Namespace} parent Namespace parent
  6292. * @param {string} name Namespace name
  6293. * @param {Object.<string,*>=} options Namespace options
  6294. * @param {string?} syntax The syntax level of this definition (e.g., proto3)
  6295. * @constructor
  6296. * @extends ProtoBuf.Reflect.T
  6297. */
  6298. var Namespace = function(builder, parent, name, options, syntax) {
  6299. T.call(this, builder, parent, name);
  6300. /**
  6301. * @override
  6302. */
  6303. this.className = "Namespace";
  6304. /**
  6305. * Children inside the namespace.
  6306. * @type {!Array.<ProtoBuf.Reflect.T>}
  6307. */
  6308. this.children = [];
  6309. /**
  6310. * Options.
  6311. * @type {!Object.<string, *>}
  6312. */
  6313. this.options = options || {};
  6314. /**
  6315. * Syntax level (e.g., proto2 or proto3).
  6316. * @type {!string}
  6317. */
  6318. this.syntax = syntax || "proto2";
  6319. };
  6320. /**
  6321. * @alias ProtoBuf.Reflect.Namespace.prototype
  6322. * @inner
  6323. */
  6324. var NamespacePrototype = Namespace.prototype = Object.create(T.prototype);
  6325. /**
  6326. * Returns an array of the namespace's children.
  6327. * @param {ProtoBuf.Reflect.T=} type Filter type (returns instances of this type only). Defaults to null (all children).
  6328. * @return {Array.<ProtoBuf.Reflect.T>}
  6329. * @expose
  6330. */
  6331. NamespacePrototype.getChildren = function(type) {
  6332. type = type || null;
  6333. if (type == null)
  6334. return this.children.slice();
  6335. var children = [];
  6336. for (var i=0, k=this.children.length; i<k; ++i)
  6337. if (this.children[i] instanceof type)
  6338. children.push(this.children[i]);
  6339. return children;
  6340. };
  6341. /**
  6342. * Adds a child to the namespace.
  6343. * @param {ProtoBuf.Reflect.T} child Child
  6344. * @throws {Error} If the child cannot be added (duplicate)
  6345. * @expose
  6346. */
  6347. NamespacePrototype.addChild = function(child) {
  6348. var other;
  6349. if (other = this.getChild(child.name)) {
  6350. // Try to revert camelcase transformation on collision
  6351. if (other instanceof Message.Field && other.name !== other.originalName && this.getChild(other.originalName) === null)
  6352. other.name = other.originalName; // Revert previous first (effectively keeps both originals)
  6353. else if (child instanceof Message.Field && child.name !== child.originalName && this.getChild(child.originalName) === null)
  6354. child.name = child.originalName;
  6355. else
  6356. throw Error("Duplicate name in namespace "+this.toString(true)+": "+child.name);
  6357. }
  6358. this.children.push(child);
  6359. };
  6360. /**
  6361. * Gets a child by its name or id.
  6362. * @param {string|number} nameOrId Child name or id
  6363. * @return {?ProtoBuf.Reflect.T} The child or null if not found
  6364. * @expose
  6365. */
  6366. NamespacePrototype.getChild = function(nameOrId) {
  6367. var key = typeof nameOrId === 'number' ? 'id' : 'name';
  6368. for (var i=0, k=this.children.length; i<k; ++i)
  6369. if (this.children[i][key] === nameOrId)
  6370. return this.children[i];
  6371. return null;
  6372. };
  6373. /**
  6374. * Resolves a reflect object inside of this namespace.
  6375. * @param {string|!Array.<string>} qn Qualified name to resolve
  6376. * @param {boolean=} excludeNonNamespace Excludes non-namespace types, defaults to `false`
  6377. * @return {?ProtoBuf.Reflect.Namespace} The resolved type or null if not found
  6378. * @expose
  6379. */
  6380. NamespacePrototype.resolve = function(qn, excludeNonNamespace) {
  6381. var part = typeof qn === 'string' ? qn.split(".") : qn,
  6382. ptr = this,
  6383. i = 0;
  6384. if (part[i] === "") { // Fully qualified name, e.g. ".My.Message'
  6385. while (ptr.parent !== null)
  6386. ptr = ptr.parent;
  6387. i++;
  6388. }
  6389. var child;
  6390. do {
  6391. do {
  6392. if (!(ptr instanceof Reflect.Namespace)) {
  6393. ptr = null;
  6394. break;
  6395. }
  6396. child = ptr.getChild(part[i]);
  6397. if (!child || !(child instanceof Reflect.T) || (excludeNonNamespace && !(child instanceof Reflect.Namespace))) {
  6398. ptr = null;
  6399. break;
  6400. }
  6401. ptr = child; i++;
  6402. } while (i < part.length);
  6403. if (ptr != null)
  6404. break; // Found
  6405. // Else search the parent
  6406. if (this.parent !== null)
  6407. return this.parent.resolve(qn, excludeNonNamespace);
  6408. } while (ptr != null);
  6409. return ptr;
  6410. };
  6411. /**
  6412. * Determines the shortest qualified name of the specified type, if any, relative to this namespace.
  6413. * @param {!ProtoBuf.Reflect.T} t Reflection type
  6414. * @returns {string} The shortest qualified name or, if there is none, the fqn
  6415. * @expose
  6416. */
  6417. NamespacePrototype.qn = function(t) {
  6418. var part = [], ptr = t;
  6419. do {
  6420. part.unshift(ptr.name);
  6421. ptr = ptr.parent;
  6422. } while (ptr !== null);
  6423. for (var len=1; len <= part.length; len++) {
  6424. var qn = part.slice(part.length-len);
  6425. if (t === this.resolve(qn, t instanceof Reflect.Namespace))
  6426. return qn.join(".");
  6427. }
  6428. return t.fqn();
  6429. };
  6430. /**
  6431. * Builds the namespace and returns the runtime counterpart.
  6432. * @return {Object.<string,Function|Object>} Runtime namespace
  6433. * @expose
  6434. */
  6435. NamespacePrototype.build = function() {
  6436. /** @dict */
  6437. var ns = {};
  6438. var children = this.children;
  6439. for (var i=0, k=children.length, child; i<k; ++i) {
  6440. child = children[i];
  6441. if (child instanceof Namespace)
  6442. ns[child.name] = child.build();
  6443. }
  6444. if (Object.defineProperty)
  6445. Object.defineProperty(ns, "$options", { "value": this.buildOpt() });
  6446. return ns;
  6447. };
  6448. /**
  6449. * Builds the namespace's '$options' property.
  6450. * @return {Object.<string,*>}
  6451. */
  6452. NamespacePrototype.buildOpt = function() {
  6453. var opt = {},
  6454. keys = Object.keys(this.options);
  6455. for (var i=0, k=keys.length; i<k; ++i) {
  6456. var key = keys[i],
  6457. val = this.options[keys[i]];
  6458. // TODO: Options are not resolved, yet.
  6459. // if (val instanceof Namespace) {
  6460. // opt[key] = val.build();
  6461. // } else {
  6462. opt[key] = val;
  6463. // }
  6464. }
  6465. return opt;
  6466. };
  6467. /**
  6468. * Gets the value assigned to the option with the specified name.
  6469. * @param {string=} name Returns the option value if specified, otherwise all options are returned.
  6470. * @return {*|Object.<string,*>}null} Option value or NULL if there is no such option
  6471. */
  6472. NamespacePrototype.getOption = function(name) {
  6473. if (typeof name === 'undefined')
  6474. return this.options;
  6475. return typeof this.options[name] !== 'undefined' ? this.options[name] : null;
  6476. };
  6477. /**
  6478. * @alias ProtoBuf.Reflect.Namespace
  6479. * @expose
  6480. */
  6481. Reflect.Namespace = Namespace;
  6482. /**
  6483. * Constructs a new Element implementation that checks and converts values for a
  6484. * particular field type, as appropriate.
  6485. *
  6486. * An Element represents a single value: either the value of a singular field,
  6487. * or a value contained in one entry of a repeated field or map field. This
  6488. * class does not implement these higher-level concepts; it only encapsulates
  6489. * the low-level typechecking and conversion.
  6490. *
  6491. * @exports ProtoBuf.Reflect.Element
  6492. * @param {{name: string, wireType: number}} type Resolved data type
  6493. * @param {ProtoBuf.Reflect.T|null} resolvedType Resolved type, if relevant
  6494. * (e.g. submessage field).
  6495. * @param {boolean} isMapKey Is this element a Map key? The value will be
  6496. * converted to string form if so.
  6497. * @param {string} syntax Syntax level of defining message type, e.g.,
  6498. * proto2 or proto3.
  6499. * @param {string} name Name of the field containing this element (for error
  6500. * messages)
  6501. * @constructor
  6502. */
  6503. var Element = function(type, resolvedType, isMapKey, syntax, name) {
  6504. /**
  6505. * Element type, as a string (e.g., int32).
  6506. * @type {{name: string, wireType: number}}
  6507. */
  6508. this.type = type;
  6509. /**
  6510. * Element type reference to submessage or enum definition, if needed.
  6511. * @type {ProtoBuf.Reflect.T|null}
  6512. */
  6513. this.resolvedType = resolvedType;
  6514. /**
  6515. * Element is a map key.
  6516. * @type {boolean}
  6517. */
  6518. this.isMapKey = isMapKey;
  6519. /**
  6520. * Syntax level of defining message type, e.g., proto2 or proto3.
  6521. * @type {string}
  6522. */
  6523. this.syntax = syntax;
  6524. /**
  6525. * Name of the field containing this element (for error messages)
  6526. * @type {string}
  6527. */
  6528. this.name = name;
  6529. if (isMapKey && ProtoBuf.MAP_KEY_TYPES.indexOf(type) < 0)
  6530. throw Error("Invalid map key type: " + type.name);
  6531. };
  6532. var ElementPrototype = Element.prototype;
  6533. /**
  6534. * Obtains a (new) default value for the specified type.
  6535. * @param type {string|{name: string, wireType: number}} Field type
  6536. * @returns {*} Default value
  6537. * @inner
  6538. */
  6539. function mkDefault(type) {
  6540. if (typeof type === 'string')
  6541. type = ProtoBuf.TYPES[type];
  6542. if (typeof type.defaultValue === 'undefined')
  6543. throw Error("default value for type "+type.name+" is not supported");
  6544. if (type == ProtoBuf.TYPES["bytes"])
  6545. return new ByteBuffer(0);
  6546. return type.defaultValue;
  6547. }
  6548. /**
  6549. * Returns the default value for this field in proto3.
  6550. * @function
  6551. * @param type {string|{name: string, wireType: number}} the field type
  6552. * @returns {*} Default value
  6553. */
  6554. Element.defaultFieldValue = mkDefault;
  6555. /**
  6556. * Makes a Long from a value.
  6557. * @param {{low: number, high: number, unsigned: boolean}|string|number} value Value
  6558. * @param {boolean=} unsigned Whether unsigned or not, defaults to reuse it from Long-like objects or to signed for
  6559. * strings and numbers
  6560. * @returns {!Long}
  6561. * @throws {Error} If the value cannot be converted to a Long
  6562. * @inner
  6563. */
  6564. function mkLong(value, unsigned) {
  6565. if (value && typeof value.low === 'number' && typeof value.high === 'number' && typeof value.unsigned === 'boolean'
  6566. && value.low === value.low && value.high === value.high)
  6567. return new ProtoBuf.Long(value.low, value.high, typeof unsigned === 'undefined' ? value.unsigned : unsigned);
  6568. if (typeof value === 'string')
  6569. return ProtoBuf.Long.fromString(value, unsigned || false, 10);
  6570. if (typeof value === 'number')
  6571. return ProtoBuf.Long.fromNumber(value, unsigned || false);
  6572. throw Error("not convertible to Long");
  6573. }
  6574. ElementPrototype.toString = function() {
  6575. return (this.name || '') + (this.isMapKey ? 'map' : 'value') + ' element';
  6576. };
  6577. /**
  6578. * Checks if the given value can be set for an element of this type (singular
  6579. * field or one element of a repeated field or map).
  6580. * @param {*} value Value to check
  6581. * @return {*} Verified, maybe adjusted, value
  6582. * @throws {Error} If the value cannot be verified for this element slot
  6583. * @expose
  6584. */
  6585. ElementPrototype.verifyValue = function(value) {
  6586. var self = this;
  6587. function fail(val, msg) {
  6588. throw Error("Illegal value for "+self.toString(true)+" of type "+self.type.name+": "+val+" ("+msg+")");
  6589. }
  6590. switch (this.type) {
  6591. // Signed 32bit
  6592. case ProtoBuf.TYPES["int32"]:
  6593. case ProtoBuf.TYPES["sint32"]:
  6594. case ProtoBuf.TYPES["sfixed32"]:
  6595. // Account for !NaN: value === value
  6596. if (typeof value !== 'number' || (value === value && value % 1 !== 0))
  6597. fail(typeof value, "not an integer");
  6598. return value > 4294967295 ? value | 0 : value;
  6599. // Unsigned 32bit
  6600. case ProtoBuf.TYPES["uint32"]:
  6601. case ProtoBuf.TYPES["fixed32"]:
  6602. if (typeof value !== 'number' || (value === value && value % 1 !== 0))
  6603. fail(typeof value, "not an integer");
  6604. return value < 0 ? value >>> 0 : value;
  6605. // Signed 64bit
  6606. case ProtoBuf.TYPES["int64"]:
  6607. case ProtoBuf.TYPES["sint64"]:
  6608. case ProtoBuf.TYPES["sfixed64"]: {
  6609. if (ProtoBuf.Long)
  6610. try {
  6611. return mkLong(value, false);
  6612. } catch (e) {
  6613. fail(typeof value, e.message);
  6614. }
  6615. else
  6616. fail(typeof value, "requires Long.js");
  6617. }
  6618. // Unsigned 64bit
  6619. case ProtoBuf.TYPES["uint64"]:
  6620. case ProtoBuf.TYPES["fixed64"]: {
  6621. if (ProtoBuf.Long)
  6622. try {
  6623. return mkLong(value, true);
  6624. } catch (e) {
  6625. fail(typeof value, e.message);
  6626. }
  6627. else
  6628. fail(typeof value, "requires Long.js");
  6629. }
  6630. // Bool
  6631. case ProtoBuf.TYPES["bool"]:
  6632. if (typeof value !== 'boolean')
  6633. fail(typeof value, "not a boolean");
  6634. return value;
  6635. // Float
  6636. case ProtoBuf.TYPES["float"]:
  6637. case ProtoBuf.TYPES["double"]:
  6638. if (typeof value !== 'number')
  6639. fail(typeof value, "not a number");
  6640. return value;
  6641. // Length-delimited string
  6642. case ProtoBuf.TYPES["string"]:
  6643. if (typeof value !== 'string' && !(value && value instanceof String))
  6644. fail(typeof value, "not a string");
  6645. return ""+value; // Convert String object to string
  6646. // Length-delimited bytes
  6647. case ProtoBuf.TYPES["bytes"]:
  6648. if (ByteBuffer.isByteBuffer(value))
  6649. return value;
  6650. return ByteBuffer.wrap(value, "base64");
  6651. // Constant enum value
  6652. case ProtoBuf.TYPES["enum"]: {
  6653. var values = this.resolvedType.getChildren(ProtoBuf.Reflect.Enum.Value);
  6654. for (i=0; i<values.length; i++)
  6655. if (values[i].name == value)
  6656. return values[i].id;
  6657. else if (values[i].id == value)
  6658. return values[i].id;
  6659. if (this.syntax === 'proto3') {
  6660. // proto3: just make sure it's an integer.
  6661. if (typeof value !== 'number' || (value === value && value % 1 !== 0))
  6662. fail(typeof value, "not an integer");
  6663. if (value > 4294967295 || value < 0)
  6664. fail(typeof value, "not in range for uint32");
  6665. return value;
  6666. } else {
  6667. // proto2 requires enum values to be valid.
  6668. fail(value, "not a valid enum value");
  6669. }
  6670. }
  6671. // Embedded message
  6672. case ProtoBuf.TYPES["group"]:
  6673. case ProtoBuf.TYPES["message"]: {
  6674. if (!value || typeof value !== 'object')
  6675. fail(typeof value, "object expected");
  6676. if (value instanceof this.resolvedType.clazz)
  6677. return value;
  6678. if (value instanceof ProtoBuf.Builder.Message) {
  6679. // Mismatched type: Convert to object (see: https://github.com/dcodeIO/ProtoBuf.js/issues/180)
  6680. var obj = {};
  6681. for (var i in value)
  6682. if (value.hasOwnProperty(i))
  6683. obj[i] = value[i];
  6684. value = obj;
  6685. }
  6686. // Else let's try to construct one from a key-value object
  6687. return new (this.resolvedType.clazz)(value); // May throw for a hundred of reasons
  6688. }
  6689. }
  6690. // We should never end here
  6691. throw Error("[INTERNAL] Illegal value for "+this.toString(true)+": "+value+" (undefined type "+this.type+")");
  6692. };
  6693. /**
  6694. * Calculates the byte length of an element on the wire.
  6695. * @param {number} id Field number
  6696. * @param {*} value Field value
  6697. * @returns {number} Byte length
  6698. * @throws {Error} If the value cannot be calculated
  6699. * @expose
  6700. */
  6701. ElementPrototype.calculateLength = function(id, value) {
  6702. if (value === null) return 0; // Nothing to encode
  6703. // Tag has already been written
  6704. var n;
  6705. switch (this.type) {
  6706. case ProtoBuf.TYPES["int32"]:
  6707. return value < 0 ? ByteBuffer.calculateVarint64(value) : ByteBuffer.calculateVarint32(value);
  6708. case ProtoBuf.TYPES["uint32"]:
  6709. return ByteBuffer.calculateVarint32(value);
  6710. case ProtoBuf.TYPES["sint32"]:
  6711. return ByteBuffer.calculateVarint32(ByteBuffer.zigZagEncode32(value));
  6712. case ProtoBuf.TYPES["fixed32"]:
  6713. case ProtoBuf.TYPES["sfixed32"]:
  6714. case ProtoBuf.TYPES["float"]:
  6715. return 4;
  6716. case ProtoBuf.TYPES["int64"]:
  6717. case ProtoBuf.TYPES["uint64"]:
  6718. return ByteBuffer.calculateVarint64(value);
  6719. case ProtoBuf.TYPES["sint64"]:
  6720. return ByteBuffer.calculateVarint64(ByteBuffer.zigZagEncode64(value));
  6721. case ProtoBuf.TYPES["fixed64"]:
  6722. case ProtoBuf.TYPES["sfixed64"]:
  6723. return 8;
  6724. case ProtoBuf.TYPES["bool"]:
  6725. return 1;
  6726. case ProtoBuf.TYPES["enum"]:
  6727. return ByteBuffer.calculateVarint32(value);
  6728. case ProtoBuf.TYPES["double"]:
  6729. return 8;
  6730. case ProtoBuf.TYPES["string"]:
  6731. n = ByteBuffer.calculateUTF8Bytes(value);
  6732. return ByteBuffer.calculateVarint32(n) + n;
  6733. case ProtoBuf.TYPES["bytes"]:
  6734. if (value.remaining() < 0)
  6735. throw Error("Illegal value for "+this.toString(true)+": "+value.remaining()+" bytes remaining");
  6736. return ByteBuffer.calculateVarint32(value.remaining()) + value.remaining();
  6737. case ProtoBuf.TYPES["message"]:
  6738. n = this.resolvedType.calculate(value);
  6739. return ByteBuffer.calculateVarint32(n) + n;
  6740. case ProtoBuf.TYPES["group"]:
  6741. n = this.resolvedType.calculate(value);
  6742. return n + ByteBuffer.calculateVarint32((id << 3) | ProtoBuf.WIRE_TYPES.ENDGROUP);
  6743. }
  6744. // We should never end here
  6745. throw Error("[INTERNAL] Illegal value to encode in "+this.toString(true)+": "+value+" (unknown type)");
  6746. };
  6747. /**
  6748. * Encodes a value to the specified buffer. Does not encode the key.
  6749. * @param {number} id Field number
  6750. * @param {*} value Field value
  6751. * @param {ByteBuffer} buffer ByteBuffer to encode to
  6752. * @return {ByteBuffer} The ByteBuffer for chaining
  6753. * @throws {Error} If the value cannot be encoded
  6754. * @expose
  6755. */
  6756. ElementPrototype.encodeValue = function(id, value, buffer) {
  6757. if (value === null) return buffer; // Nothing to encode
  6758. // Tag has already been written
  6759. switch (this.type) {
  6760. // 32bit signed varint
  6761. case ProtoBuf.TYPES["int32"]:
  6762. // "If you use int32 or int64 as the type for a negative number, the resulting varint is always ten bytes
  6763. // long – it is, effectively, treated like a very large unsigned integer." (see #122)
  6764. if (value < 0)
  6765. buffer.writeVarint64(value);
  6766. else
  6767. buffer.writeVarint32(value);
  6768. break;
  6769. // 32bit unsigned varint
  6770. case ProtoBuf.TYPES["uint32"]:
  6771. buffer.writeVarint32(value);
  6772. break;
  6773. // 32bit varint zig-zag
  6774. case ProtoBuf.TYPES["sint32"]:
  6775. buffer.writeVarint32ZigZag(value);
  6776. break;
  6777. // Fixed unsigned 32bit
  6778. case ProtoBuf.TYPES["fixed32"]:
  6779. buffer.writeUint32(value);
  6780. break;
  6781. // Fixed signed 32bit
  6782. case ProtoBuf.TYPES["sfixed32"]:
  6783. buffer.writeInt32(value);
  6784. break;
  6785. // 64bit varint as-is
  6786. case ProtoBuf.TYPES["int64"]:
  6787. case ProtoBuf.TYPES["uint64"]:
  6788. buffer.writeVarint64(value); // throws
  6789. break;
  6790. // 64bit varint zig-zag
  6791. case ProtoBuf.TYPES["sint64"]:
  6792. buffer.writeVarint64ZigZag(value); // throws
  6793. break;
  6794. // Fixed unsigned 64bit
  6795. case ProtoBuf.TYPES["fixed64"]:
  6796. buffer.writeUint64(value); // throws
  6797. break;
  6798. // Fixed signed 64bit
  6799. case ProtoBuf.TYPES["sfixed64"]:
  6800. buffer.writeInt64(value); // throws
  6801. break;
  6802. // Bool
  6803. case ProtoBuf.TYPES["bool"]:
  6804. if (typeof value === 'string')
  6805. buffer.writeVarint32(value.toLowerCase() === 'false' ? 0 : !!value);
  6806. else
  6807. buffer.writeVarint32(value ? 1 : 0);
  6808. break;
  6809. // Constant enum value
  6810. case ProtoBuf.TYPES["enum"]:
  6811. buffer.writeVarint32(value);
  6812. break;
  6813. // 32bit float
  6814. case ProtoBuf.TYPES["float"]:
  6815. buffer.writeFloat32(value);
  6816. break;
  6817. // 64bit float
  6818. case ProtoBuf.TYPES["double"]:
  6819. buffer.writeFloat64(value);
  6820. break;
  6821. // Length-delimited string
  6822. case ProtoBuf.TYPES["string"]:
  6823. buffer.writeVString(value);
  6824. break;
  6825. // Length-delimited bytes
  6826. case ProtoBuf.TYPES["bytes"]:
  6827. if (value.remaining() < 0)
  6828. throw Error("Illegal value for "+this.toString(true)+": "+value.remaining()+" bytes remaining");
  6829. var prevOffset = value.offset;
  6830. buffer.writeVarint32(value.remaining());
  6831. buffer.append(value);
  6832. value.offset = prevOffset;
  6833. break;
  6834. // Embedded message
  6835. case ProtoBuf.TYPES["message"]:
  6836. var bb = new ByteBuffer().LE();
  6837. this.resolvedType.encode(value, bb);
  6838. buffer.writeVarint32(bb.offset);
  6839. buffer.append(bb.flip());
  6840. break;
  6841. // Legacy group
  6842. case ProtoBuf.TYPES["group"]:
  6843. this.resolvedType.encode(value, buffer);
  6844. buffer.writeVarint32((id << 3) | ProtoBuf.WIRE_TYPES.ENDGROUP);
  6845. break;
  6846. default:
  6847. // We should never end here
  6848. throw Error("[INTERNAL] Illegal value to encode in "+this.toString(true)+": "+value+" (unknown type)");
  6849. }
  6850. return buffer;
  6851. };
  6852. /**
  6853. * Decode one element value from the specified buffer.
  6854. * @param {ByteBuffer} buffer ByteBuffer to decode from
  6855. * @param {number} wireType The field wire type
  6856. * @param {number} id The field number
  6857. * @return {*} Decoded value
  6858. * @throws {Error} If the field cannot be decoded
  6859. * @expose
  6860. */
  6861. ElementPrototype.decode = function(buffer, wireType, id) {
  6862. if (wireType != this.type.wireType)
  6863. throw Error("Unexpected wire type for element");
  6864. var value, nBytes;
  6865. switch (this.type) {
  6866. // 32bit signed varint
  6867. case ProtoBuf.TYPES["int32"]:
  6868. return buffer.readVarint32() | 0;
  6869. // 32bit unsigned varint
  6870. case ProtoBuf.TYPES["uint32"]:
  6871. return buffer.readVarint32() >>> 0;
  6872. // 32bit signed varint zig-zag
  6873. case ProtoBuf.TYPES["sint32"]:
  6874. return buffer.readVarint32ZigZag() | 0;
  6875. // Fixed 32bit unsigned
  6876. case ProtoBuf.TYPES["fixed32"]:
  6877. return buffer.readUint32() >>> 0;
  6878. case ProtoBuf.TYPES["sfixed32"]:
  6879. return buffer.readInt32() | 0;
  6880. // 64bit signed varint
  6881. case ProtoBuf.TYPES["int64"]:
  6882. return buffer.readVarint64();
  6883. // 64bit unsigned varint
  6884. case ProtoBuf.TYPES["uint64"]:
  6885. return buffer.readVarint64().toUnsigned();
  6886. // 64bit signed varint zig-zag
  6887. case ProtoBuf.TYPES["sint64"]:
  6888. return buffer.readVarint64ZigZag();
  6889. // Fixed 64bit unsigned
  6890. case ProtoBuf.TYPES["fixed64"]:
  6891. return buffer.readUint64();
  6892. // Fixed 64bit signed
  6893. case ProtoBuf.TYPES["sfixed64"]:
  6894. return buffer.readInt64();
  6895. // Bool varint
  6896. case ProtoBuf.TYPES["bool"]:
  6897. return !!buffer.readVarint32();
  6898. // Constant enum value (varint)
  6899. case ProtoBuf.TYPES["enum"]:
  6900. // The following Builder.Message#set will already throw
  6901. return buffer.readVarint32();
  6902. // 32bit float
  6903. case ProtoBuf.TYPES["float"]:
  6904. return buffer.readFloat();
  6905. // 64bit float
  6906. case ProtoBuf.TYPES["double"]:
  6907. return buffer.readDouble();
  6908. // Length-delimited string
  6909. case ProtoBuf.TYPES["string"]:
  6910. return buffer.readVString();
  6911. // Length-delimited bytes
  6912. case ProtoBuf.TYPES["bytes"]: {
  6913. nBytes = buffer.readVarint32();
  6914. if (buffer.remaining() < nBytes)
  6915. throw Error("Illegal number of bytes for "+this.toString(true)+": "+nBytes+" required but got only "+buffer.remaining());
  6916. value = buffer.clone(); // Offset already set
  6917. value.limit = value.offset+nBytes;
  6918. buffer.offset += nBytes;
  6919. return value;
  6920. }
  6921. // Length-delimited embedded message
  6922. case ProtoBuf.TYPES["message"]: {
  6923. nBytes = buffer.readVarint32();
  6924. return this.resolvedType.decode(buffer, nBytes);
  6925. }
  6926. // Legacy group
  6927. case ProtoBuf.TYPES["group"]:
  6928. return this.resolvedType.decode(buffer, -1, id);
  6929. }
  6930. // We should never end here
  6931. throw Error("[INTERNAL] Illegal decode type");
  6932. };
  6933. /**
  6934. * Converts a value from a string to the canonical element type.
  6935. *
  6936. * Legal only when isMapKey is true.
  6937. *
  6938. * @param {string} str The string value
  6939. * @returns {*} The value
  6940. */
  6941. ElementPrototype.valueFromString = function(str) {
  6942. if (!this.isMapKey) {
  6943. throw Error("valueFromString() called on non-map-key element");
  6944. }
  6945. switch (this.type) {
  6946. case ProtoBuf.TYPES["int32"]:
  6947. case ProtoBuf.TYPES["sint32"]:
  6948. case ProtoBuf.TYPES["sfixed32"]:
  6949. case ProtoBuf.TYPES["uint32"]:
  6950. case ProtoBuf.TYPES["fixed32"]:
  6951. return this.verifyValue(parseInt(str));
  6952. case ProtoBuf.TYPES["int64"]:
  6953. case ProtoBuf.TYPES["sint64"]:
  6954. case ProtoBuf.TYPES["sfixed64"]:
  6955. case ProtoBuf.TYPES["uint64"]:
  6956. case ProtoBuf.TYPES["fixed64"]:
  6957. // Long-based fields support conversions from string already.
  6958. return this.verifyValue(str);
  6959. case ProtoBuf.TYPES["bool"]:
  6960. return str === "true";
  6961. case ProtoBuf.TYPES["string"]:
  6962. return this.verifyValue(str);
  6963. case ProtoBuf.TYPES["bytes"]:
  6964. return ByteBuffer.fromBinary(str);
  6965. }
  6966. };
  6967. /**
  6968. * Converts a value from the canonical element type to a string.
  6969. *
  6970. * It should be the case that `valueFromString(valueToString(val))` returns
  6971. * a value equivalent to `verifyValue(val)` for every legal value of `val`
  6972. * according to this element type.
  6973. *
  6974. * This may be used when the element must be stored or used as a string,
  6975. * e.g., as a map key on an Object.
  6976. *
  6977. * Legal only when isMapKey is true.
  6978. *
  6979. * @param {*} val The value
  6980. * @returns {string} The string form of the value.
  6981. */
  6982. ElementPrototype.valueToString = function(value) {
  6983. if (!this.isMapKey) {
  6984. throw Error("valueToString() called on non-map-key element");
  6985. }
  6986. if (this.type === ProtoBuf.TYPES["bytes"]) {
  6987. return value.toString("binary");
  6988. } else {
  6989. return value.toString();
  6990. }
  6991. };
  6992. /**
  6993. * @alias ProtoBuf.Reflect.Element
  6994. * @expose
  6995. */
  6996. Reflect.Element = Element;
  6997. /**
  6998. * Constructs a new Message.
  6999. * @exports ProtoBuf.Reflect.Message
  7000. * @param {!ProtoBuf.Builder} builder Builder reference
  7001. * @param {!ProtoBuf.Reflect.Namespace} parent Parent message or namespace
  7002. * @param {string} name Message name
  7003. * @param {Object.<string,*>=} options Message options
  7004. * @param {boolean=} isGroup `true` if this is a legacy group
  7005. * @param {string?} syntax The syntax level of this definition (e.g., proto3)
  7006. * @constructor
  7007. * @extends ProtoBuf.Reflect.Namespace
  7008. */
  7009. var Message = function(builder, parent, name, options, isGroup, syntax) {
  7010. Namespace.call(this, builder, parent, name, options, syntax);
  7011. /**
  7012. * @override
  7013. */
  7014. this.className = "Message";
  7015. /**
  7016. * Extensions range.
  7017. * @type {!Array.<number>|undefined}
  7018. * @expose
  7019. */
  7020. this.extensions = undefined;
  7021. /**
  7022. * Runtime message class.
  7023. * @type {?function(new:ProtoBuf.Builder.Message)}
  7024. * @expose
  7025. */
  7026. this.clazz = null;
  7027. /**
  7028. * Whether this is a legacy group or not.
  7029. * @type {boolean}
  7030. * @expose
  7031. */
  7032. this.isGroup = !!isGroup;
  7033. // The following cached collections are used to efficiently iterate over or look up fields when decoding.
  7034. /**
  7035. * Cached fields.
  7036. * @type {?Array.<!ProtoBuf.Reflect.Message.Field>}
  7037. * @private
  7038. */
  7039. this._fields = null;
  7040. /**
  7041. * Cached fields by id.
  7042. * @type {?Object.<number,!ProtoBuf.Reflect.Message.Field>}
  7043. * @private
  7044. */
  7045. this._fieldsById = null;
  7046. /**
  7047. * Cached fields by name.
  7048. * @type {?Object.<string,!ProtoBuf.Reflect.Message.Field>}
  7049. * @private
  7050. */
  7051. this._fieldsByName = null;
  7052. };
  7053. /**
  7054. * @alias ProtoBuf.Reflect.Message.prototype
  7055. * @inner
  7056. */
  7057. var MessagePrototype = Message.prototype = Object.create(Namespace.prototype);
  7058. /**
  7059. * Builds the message and returns the runtime counterpart, which is a fully functional class.
  7060. * @see ProtoBuf.Builder.Message
  7061. * @param {boolean=} rebuild Whether to rebuild or not, defaults to false
  7062. * @return {ProtoBuf.Reflect.Message} Message class
  7063. * @throws {Error} If the message cannot be built
  7064. * @expose
  7065. */
  7066. MessagePrototype.build = function(rebuild) {
  7067. if (this.clazz && !rebuild)
  7068. return this.clazz;
  7069. // Create the runtime Message class in its own scope
  7070. var clazz = (function(ProtoBuf, T) {
  7071. var fields = T.getChildren(ProtoBuf.Reflect.Message.Field),
  7072. oneofs = T.getChildren(ProtoBuf.Reflect.Message.OneOf);
  7073. /**
  7074. * Constructs a new runtime Message.
  7075. * @name ProtoBuf.Builder.Message
  7076. * @class Barebone of all runtime messages.
  7077. * @param {!Object.<string,*>|string} values Preset values
  7078. * @param {...string} var_args
  7079. * @constructor
  7080. * @throws {Error} If the message cannot be created
  7081. */
  7082. var Message = function(values, var_args) {
  7083. ProtoBuf.Builder.Message.call(this);
  7084. // Create virtual oneof properties
  7085. for (var i=0, k=oneofs.length; i<k; ++i)
  7086. this[oneofs[i].name] = null;
  7087. // Create fields and set default values
  7088. for (i=0, k=fields.length; i<k; ++i) {
  7089. var field = fields[i];
  7090. this[field.name] =
  7091. field.repeated ? [] :
  7092. (field.map ? new ProtoBuf.Map(field) : null);
  7093. if ((field.required || T.syntax === 'proto3') &&
  7094. field.defaultValue !== null)
  7095. this[field.name] = field.defaultValue;
  7096. }
  7097. if (arguments.length > 0) {
  7098. var value;
  7099. // Set field values from a values object
  7100. if (arguments.length === 1 && values !== null && typeof values === 'object' &&
  7101. /* not _another_ Message */ (typeof values.encode !== 'function' || values instanceof Message) &&
  7102. /* not a repeated field */ !Array.isArray(values) &&
  7103. /* not a Map */ !(values instanceof ProtoBuf.Map) &&
  7104. /* not a ByteBuffer */ !ByteBuffer.isByteBuffer(values) &&
  7105. /* not an ArrayBuffer */ !(values instanceof ArrayBuffer) &&
  7106. /* not a Long */ !(ProtoBuf.Long && values instanceof ProtoBuf.Long)) {
  7107. this.$set(values);
  7108. } else // Set field values from arguments, in declaration order
  7109. for (i=0, k=arguments.length; i<k; ++i)
  7110. if (typeof (value = arguments[i]) !== 'undefined')
  7111. this.$set(fields[i].name, value); // May throw
  7112. }
  7113. };
  7114. /**
  7115. * @alias ProtoBuf.Builder.Message.prototype
  7116. * @inner
  7117. */
  7118. var MessagePrototype = Message.prototype = Object.create(ProtoBuf.Builder.Message.prototype);
  7119. /**
  7120. * Adds a value to a repeated field.
  7121. * @name ProtoBuf.Builder.Message#add
  7122. * @function
  7123. * @param {string} key Field name
  7124. * @param {*} value Value to add
  7125. * @param {boolean=} noAssert Whether to assert the value or not (asserts by default)
  7126. * @returns {!ProtoBuf.Builder.Message} this
  7127. * @throws {Error} If the value cannot be added
  7128. * @expose
  7129. */
  7130. MessagePrototype.add = function(key, value, noAssert) {
  7131. var field = T._fieldsByName[key];
  7132. if (!noAssert) {
  7133. if (!field)
  7134. throw Error(this+"#"+key+" is undefined");
  7135. if (!(field instanceof ProtoBuf.Reflect.Message.Field))
  7136. throw Error(this+"#"+key+" is not a field: "+field.toString(true)); // May throw if it's an enum or embedded message
  7137. if (!field.repeated)
  7138. throw Error(this+"#"+key+" is not a repeated field");
  7139. value = field.verifyValue(value, true);
  7140. }
  7141. if (this[key] === null)
  7142. this[key] = [];
  7143. this[key].push(value);
  7144. return this;
  7145. };
  7146. /**
  7147. * Adds a value to a repeated field. This is an alias for {@link ProtoBuf.Builder.Message#add}.
  7148. * @name ProtoBuf.Builder.Message#$add
  7149. * @function
  7150. * @param {string} key Field name
  7151. * @param {*} value Value to add
  7152. * @param {boolean=} noAssert Whether to assert the value or not (asserts by default)
  7153. * @returns {!ProtoBuf.Builder.Message} this
  7154. * @throws {Error} If the value cannot be added
  7155. * @expose
  7156. */
  7157. MessagePrototype.$add = MessagePrototype.add;
  7158. /**
  7159. * Sets a field's value.
  7160. * @name ProtoBuf.Builder.Message#set
  7161. * @function
  7162. * @param {string|!Object.<string,*>} keyOrObj String key or plain object holding multiple values
  7163. * @param {(*|boolean)=} value Value to set if key is a string, otherwise omitted
  7164. * @param {boolean=} noAssert Whether to not assert for an actual field / proper value type, defaults to `false`
  7165. * @returns {!ProtoBuf.Builder.Message} this
  7166. * @throws {Error} If the value cannot be set
  7167. * @expose
  7168. */
  7169. MessagePrototype.set = function(keyOrObj, value, noAssert) {
  7170. if (keyOrObj && typeof keyOrObj === 'object') {
  7171. noAssert = value;
  7172. for (var ikey in keyOrObj) {
  7173. // Check if virtual oneof field - don't set these
  7174. if (keyOrObj.hasOwnProperty(ikey) && typeof (value = keyOrObj[ikey]) !== 'undefined' && T._oneofsByName[ikey] === undefined)
  7175. this.$set(ikey, value, noAssert);
  7176. }
  7177. return this;
  7178. }
  7179. var field = T._fieldsByName[keyOrObj];
  7180. if (!noAssert) {
  7181. if (!field)
  7182. throw Error(this+"#"+keyOrObj+" is not a field: undefined");
  7183. if (!(field instanceof ProtoBuf.Reflect.Message.Field))
  7184. throw Error(this+"#"+keyOrObj+" is not a field: "+field.toString(true));
  7185. this[field.name] = (value = field.verifyValue(value)); // May throw
  7186. } else
  7187. this[keyOrObj] = value;
  7188. if (field && field.oneof) { // Field is part of an OneOf (not a virtual OneOf field)
  7189. var currentField = this[field.oneof.name]; // Virtual field references currently set field
  7190. if (value !== null) {
  7191. if (currentField !== null && currentField !== field.name)
  7192. this[currentField] = null; // Clear currently set field
  7193. this[field.oneof.name] = field.name; // Point virtual field at this field
  7194. } else if (/* value === null && */currentField === keyOrObj)
  7195. this[field.oneof.name] = null; // Clear virtual field (current field explicitly cleared)
  7196. }
  7197. return this;
  7198. };
  7199. /**
  7200. * Sets a field's value. This is an alias for [@link ProtoBuf.Builder.Message#set}.
  7201. * @name ProtoBuf.Builder.Message#$set
  7202. * @function
  7203. * @param {string|!Object.<string,*>} keyOrObj String key or plain object holding multiple values
  7204. * @param {(*|boolean)=} value Value to set if key is a string, otherwise omitted
  7205. * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
  7206. * @throws {Error} If the value cannot be set
  7207. * @expose
  7208. */
  7209. MessagePrototype.$set = MessagePrototype.set;
  7210. /**
  7211. * Gets a field's value.
  7212. * @name ProtoBuf.Builder.Message#get
  7213. * @function
  7214. * @param {string} key Key
  7215. * @param {boolean=} noAssert Whether to not assert for an actual field, defaults to `false`
  7216. * @return {*} Value
  7217. * @throws {Error} If there is no such field
  7218. * @expose
  7219. */
  7220. MessagePrototype.get = function(key, noAssert) {
  7221. if (noAssert)
  7222. return this[key];
  7223. var field = T._fieldsByName[key];
  7224. if (!field || !(field instanceof ProtoBuf.Reflect.Message.Field))
  7225. throw Error(this+"#"+key+" is not a field: undefined");
  7226. if (!(field instanceof ProtoBuf.Reflect.Message.Field))
  7227. throw Error(this+"#"+key+" is not a field: "+field.toString(true));
  7228. return this[field.name];
  7229. };
  7230. /**
  7231. * Gets a field's value. This is an alias for {@link ProtoBuf.Builder.Message#$get}.
  7232. * @name ProtoBuf.Builder.Message#$get
  7233. * @function
  7234. * @param {string} key Key
  7235. * @return {*} Value
  7236. * @throws {Error} If there is no such field
  7237. * @expose
  7238. */
  7239. MessagePrototype.$get = MessagePrototype.get;
  7240. // Getters and setters
  7241. for (var i=0; i<fields.length; i++) {
  7242. var field = fields[i];
  7243. // no setters for extension fields as these are named by their fqn
  7244. if (field instanceof ProtoBuf.Reflect.Message.ExtensionField)
  7245. continue;
  7246. if (T.builder.options['populateAccessors'])
  7247. (function(field) {
  7248. // set/get[SomeValue]
  7249. var Name = field.originalName.replace(/(_[a-zA-Z])/g, function(match) {
  7250. return match.toUpperCase().replace('_','');
  7251. });
  7252. Name = Name.substring(0,1).toUpperCase() + Name.substring(1);
  7253. // set/get_[some_value] FIXME: Do we really need these?
  7254. var name = field.originalName.replace(/([A-Z])/g, function(match) {
  7255. return "_"+match;
  7256. });
  7257. /**
  7258. * The current field's unbound setter function.
  7259. * @function
  7260. * @param {*} value
  7261. * @param {boolean=} noAssert
  7262. * @returns {!ProtoBuf.Builder.Message}
  7263. * @inner
  7264. */
  7265. var setter = function(value, noAssert) {
  7266. this[field.name] = noAssert ? value : field.verifyValue(value);
  7267. return this;
  7268. };
  7269. /**
  7270. * The current field's unbound getter function.
  7271. * @function
  7272. * @returns {*}
  7273. * @inner
  7274. */
  7275. var getter = function() {
  7276. return this[field.name];
  7277. };
  7278. if (T.getChild("set"+Name) === null)
  7279. /**
  7280. * Sets a value. This method is present for each field, but only if there is no name conflict with
  7281. * another field.
  7282. * @name ProtoBuf.Builder.Message#set[SomeField]
  7283. * @function
  7284. * @param {*} value Value to set
  7285. * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
  7286. * @returns {!ProtoBuf.Builder.Message} this
  7287. * @abstract
  7288. * @throws {Error} If the value cannot be set
  7289. */
  7290. MessagePrototype["set"+Name] = setter;
  7291. if (T.getChild("set_"+name) === null)
  7292. /**
  7293. * Sets a value. This method is present for each field, but only if there is no name conflict with
  7294. * another field.
  7295. * @name ProtoBuf.Builder.Message#set_[some_field]
  7296. * @function
  7297. * @param {*} value Value to set
  7298. * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
  7299. * @returns {!ProtoBuf.Builder.Message} this
  7300. * @abstract
  7301. * @throws {Error} If the value cannot be set
  7302. */
  7303. MessagePrototype["set_"+name] = setter;
  7304. if (T.getChild("get"+Name) === null)
  7305. /**
  7306. * Gets a value. This method is present for each field, but only if there is no name conflict with
  7307. * another field.
  7308. * @name ProtoBuf.Builder.Message#get[SomeField]
  7309. * @function
  7310. * @abstract
  7311. * @return {*} The value
  7312. */
  7313. MessagePrototype["get"+Name] = getter;
  7314. if (T.getChild("get_"+name) === null)
  7315. /**
  7316. * Gets a value. This method is present for each field, but only if there is no name conflict with
  7317. * another field.
  7318. * @name ProtoBuf.Builder.Message#get_[some_field]
  7319. * @function
  7320. * @return {*} The value
  7321. * @abstract
  7322. */
  7323. MessagePrototype["get_"+name] = getter;
  7324. })(field);
  7325. }
  7326. // En-/decoding
  7327. /**
  7328. * Encodes the message.
  7329. * @name ProtoBuf.Builder.Message#$encode
  7330. * @function
  7331. * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.
  7332. * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
  7333. * @return {!ByteBuffer} Encoded message as a ByteBuffer
  7334. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  7335. * returns the encoded ByteBuffer in the `encoded` property on the error.
  7336. * @expose
  7337. * @see ProtoBuf.Builder.Message#encode64
  7338. * @see ProtoBuf.Builder.Message#encodeHex
  7339. * @see ProtoBuf.Builder.Message#encodeAB
  7340. */
  7341. MessagePrototype.encode = function(buffer, noVerify) {
  7342. if (typeof buffer === 'boolean')
  7343. noVerify = buffer,
  7344. buffer = undefined;
  7345. var isNew = false;
  7346. if (!buffer)
  7347. buffer = new ByteBuffer(),
  7348. isNew = true;
  7349. var le = buffer.littleEndian;
  7350. try {
  7351. T.encode(this, buffer.LE(), noVerify);
  7352. return (isNew ? buffer.flip() : buffer).LE(le);
  7353. } catch (e) {
  7354. buffer.LE(le);
  7355. throw(e);
  7356. }
  7357. };
  7358. /**
  7359. * Encodes a message using the specified data payload.
  7360. * @param {!Object.<string,*>} data Data payload
  7361. * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.
  7362. * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
  7363. * @return {!ByteBuffer} Encoded message as a ByteBuffer
  7364. * @expose
  7365. */
  7366. Message.encode = function(data, buffer, noVerify) {
  7367. return new Message(data).encode(buffer, noVerify);
  7368. };
  7369. /**
  7370. * Calculates the byte length of the message.
  7371. * @name ProtoBuf.Builder.Message#calculate
  7372. * @function
  7373. * @returns {number} Byte length
  7374. * @throws {Error} If the message cannot be calculated or if required fields are missing.
  7375. * @expose
  7376. */
  7377. MessagePrototype.calculate = function() {
  7378. return T.calculate(this);
  7379. };
  7380. /**
  7381. * Encodes the varint32 length-delimited message.
  7382. * @name ProtoBuf.Builder.Message#encodeDelimited
  7383. * @function
  7384. * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.
  7385. * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
  7386. * @return {!ByteBuffer} Encoded message as a ByteBuffer
  7387. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  7388. * returns the encoded ByteBuffer in the `encoded` property on the error.
  7389. * @expose
  7390. */
  7391. MessagePrototype.encodeDelimited = function(buffer, noVerify) {
  7392. var isNew = false;
  7393. if (!buffer)
  7394. buffer = new ByteBuffer(),
  7395. isNew = true;
  7396. var enc = new ByteBuffer().LE();
  7397. T.encode(this, enc, noVerify).flip();
  7398. buffer.writeVarint32(enc.remaining());
  7399. buffer.append(enc);
  7400. return isNew ? buffer.flip() : buffer;
  7401. };
  7402. /**
  7403. * Directly encodes the message to an ArrayBuffer.
  7404. * @name ProtoBuf.Builder.Message#encodeAB
  7405. * @function
  7406. * @return {ArrayBuffer} Encoded message as ArrayBuffer
  7407. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  7408. * returns the encoded ArrayBuffer in the `encoded` property on the error.
  7409. * @expose
  7410. */
  7411. MessagePrototype.encodeAB = function() {
  7412. try {
  7413. return this.encode().toArrayBuffer();
  7414. } catch (e) {
  7415. if (e["encoded"]) e["encoded"] = e["encoded"].toArrayBuffer();
  7416. throw(e);
  7417. }
  7418. };
  7419. /**
  7420. * Returns the message as an ArrayBuffer. This is an alias for {@link ProtoBuf.Builder.Message#encodeAB}.
  7421. * @name ProtoBuf.Builder.Message#toArrayBuffer
  7422. * @function
  7423. * @return {ArrayBuffer} Encoded message as ArrayBuffer
  7424. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  7425. * returns the encoded ArrayBuffer in the `encoded` property on the error.
  7426. * @expose
  7427. */
  7428. MessagePrototype.toArrayBuffer = MessagePrototype.encodeAB;
  7429. /**
  7430. * Directly encodes the message to a node Buffer.
  7431. * @name ProtoBuf.Builder.Message#encodeNB
  7432. * @function
  7433. * @return {!Buffer}
  7434. * @throws {Error} If the message cannot be encoded, not running under node.js or if required fields are
  7435. * missing. The later still returns the encoded node Buffer in the `encoded` property on the error.
  7436. * @expose
  7437. */
  7438. MessagePrototype.encodeNB = function() {
  7439. try {
  7440. return this.encode().toBuffer();
  7441. } catch (e) {
  7442. if (e["encoded"]) e["encoded"] = e["encoded"].toBuffer();
  7443. throw(e);
  7444. }
  7445. };
  7446. /**
  7447. * Returns the message as a node Buffer. This is an alias for {@link ProtoBuf.Builder.Message#encodeNB}.
  7448. * @name ProtoBuf.Builder.Message#toBuffer
  7449. * @function
  7450. * @return {!Buffer}
  7451. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  7452. * returns the encoded node Buffer in the `encoded` property on the error.
  7453. * @expose
  7454. */
  7455. MessagePrototype.toBuffer = MessagePrototype.encodeNB;
  7456. /**
  7457. * Directly encodes the message to a base64 encoded string.
  7458. * @name ProtoBuf.Builder.Message#encode64
  7459. * @function
  7460. * @return {string} Base64 encoded string
  7461. * @throws {Error} If the underlying buffer cannot be encoded or if required fields are missing. The later
  7462. * still returns the encoded base64 string in the `encoded` property on the error.
  7463. * @expose
  7464. */
  7465. MessagePrototype.encode64 = function() {
  7466. try {
  7467. return this.encode().toBase64();
  7468. } catch (e) {
  7469. if (e["encoded"]) e["encoded"] = e["encoded"].toBase64();
  7470. throw(e);
  7471. }
  7472. };
  7473. /**
  7474. * Returns the message as a base64 encoded string. This is an alias for {@link ProtoBuf.Builder.Message#encode64}.
  7475. * @name ProtoBuf.Builder.Message#toBase64
  7476. * @function
  7477. * @return {string} Base64 encoded string
  7478. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  7479. * returns the encoded base64 string in the `encoded` property on the error.
  7480. * @expose
  7481. */
  7482. MessagePrototype.toBase64 = MessagePrototype.encode64;
  7483. /**
  7484. * Directly encodes the message to a hex encoded string.
  7485. * @name ProtoBuf.Builder.Message#encodeHex
  7486. * @function
  7487. * @return {string} Hex encoded string
  7488. * @throws {Error} If the underlying buffer cannot be encoded or if required fields are missing. The later
  7489. * still returns the encoded hex string in the `encoded` property on the error.
  7490. * @expose
  7491. */
  7492. MessagePrototype.encodeHex = function() {
  7493. try {
  7494. return this.encode().toHex();
  7495. } catch (e) {
  7496. if (e["encoded"]) e["encoded"] = e["encoded"].toHex();
  7497. throw(e);
  7498. }
  7499. };
  7500. /**
  7501. * Returns the message as a hex encoded string. This is an alias for {@link ProtoBuf.Builder.Message#encodeHex}.
  7502. * @name ProtoBuf.Builder.Message#toHex
  7503. * @function
  7504. * @return {string} Hex encoded string
  7505. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  7506. * returns the encoded hex string in the `encoded` property on the error.
  7507. * @expose
  7508. */
  7509. MessagePrototype.toHex = MessagePrototype.encodeHex;
  7510. /**
  7511. * Clones a message object or field value to a raw object.
  7512. * @param {*} obj Object to clone
  7513. * @param {boolean} binaryAsBase64 Whether to include binary data as base64 strings or as a buffer otherwise
  7514. * @param {boolean} longsAsStrings Whether to encode longs as strings
  7515. * @param {!ProtoBuf.Reflect.T=} resolvedType The resolved field type if a field
  7516. * @returns {*} Cloned object
  7517. * @inner
  7518. */
  7519. function cloneRaw(obj, binaryAsBase64, longsAsStrings, resolvedType) {
  7520. if (obj === null || typeof obj !== 'object') {
  7521. // Convert enum values to their respective names
  7522. if (resolvedType && resolvedType instanceof ProtoBuf.Reflect.Enum) {
  7523. var name = ProtoBuf.Reflect.Enum.getName(resolvedType.object, obj);
  7524. if (name !== null)
  7525. return name;
  7526. }
  7527. // Pass-through string, number, boolean, null...
  7528. return obj;
  7529. }
  7530. // Convert ByteBuffers to raw buffer or strings
  7531. if (ByteBuffer.isByteBuffer(obj))
  7532. return binaryAsBase64 ? obj.toBase64() : obj.toBuffer();
  7533. // Convert Longs to proper objects or strings
  7534. if (ProtoBuf.Long.isLong(obj))
  7535. return longsAsStrings ? obj.toString() : ProtoBuf.Long.fromValue(obj);
  7536. var clone;
  7537. // Clone arrays
  7538. if (Array.isArray(obj)) {
  7539. clone = [];
  7540. obj.forEach(function(v, k) {
  7541. clone[k] = cloneRaw(v, binaryAsBase64, longsAsStrings, resolvedType);
  7542. });
  7543. return clone;
  7544. }
  7545. clone = {};
  7546. // Convert maps to objects
  7547. if (obj instanceof ProtoBuf.Map) {
  7548. var it = obj.entries();
  7549. for (var e = it.next(); !e.done; e = it.next())
  7550. clone[obj.keyElem.valueToString(e.value[0])] = cloneRaw(e.value[1], binaryAsBase64, longsAsStrings, obj.valueElem.resolvedType);
  7551. return clone;
  7552. }
  7553. // Everything else is a non-null object
  7554. var type = obj.$type,
  7555. field = undefined;
  7556. for (var i in obj)
  7557. if (obj.hasOwnProperty(i)) {
  7558. if (type && (field = type.getChild(i)))
  7559. clone[i] = cloneRaw(obj[i], binaryAsBase64, longsAsStrings, field.resolvedType);
  7560. else
  7561. clone[i] = cloneRaw(obj[i], binaryAsBase64, longsAsStrings);
  7562. }
  7563. return clone;
  7564. }
  7565. /**
  7566. * Returns the message's raw payload.
  7567. * @param {boolean=} binaryAsBase64 Whether to include binary data as base64 strings instead of Buffers, defaults to `false`
  7568. * @param {boolean} longsAsStrings Whether to encode longs as strings
  7569. * @returns {Object.<string,*>} Raw payload
  7570. * @expose
  7571. */
  7572. MessagePrototype.toRaw = function(binaryAsBase64, longsAsStrings) {
  7573. return cloneRaw(this, !!binaryAsBase64, !!longsAsStrings, this.$type);
  7574. };
  7575. /**
  7576. * Encodes a message to JSON.
  7577. * @returns {string} JSON string
  7578. * @expose
  7579. */
  7580. MessagePrototype.encodeJSON = function() {
  7581. return JSON.stringify(
  7582. cloneRaw(this,
  7583. /* binary-as-base64 */ true,
  7584. /* longs-as-strings */ true,
  7585. this.$type
  7586. )
  7587. );
  7588. };
  7589. /**
  7590. * Decodes a message from the specified buffer or string.
  7591. * @name ProtoBuf.Builder.Message.decode
  7592. * @function
  7593. * @param {!ByteBuffer|!ArrayBuffer|!Buffer|string} buffer Buffer to decode from
  7594. * @param {(number|string)=} length Message length. Defaults to decode all the remainig data.
  7595. * @param {string=} enc Encoding if buffer is a string: hex, utf8 (not recommended), defaults to base64
  7596. * @return {!ProtoBuf.Builder.Message} Decoded message
  7597. * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
  7598. * returns the decoded message with missing fields in the `decoded` property on the error.
  7599. * @expose
  7600. * @see ProtoBuf.Builder.Message.decode64
  7601. * @see ProtoBuf.Builder.Message.decodeHex
  7602. */
  7603. Message.decode = function(buffer, length, enc) {
  7604. if (typeof length === 'string')
  7605. enc = length,
  7606. length = -1;
  7607. if (typeof buffer === 'string')
  7608. buffer = ByteBuffer.wrap(buffer, enc ? enc : "base64");
  7609. else if (!ByteBuffer.isByteBuffer(buffer))
  7610. buffer = ByteBuffer.wrap(buffer); // May throw
  7611. var le = buffer.littleEndian;
  7612. try {
  7613. var msg = T.decode(buffer.LE(), length);
  7614. buffer.LE(le);
  7615. return msg;
  7616. } catch (e) {
  7617. buffer.LE(le);
  7618. throw(e);
  7619. }
  7620. };
  7621. /**
  7622. * Decodes a varint32 length-delimited message from the specified buffer or string.
  7623. * @name ProtoBuf.Builder.Message.decodeDelimited
  7624. * @function
  7625. * @param {!ByteBuffer|!ArrayBuffer|!Buffer|string} buffer Buffer to decode from
  7626. * @param {string=} enc Encoding if buffer is a string: hex, utf8 (not recommended), defaults to base64
  7627. * @return {ProtoBuf.Builder.Message} Decoded message or `null` if not enough bytes are available yet
  7628. * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
  7629. * returns the decoded message with missing fields in the `decoded` property on the error.
  7630. * @expose
  7631. */
  7632. Message.decodeDelimited = function(buffer, enc) {
  7633. if (typeof buffer === 'string')
  7634. buffer = ByteBuffer.wrap(buffer, enc ? enc : "base64");
  7635. else if (!ByteBuffer.isByteBuffer(buffer))
  7636. buffer = ByteBuffer.wrap(buffer); // May throw
  7637. if (buffer.remaining() < 1)
  7638. return null;
  7639. var off = buffer.offset,
  7640. len = buffer.readVarint32();
  7641. if (buffer.remaining() < len) {
  7642. buffer.offset = off;
  7643. return null;
  7644. }
  7645. try {
  7646. var msg = T.decode(buffer.slice(buffer.offset, buffer.offset + len).LE());
  7647. buffer.offset += len;
  7648. return msg;
  7649. } catch (err) {
  7650. buffer.offset += len;
  7651. throw err;
  7652. }
  7653. };
  7654. /**
  7655. * Decodes the message from the specified base64 encoded string.
  7656. * @name ProtoBuf.Builder.Message.decode64
  7657. * @function
  7658. * @param {string} str String to decode from
  7659. * @return {!ProtoBuf.Builder.Message} Decoded message
  7660. * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
  7661. * returns the decoded message with missing fields in the `decoded` property on the error.
  7662. * @expose
  7663. */
  7664. Message.decode64 = function(str) {
  7665. return Message.decode(str, "base64");
  7666. };
  7667. /**
  7668. * Decodes the message from the specified hex encoded string.
  7669. * @name ProtoBuf.Builder.Message.decodeHex
  7670. * @function
  7671. * @param {string} str String to decode from
  7672. * @return {!ProtoBuf.Builder.Message} Decoded message
  7673. * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
  7674. * returns the decoded message with missing fields in the `decoded` property on the error.
  7675. * @expose
  7676. */
  7677. Message.decodeHex = function(str) {
  7678. return Message.decode(str, "hex");
  7679. };
  7680. /**
  7681. * Decodes the message from a JSON string.
  7682. * @name ProtoBuf.Builder.Message.decodeJSON
  7683. * @function
  7684. * @param {string} str String to decode from
  7685. * @return {!ProtoBuf.Builder.Message} Decoded message
  7686. * @throws {Error} If the message cannot be decoded or if required fields are
  7687. * missing.
  7688. * @expose
  7689. */
  7690. Message.decodeJSON = function(str) {
  7691. return new Message(JSON.parse(str));
  7692. };
  7693. // Utility
  7694. /**
  7695. * Returns a string representation of this Message.
  7696. * @name ProtoBuf.Builder.Message#toString
  7697. * @function
  7698. * @return {string} String representation as of ".Fully.Qualified.MessageName"
  7699. * @expose
  7700. */
  7701. MessagePrototype.toString = function() {
  7702. return T.toString();
  7703. };
  7704. if (Object.defineProperty)
  7705. Object.defineProperty(Message, '$options', { "value": T.buildOpt() }),
  7706. Object.defineProperty(MessagePrototype, "$options", { "value": Message["$options"] }),
  7707. Object.defineProperty(Message, "$type", { "value": T }),
  7708. Object.defineProperty(MessagePrototype, "$type", { "value": T });
  7709. return Message;
  7710. })(ProtoBuf, this);
  7711. // Static enums and prototyped sub-messages / cached collections
  7712. this._fields = [];
  7713. this._fieldsById = {};
  7714. this._fieldsByName = {};
  7715. this._oneofsByName = {};
  7716. for (var i=0, k=this.children.length, child; i<k; i++) {
  7717. child = this.children[i];
  7718. if (child instanceof Enum || child instanceof Message || child instanceof Service) {
  7719. if (clazz.hasOwnProperty(child.name))
  7720. throw Error("Illegal reflect child of "+this.toString(true)+": "+child.toString(true)+" cannot override static property '"+child.name+"'");
  7721. clazz[child.name] = child.build();
  7722. } else if (child instanceof Message.Field)
  7723. child.build(),
  7724. this._fields.push(child),
  7725. this._fieldsById[child.id] = child,
  7726. this._fieldsByName[child.name] = child;
  7727. else if (child instanceof Message.OneOf) {
  7728. this._oneofsByName[child.name] = child;
  7729. }
  7730. else if (!(child instanceof Message.OneOf) && !(child instanceof Extension)) // Not built
  7731. throw Error("Illegal reflect child of "+this.toString(true)+": "+this.children[i].toString(true));
  7732. }
  7733. return this.clazz = clazz;
  7734. };
  7735. /**
  7736. * Encodes a runtime message's contents to the specified buffer.
  7737. * @param {!ProtoBuf.Builder.Message} message Runtime message to encode
  7738. * @param {ByteBuffer} buffer ByteBuffer to write to
  7739. * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
  7740. * @return {ByteBuffer} The ByteBuffer for chaining
  7741. * @throws {Error} If required fields are missing or the message cannot be encoded for another reason
  7742. * @expose
  7743. */
  7744. MessagePrototype.encode = function(message, buffer, noVerify) {
  7745. var fieldMissing = null,
  7746. field;
  7747. for (var i=0, k=this._fields.length, val; i<k; ++i) {
  7748. field = this._fields[i];
  7749. val = message[field.name];
  7750. if (field.required && val === null) {
  7751. if (fieldMissing === null)
  7752. fieldMissing = field;
  7753. } else
  7754. field.encode(noVerify ? val : field.verifyValue(val), buffer, message);
  7755. }
  7756. if (fieldMissing !== null) {
  7757. var err = Error("Missing at least one required field for "+this.toString(true)+": "+fieldMissing);
  7758. err["encoded"] = buffer; // Still expose what we got
  7759. throw(err);
  7760. }
  7761. return buffer;
  7762. };
  7763. /**
  7764. * Calculates a runtime message's byte length.
  7765. * @param {!ProtoBuf.Builder.Message} message Runtime message to encode
  7766. * @returns {number} Byte length
  7767. * @throws {Error} If required fields are missing or the message cannot be calculated for another reason
  7768. * @expose
  7769. */
  7770. MessagePrototype.calculate = function(message) {
  7771. for (var n=0, i=0, k=this._fields.length, field, val; i<k; ++i) {
  7772. field = this._fields[i];
  7773. val = message[field.name];
  7774. if (field.required && val === null)
  7775. throw Error("Missing at least one required field for "+this.toString(true)+": "+field);
  7776. else
  7777. n += field.calculate(val, message);
  7778. }
  7779. return n;
  7780. };
  7781. /**
  7782. * Skips all data until the end of the specified group has been reached.
  7783. * @param {number} expectedId Expected GROUPEND id
  7784. * @param {!ByteBuffer} buf ByteBuffer
  7785. * @returns {boolean} `true` if a value as been skipped, `false` if the end has been reached
  7786. * @throws {Error} If it wasn't possible to find the end of the group (buffer overrun or end tag mismatch)
  7787. * @inner
  7788. */
  7789. function skipTillGroupEnd(expectedId, buf) {
  7790. var tag = buf.readVarint32(), // Throws on OOB
  7791. wireType = tag & 0x07,
  7792. id = tag >>> 3;
  7793. switch (wireType) {
  7794. case ProtoBuf.WIRE_TYPES.VARINT:
  7795. do tag = buf.readUint8();
  7796. while ((tag & 0x80) === 0x80);
  7797. break;
  7798. case ProtoBuf.WIRE_TYPES.BITS64:
  7799. buf.offset += 8;
  7800. break;
  7801. case ProtoBuf.WIRE_TYPES.LDELIM:
  7802. tag = buf.readVarint32(); // reads the varint
  7803. buf.offset += tag; // skips n bytes
  7804. break;
  7805. case ProtoBuf.WIRE_TYPES.STARTGROUP:
  7806. skipTillGroupEnd(id, buf);
  7807. break;
  7808. case ProtoBuf.WIRE_TYPES.ENDGROUP:
  7809. if (id === expectedId)
  7810. return false;
  7811. else
  7812. throw Error("Illegal GROUPEND after unknown group: "+id+" ("+expectedId+" expected)");
  7813. case ProtoBuf.WIRE_TYPES.BITS32:
  7814. buf.offset += 4;
  7815. break;
  7816. default:
  7817. throw Error("Illegal wire type in unknown group "+expectedId+": "+wireType);
  7818. }
  7819. return true;
  7820. }
  7821. /**
  7822. * Decodes an encoded message and returns the decoded message.
  7823. * @param {ByteBuffer} buffer ByteBuffer to decode from
  7824. * @param {number=} length Message length. Defaults to decode all remaining data.
  7825. * @param {number=} expectedGroupEndId Expected GROUPEND id if this is a legacy group
  7826. * @return {ProtoBuf.Builder.Message} Decoded message
  7827. * @throws {Error} If the message cannot be decoded
  7828. * @expose
  7829. */
  7830. MessagePrototype.decode = function(buffer, length, expectedGroupEndId) {
  7831. if (typeof length !== 'number')
  7832. length = -1;
  7833. var start = buffer.offset,
  7834. msg = new (this.clazz)(),
  7835. tag, wireType, id, field;
  7836. while (buffer.offset < start+length || (length === -1 && buffer.remaining() > 0)) {
  7837. tag = buffer.readVarint32();
  7838. wireType = tag & 0x07;
  7839. id = tag >>> 3;
  7840. if (wireType === ProtoBuf.WIRE_TYPES.ENDGROUP) {
  7841. if (id !== expectedGroupEndId)
  7842. throw Error("Illegal group end indicator for "+this.toString(true)+": "+id+" ("+(expectedGroupEndId ? expectedGroupEndId+" expected" : "not a group")+")");
  7843. break;
  7844. }
  7845. if (!(field = this._fieldsById[id])) {
  7846. // "messages created by your new code can be parsed by your old code: old binaries simply ignore the new field when parsing."
  7847. switch (wireType) {
  7848. case ProtoBuf.WIRE_TYPES.VARINT:
  7849. buffer.readVarint32();
  7850. break;
  7851. case ProtoBuf.WIRE_TYPES.BITS32:
  7852. buffer.offset += 4;
  7853. break;
  7854. case ProtoBuf.WIRE_TYPES.BITS64:
  7855. buffer.offset += 8;
  7856. break;
  7857. case ProtoBuf.WIRE_TYPES.LDELIM:
  7858. var len = buffer.readVarint32();
  7859. buffer.offset += len;
  7860. break;
  7861. case ProtoBuf.WIRE_TYPES.STARTGROUP:
  7862. while (skipTillGroupEnd(id, buffer)) {}
  7863. break;
  7864. default:
  7865. throw Error("Illegal wire type for unknown field "+id+" in "+this.toString(true)+"#decode: "+wireType);
  7866. }
  7867. continue;
  7868. }
  7869. if (field.repeated && !field.options["packed"]) {
  7870. msg[field.name].push(field.decode(wireType, buffer));
  7871. } else if (field.map) {
  7872. var keyval = field.decode(wireType, buffer);
  7873. msg[field.name].set(keyval[0], keyval[1]);
  7874. } else {
  7875. msg[field.name] = field.decode(wireType, buffer);
  7876. if (field.oneof) { // Field is part of an OneOf (not a virtual OneOf field)
  7877. var currentField = msg[field.oneof.name]; // Virtual field references currently set field
  7878. if (currentField !== null && currentField !== field.name)
  7879. msg[currentField] = null; // Clear currently set field
  7880. msg[field.oneof.name] = field.name; // Point virtual field at this field
  7881. }
  7882. }
  7883. }
  7884. // Check if all required fields are present and set default values for optional fields that are not
  7885. for (var i=0, k=this._fields.length; i<k; ++i) {
  7886. field = this._fields[i];
  7887. if (msg[field.name] === null) {
  7888. if (this.syntax === "proto3") { // Proto3 sets default values by specification
  7889. msg[field.name] = field.defaultValue;
  7890. } else if (field.required) {
  7891. var err = Error("Missing at least one required field for " + this.toString(true) + ": " + field.name);
  7892. err["decoded"] = msg; // Still expose what we got
  7893. throw(err);
  7894. } else if (ProtoBuf.populateDefaults && field.defaultValue !== null)
  7895. msg[field.name] = field.defaultValue;
  7896. }
  7897. }
  7898. return msg;
  7899. };
  7900. /**
  7901. * @alias ProtoBuf.Reflect.Message
  7902. * @expose
  7903. */
  7904. Reflect.Message = Message;
  7905. /**
  7906. * Constructs a new Message Field.
  7907. * @exports ProtoBuf.Reflect.Message.Field
  7908. * @param {!ProtoBuf.Builder} builder Builder reference
  7909. * @param {!ProtoBuf.Reflect.Message} message Message reference
  7910. * @param {string} rule Rule, one of requried, optional, repeated
  7911. * @param {string?} keytype Key data type, if any.
  7912. * @param {string} type Data type, e.g. int32
  7913. * @param {string} name Field name
  7914. * @param {number} id Unique field id
  7915. * @param {Object.<string,*>=} options Options
  7916. * @param {!ProtoBuf.Reflect.Message.OneOf=} oneof Enclosing OneOf
  7917. * @param {string?} syntax The syntax level of this definition (e.g., proto3)
  7918. * @constructor
  7919. * @extends ProtoBuf.Reflect.T
  7920. */
  7921. var Field = function(builder, message, rule, keytype, type, name, id, options, oneof, syntax) {
  7922. T.call(this, builder, message, name);
  7923. /**
  7924. * @override
  7925. */
  7926. this.className = "Message.Field";
  7927. /**
  7928. * Message field required flag.
  7929. * @type {boolean}
  7930. * @expose
  7931. */
  7932. this.required = rule === "required";
  7933. /**
  7934. * Message field repeated flag.
  7935. * @type {boolean}
  7936. * @expose
  7937. */
  7938. this.repeated = rule === "repeated";
  7939. /**
  7940. * Message field map flag.
  7941. * @type {boolean}
  7942. * @expose
  7943. */
  7944. this.map = rule === "map";
  7945. /**
  7946. * Message field key type. Type reference string if unresolved, protobuf
  7947. * type if resolved. Valid only if this.map === true, null otherwise.
  7948. * @type {string|{name: string, wireType: number}|null}
  7949. * @expose
  7950. */
  7951. this.keyType = keytype || null;
  7952. /**
  7953. * Message field type. Type reference string if unresolved, protobuf type if
  7954. * resolved. In a map field, this is the value type.
  7955. * @type {string|{name: string, wireType: number}}
  7956. * @expose
  7957. */
  7958. this.type = type;
  7959. /**
  7960. * Resolved type reference inside the global namespace.
  7961. * @type {ProtoBuf.Reflect.T|null}
  7962. * @expose
  7963. */
  7964. this.resolvedType = null;
  7965. /**
  7966. * Unique message field id.
  7967. * @type {number}
  7968. * @expose
  7969. */
  7970. this.id = id;
  7971. /**
  7972. * Message field options.
  7973. * @type {!Object.<string,*>}
  7974. * @dict
  7975. * @expose
  7976. */
  7977. this.options = options || {};
  7978. /**
  7979. * Default value.
  7980. * @type {*}
  7981. * @expose
  7982. */
  7983. this.defaultValue = null;
  7984. /**
  7985. * Enclosing OneOf.
  7986. * @type {?ProtoBuf.Reflect.Message.OneOf}
  7987. * @expose
  7988. */
  7989. this.oneof = oneof || null;
  7990. /**
  7991. * Syntax level of this definition (e.g., proto3).
  7992. * @type {string}
  7993. * @expose
  7994. */
  7995. this.syntax = syntax || 'proto2';
  7996. /**
  7997. * Original field name.
  7998. * @type {string}
  7999. * @expose
  8000. */
  8001. this.originalName = this.name; // Used to revert camelcase transformation on naming collisions
  8002. /**
  8003. * Element implementation. Created in build() after types are resolved.
  8004. * @type {ProtoBuf.Element}
  8005. * @expose
  8006. */
  8007. this.element = null;
  8008. /**
  8009. * Key element implementation, for map fields. Created in build() after
  8010. * types are resolved.
  8011. * @type {ProtoBuf.Element}
  8012. * @expose
  8013. */
  8014. this.keyElement = null;
  8015. // Convert field names to camel case notation if the override is set
  8016. if (this.builder.options['convertFieldsToCamelCase'] && !(this instanceof Message.ExtensionField))
  8017. this.name = ProtoBuf.Util.toCamelCase(this.name);
  8018. };
  8019. /**
  8020. * @alias ProtoBuf.Reflect.Message.Field.prototype
  8021. * @inner
  8022. */
  8023. var FieldPrototype = Field.prototype = Object.create(T.prototype);
  8024. /**
  8025. * Builds the field.
  8026. * @override
  8027. * @expose
  8028. */
  8029. FieldPrototype.build = function() {
  8030. this.element = new Element(this.type, this.resolvedType, false, this.syntax, this.name);
  8031. if (this.map)
  8032. this.keyElement = new Element(this.keyType, undefined, true, this.syntax, this.name);
  8033. // In proto3, fields do not have field presence, and every field is set to
  8034. // its type's default value ("", 0, 0.0, or false).
  8035. if (this.syntax === 'proto3' && !this.repeated && !this.map)
  8036. this.defaultValue = Element.defaultFieldValue(this.type);
  8037. // Otherwise, default values are present when explicitly specified
  8038. else if (typeof this.options['default'] !== 'undefined')
  8039. this.defaultValue = this.verifyValue(this.options['default']);
  8040. };
  8041. /**
  8042. * Checks if the given value can be set for this field.
  8043. * @param {*} value Value to check
  8044. * @param {boolean=} skipRepeated Whether to skip the repeated value check or not. Defaults to false.
  8045. * @return {*} Verified, maybe adjusted, value
  8046. * @throws {Error} If the value cannot be set for this field
  8047. * @expose
  8048. */
  8049. FieldPrototype.verifyValue = function(value, skipRepeated) {
  8050. skipRepeated = skipRepeated || false;
  8051. var self = this;
  8052. function fail(val, msg) {
  8053. throw Error("Illegal value for "+self.toString(true)+" of type "+self.type.name+": "+val+" ("+msg+")");
  8054. }
  8055. if (value === null) { // NULL values for optional fields
  8056. if (this.required)
  8057. fail(typeof value, "required");
  8058. if (this.syntax === 'proto3' && this.type !== ProtoBuf.TYPES["message"])
  8059. fail(typeof value, "proto3 field without field presence cannot be null");
  8060. return null;
  8061. }
  8062. var i;
  8063. if (this.repeated && !skipRepeated) { // Repeated values as arrays
  8064. if (!Array.isArray(value))
  8065. value = [value];
  8066. var res = [];
  8067. for (i=0; i<value.length; i++)
  8068. res.push(this.element.verifyValue(value[i]));
  8069. return res;
  8070. }
  8071. if (this.map && !skipRepeated) { // Map values as objects
  8072. if (!(value instanceof ProtoBuf.Map)) {
  8073. // If not already a Map, attempt to convert.
  8074. if (!(value instanceof Object)) {
  8075. fail(typeof value,
  8076. "expected ProtoBuf.Map or raw object for map field");
  8077. }
  8078. return new ProtoBuf.Map(this, value);
  8079. } else {
  8080. return value;
  8081. }
  8082. }
  8083. // All non-repeated fields expect no array
  8084. if (!this.repeated && Array.isArray(value))
  8085. fail(typeof value, "no array expected");
  8086. return this.element.verifyValue(value);
  8087. };
  8088. /**
  8089. * Determines whether the field will have a presence on the wire given its
  8090. * value.
  8091. * @param {*} value Verified field value
  8092. * @param {!ProtoBuf.Builder.Message} message Runtime message
  8093. * @return {boolean} Whether the field will be present on the wire
  8094. */
  8095. FieldPrototype.hasWirePresence = function(value, message) {
  8096. if (this.syntax !== 'proto3')
  8097. return (value !== null);
  8098. if (this.oneof && message[this.oneof.name] === this.name)
  8099. return true;
  8100. switch (this.type) {
  8101. case ProtoBuf.TYPES["int32"]:
  8102. case ProtoBuf.TYPES["sint32"]:
  8103. case ProtoBuf.TYPES["sfixed32"]:
  8104. case ProtoBuf.TYPES["uint32"]:
  8105. case ProtoBuf.TYPES["fixed32"]:
  8106. return value !== 0;
  8107. case ProtoBuf.TYPES["int64"]:
  8108. case ProtoBuf.TYPES["sint64"]:
  8109. case ProtoBuf.TYPES["sfixed64"]:
  8110. case ProtoBuf.TYPES["uint64"]:
  8111. case ProtoBuf.TYPES["fixed64"]:
  8112. return value.low !== 0 || value.high !== 0;
  8113. case ProtoBuf.TYPES["bool"]:
  8114. return value;
  8115. case ProtoBuf.TYPES["float"]:
  8116. case ProtoBuf.TYPES["double"]:
  8117. return value !== 0.0;
  8118. case ProtoBuf.TYPES["string"]:
  8119. return value.length > 0;
  8120. case ProtoBuf.TYPES["bytes"]:
  8121. return value.remaining() > 0;
  8122. case ProtoBuf.TYPES["enum"]:
  8123. return value !== 0;
  8124. case ProtoBuf.TYPES["message"]:
  8125. return value !== null;
  8126. default:
  8127. return true;
  8128. }
  8129. };
  8130. /**
  8131. * Encodes the specified field value to the specified buffer.
  8132. * @param {*} value Verified field value
  8133. * @param {ByteBuffer} buffer ByteBuffer to encode to
  8134. * @param {!ProtoBuf.Builder.Message} message Runtime message
  8135. * @return {ByteBuffer} The ByteBuffer for chaining
  8136. * @throws {Error} If the field cannot be encoded
  8137. * @expose
  8138. */
  8139. FieldPrototype.encode = function(value, buffer, message) {
  8140. if (this.type === null || typeof this.type !== 'object')
  8141. throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);
  8142. if (value === null || (this.repeated && value.length == 0))
  8143. return buffer; // Optional omitted
  8144. try {
  8145. if (this.repeated) {
  8146. var i;
  8147. // "Only repeated fields of primitive numeric types (types which use the varint, 32-bit, or 64-bit wire
  8148. // types) can be declared 'packed'."
  8149. if (this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {
  8150. // "All of the elements of the field are packed into a single key-value pair with wire type 2
  8151. // (length-delimited). Each element is encoded the same way it would be normally, except without a
  8152. // tag preceding it."
  8153. buffer.writeVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
  8154. buffer.ensureCapacity(buffer.offset += 1); // We do not know the length yet, so let's assume a varint of length 1
  8155. var start = buffer.offset; // Remember where the contents begin
  8156. for (i=0; i<value.length; i++)
  8157. this.element.encodeValue(this.id, value[i], buffer);
  8158. var len = buffer.offset-start,
  8159. varintLen = ByteBuffer.calculateVarint32(len);
  8160. if (varintLen > 1) { // We need to move the contents
  8161. var contents = buffer.slice(start, buffer.offset);
  8162. start += varintLen-1;
  8163. buffer.offset = start;
  8164. buffer.append(contents);
  8165. }
  8166. buffer.writeVarint32(len, start-varintLen);
  8167. } else {
  8168. // "If your message definition has repeated elements (without the [packed=true] option), the encoded
  8169. // message has zero or more key-value pairs with the same tag number"
  8170. for (i=0; i<value.length; i++)
  8171. buffer.writeVarint32((this.id << 3) | this.type.wireType),
  8172. this.element.encodeValue(this.id, value[i], buffer);
  8173. }
  8174. } else if (this.map) {
  8175. // Write out each map entry as a submessage.
  8176. value.forEach(function(val, key, m) {
  8177. // Compute the length of the submessage (key, val) pair.
  8178. var length =
  8179. ByteBuffer.calculateVarint32((1 << 3) | this.keyType.wireType) +
  8180. this.keyElement.calculateLength(1, key) +
  8181. ByteBuffer.calculateVarint32((2 << 3) | this.type.wireType) +
  8182. this.element.calculateLength(2, val);
  8183. // Submessage with wire type of length-delimited.
  8184. buffer.writeVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
  8185. buffer.writeVarint32(length);
  8186. // Write out the key and val.
  8187. buffer.writeVarint32((1 << 3) | this.keyType.wireType);
  8188. this.keyElement.encodeValue(1, key, buffer);
  8189. buffer.writeVarint32((2 << 3) | this.type.wireType);
  8190. this.element.encodeValue(2, val, buffer);
  8191. }, this);
  8192. } else {
  8193. if (this.hasWirePresence(value, message)) {
  8194. buffer.writeVarint32((this.id << 3) | this.type.wireType);
  8195. this.element.encodeValue(this.id, value, buffer);
  8196. }
  8197. }
  8198. } catch (e) {
  8199. throw Error("Illegal value for "+this.toString(true)+": "+value+" ("+e+")");
  8200. }
  8201. return buffer;
  8202. };
  8203. /**
  8204. * Calculates the length of this field's value on the network level.
  8205. * @param {*} value Field value
  8206. * @param {!ProtoBuf.Builder.Message} message Runtime message
  8207. * @returns {number} Byte length
  8208. * @expose
  8209. */
  8210. FieldPrototype.calculate = function(value, message) {
  8211. value = this.verifyValue(value); // May throw
  8212. if (this.type === null || typeof this.type !== 'object')
  8213. throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);
  8214. if (value === null || (this.repeated && value.length == 0))
  8215. return 0; // Optional omitted
  8216. var n = 0;
  8217. try {
  8218. if (this.repeated) {
  8219. var i, ni;
  8220. if (this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {
  8221. n += ByteBuffer.calculateVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
  8222. ni = 0;
  8223. for (i=0; i<value.length; i++)
  8224. ni += this.element.calculateLength(this.id, value[i]);
  8225. n += ByteBuffer.calculateVarint32(ni);
  8226. n += ni;
  8227. } else {
  8228. for (i=0; i<value.length; i++)
  8229. n += ByteBuffer.calculateVarint32((this.id << 3) | this.type.wireType),
  8230. n += this.element.calculateLength(this.id, value[i]);
  8231. }
  8232. } else if (this.map) {
  8233. // Each map entry becomes a submessage.
  8234. value.forEach(function(val, key, m) {
  8235. // Compute the length of the submessage (key, val) pair.
  8236. var length =
  8237. ByteBuffer.calculateVarint32((1 << 3) | this.keyType.wireType) +
  8238. this.keyElement.calculateLength(1, key) +
  8239. ByteBuffer.calculateVarint32((2 << 3) | this.type.wireType) +
  8240. this.element.calculateLength(2, val);
  8241. n += ByteBuffer.calculateVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
  8242. n += ByteBuffer.calculateVarint32(length);
  8243. n += length;
  8244. }, this);
  8245. } else {
  8246. if (this.hasWirePresence(value, message)) {
  8247. n += ByteBuffer.calculateVarint32((this.id << 3) | this.type.wireType);
  8248. n += this.element.calculateLength(this.id, value);
  8249. }
  8250. }
  8251. } catch (e) {
  8252. throw Error("Illegal value for "+this.toString(true)+": "+value+" ("+e+")");
  8253. }
  8254. return n;
  8255. };
  8256. /**
  8257. * Decode the field value from the specified buffer.
  8258. * @param {number} wireType Leading wire type
  8259. * @param {ByteBuffer} buffer ByteBuffer to decode from
  8260. * @param {boolean=} skipRepeated Whether to skip the repeated check or not. Defaults to false.
  8261. * @return {*} Decoded value: array for packed repeated fields, [key, value] for
  8262. * map fields, or an individual value otherwise.
  8263. * @throws {Error} If the field cannot be decoded
  8264. * @expose
  8265. */
  8266. FieldPrototype.decode = function(wireType, buffer, skipRepeated) {
  8267. var value, nBytes;
  8268. // We expect wireType to match the underlying type's wireType unless we see
  8269. // a packed repeated field, or unless this is a map field.
  8270. var wireTypeOK =
  8271. (!this.map && wireType == this.type.wireType) ||
  8272. (!skipRepeated && this.repeated && this.options["packed"] &&
  8273. wireType == ProtoBuf.WIRE_TYPES.LDELIM) ||
  8274. (this.map && wireType == ProtoBuf.WIRE_TYPES.LDELIM);
  8275. if (!wireTypeOK)
  8276. throw Error("Illegal wire type for field "+this.toString(true)+": "+wireType+" ("+this.type.wireType+" expected)");
  8277. // Handle packed repeated fields.
  8278. if (wireType == ProtoBuf.WIRE_TYPES.LDELIM && this.repeated && this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {
  8279. if (!skipRepeated) {
  8280. nBytes = buffer.readVarint32();
  8281. nBytes = buffer.offset + nBytes; // Limit
  8282. var values = [];
  8283. while (buffer.offset < nBytes)
  8284. values.push(this.decode(this.type.wireType, buffer, true));
  8285. return values;
  8286. }
  8287. // Read the next value otherwise...
  8288. }
  8289. // Handle maps.
  8290. if (this.map) {
  8291. // Read one (key, value) submessage, and return [key, value]
  8292. var key = Element.defaultFieldValue(this.keyType);
  8293. value = Element.defaultFieldValue(this.type);
  8294. // Read the length
  8295. nBytes = buffer.readVarint32();
  8296. if (buffer.remaining() < nBytes)
  8297. throw Error("Illegal number of bytes for "+this.toString(true)+": "+nBytes+" required but got only "+buffer.remaining());
  8298. // Get a sub-buffer of this key/value submessage
  8299. var msgbuf = buffer.clone();
  8300. msgbuf.limit = msgbuf.offset + nBytes;
  8301. buffer.offset += nBytes;
  8302. while (msgbuf.remaining() > 0) {
  8303. var tag = msgbuf.readVarint32();
  8304. wireType = tag & 0x07;
  8305. var id = tag >>> 3;
  8306. if (id === 1) {
  8307. key = this.keyElement.decode(msgbuf, wireType, id);
  8308. } else if (id === 2) {
  8309. value = this.element.decode(msgbuf, wireType, id);
  8310. } else {
  8311. throw Error("Unexpected tag in map field key/value submessage");
  8312. }
  8313. }
  8314. return [key, value];
  8315. }
  8316. // Handle singular and non-packed repeated field values.
  8317. return this.element.decode(buffer, wireType, this.id);
  8318. };
  8319. /**
  8320. * @alias ProtoBuf.Reflect.Message.Field
  8321. * @expose
  8322. */
  8323. Reflect.Message.Field = Field;
  8324. /**
  8325. * Constructs a new Message ExtensionField.
  8326. * @exports ProtoBuf.Reflect.Message.ExtensionField
  8327. * @param {!ProtoBuf.Builder} builder Builder reference
  8328. * @param {!ProtoBuf.Reflect.Message} message Message reference
  8329. * @param {string} rule Rule, one of requried, optional, repeated
  8330. * @param {string} type Data type, e.g. int32
  8331. * @param {string} name Field name
  8332. * @param {number} id Unique field id
  8333. * @param {!Object.<string,*>=} options Options
  8334. * @constructor
  8335. * @extends ProtoBuf.Reflect.Message.Field
  8336. */
  8337. var ExtensionField = function(builder, message, rule, type, name, id, options) {
  8338. Field.call(this, builder, message, rule, /* keytype = */ null, type, name, id, options);
  8339. /**
  8340. * Extension reference.
  8341. * @type {!ProtoBuf.Reflect.Extension}
  8342. * @expose
  8343. */
  8344. this.extension;
  8345. };
  8346. // Extends Field
  8347. ExtensionField.prototype = Object.create(Field.prototype);
  8348. /**
  8349. * @alias ProtoBuf.Reflect.Message.ExtensionField
  8350. * @expose
  8351. */
  8352. Reflect.Message.ExtensionField = ExtensionField;
  8353. /**
  8354. * Constructs a new Message OneOf.
  8355. * @exports ProtoBuf.Reflect.Message.OneOf
  8356. * @param {!ProtoBuf.Builder} builder Builder reference
  8357. * @param {!ProtoBuf.Reflect.Message} message Message reference
  8358. * @param {string} name OneOf name
  8359. * @constructor
  8360. * @extends ProtoBuf.Reflect.T
  8361. */
  8362. var OneOf = function(builder, message, name) {
  8363. T.call(this, builder, message, name);
  8364. /**
  8365. * Enclosed fields.
  8366. * @type {!Array.<!ProtoBuf.Reflect.Message.Field>}
  8367. * @expose
  8368. */
  8369. this.fields = [];
  8370. };
  8371. /**
  8372. * @alias ProtoBuf.Reflect.Message.OneOf
  8373. * @expose
  8374. */
  8375. Reflect.Message.OneOf = OneOf;
  8376. /**
  8377. * Constructs a new Enum.
  8378. * @exports ProtoBuf.Reflect.Enum
  8379. * @param {!ProtoBuf.Builder} builder Builder reference
  8380. * @param {!ProtoBuf.Reflect.T} parent Parent Reflect object
  8381. * @param {string} name Enum name
  8382. * @param {Object.<string,*>=} options Enum options
  8383. * @param {string?} syntax The syntax level (e.g., proto3)
  8384. * @constructor
  8385. * @extends ProtoBuf.Reflect.Namespace
  8386. */
  8387. var Enum = function(builder, parent, name, options, syntax) {
  8388. Namespace.call(this, builder, parent, name, options, syntax);
  8389. /**
  8390. * @override
  8391. */
  8392. this.className = "Enum";
  8393. /**
  8394. * Runtime enum object.
  8395. * @type {Object.<string,number>|null}
  8396. * @expose
  8397. */
  8398. this.object = null;
  8399. };
  8400. /**
  8401. * Gets the string name of an enum value.
  8402. * @param {!ProtoBuf.Builder.Enum} enm Runtime enum
  8403. * @param {number} value Enum value
  8404. * @returns {?string} Name or `null` if not present
  8405. * @expose
  8406. */
  8407. Enum.getName = function(enm, value) {
  8408. var keys = Object.keys(enm);
  8409. for (var i=0, key; i<keys.length; ++i)
  8410. if (enm[key = keys[i]] === value)
  8411. return key;
  8412. return null;
  8413. };
  8414. /**
  8415. * @alias ProtoBuf.Reflect.Enum.prototype
  8416. * @inner
  8417. */
  8418. var EnumPrototype = Enum.prototype = Object.create(Namespace.prototype);
  8419. /**
  8420. * Builds this enum and returns the runtime counterpart.
  8421. * @param {boolean} rebuild Whether to rebuild or not, defaults to false
  8422. * @returns {!Object.<string,number>}
  8423. * @expose
  8424. */
  8425. EnumPrototype.build = function(rebuild) {
  8426. if (this.object && !rebuild)
  8427. return this.object;
  8428. var enm = new ProtoBuf.Builder.Enum(),
  8429. values = this.getChildren(Enum.Value);
  8430. for (var i=0, k=values.length; i<k; ++i)
  8431. enm[values[i]['name']] = values[i]['id'];
  8432. if (Object.defineProperty)
  8433. Object.defineProperty(enm, '$options', {
  8434. "value": this.buildOpt(),
  8435. "enumerable": false
  8436. });
  8437. return this.object = enm;
  8438. };
  8439. /**
  8440. * @alias ProtoBuf.Reflect.Enum
  8441. * @expose
  8442. */
  8443. Reflect.Enum = Enum;
  8444. /**
  8445. * Constructs a new Enum Value.
  8446. * @exports ProtoBuf.Reflect.Enum.Value
  8447. * @param {!ProtoBuf.Builder} builder Builder reference
  8448. * @param {!ProtoBuf.Reflect.Enum} enm Enum reference
  8449. * @param {string} name Field name
  8450. * @param {number} id Unique field id
  8451. * @constructor
  8452. * @extends ProtoBuf.Reflect.T
  8453. */
  8454. var Value = function(builder, enm, name, id) {
  8455. T.call(this, builder, enm, name);
  8456. /**
  8457. * @override
  8458. */
  8459. this.className = "Enum.Value";
  8460. /**
  8461. * Unique enum value id.
  8462. * @type {number}
  8463. * @expose
  8464. */
  8465. this.id = id;
  8466. };
  8467. // Extends T
  8468. Value.prototype = Object.create(T.prototype);
  8469. /**
  8470. * @alias ProtoBuf.Reflect.Enum.Value
  8471. * @expose
  8472. */
  8473. Reflect.Enum.Value = Value;
  8474. /**
  8475. * An extension (field).
  8476. * @exports ProtoBuf.Reflect.Extension
  8477. * @constructor
  8478. * @param {!ProtoBuf.Builder} builder Builder reference
  8479. * @param {!ProtoBuf.Reflect.T} parent Parent object
  8480. * @param {string} name Object name
  8481. * @param {!ProtoBuf.Reflect.Message.Field} field Extension field
  8482. */
  8483. var Extension = function(builder, parent, name, field) {
  8484. T.call(this, builder, parent, name);
  8485. /**
  8486. * Extended message field.
  8487. * @type {!ProtoBuf.Reflect.Message.Field}
  8488. * @expose
  8489. */
  8490. this.field = field;
  8491. };
  8492. // Extends T
  8493. Extension.prototype = Object.create(T.prototype);
  8494. /**
  8495. * @alias ProtoBuf.Reflect.Extension
  8496. * @expose
  8497. */
  8498. Reflect.Extension = Extension;
  8499. /**
  8500. * Constructs a new Service.
  8501. * @exports ProtoBuf.Reflect.Service
  8502. * @param {!ProtoBuf.Builder} builder Builder reference
  8503. * @param {!ProtoBuf.Reflect.Namespace} root Root
  8504. * @param {string} name Service name
  8505. * @param {Object.<string,*>=} options Options
  8506. * @constructor
  8507. * @extends ProtoBuf.Reflect.Namespace
  8508. */
  8509. var Service = function(builder, root, name, options) {
  8510. Namespace.call(this, builder, root, name, options);
  8511. /**
  8512. * @override
  8513. */
  8514. this.className = "Service";
  8515. /**
  8516. * Built runtime service class.
  8517. * @type {?function(new:ProtoBuf.Builder.Service)}
  8518. */
  8519. this.clazz = null;
  8520. };
  8521. /**
  8522. * @alias ProtoBuf.Reflect.Service.prototype
  8523. * @inner
  8524. */
  8525. var ServicePrototype = Service.prototype = Object.create(Namespace.prototype);
  8526. /**
  8527. * Builds the service and returns the runtime counterpart, which is a fully functional class.
  8528. * @see ProtoBuf.Builder.Service
  8529. * @param {boolean=} rebuild Whether to rebuild or not
  8530. * @return {Function} Service class
  8531. * @throws {Error} If the message cannot be built
  8532. * @expose
  8533. */
  8534. ServicePrototype.build = function(rebuild) {
  8535. if (this.clazz && !rebuild)
  8536. return this.clazz;
  8537. // Create the runtime Service class in its own scope
  8538. return this.clazz = (function(ProtoBuf, T) {
  8539. /**
  8540. * Constructs a new runtime Service.
  8541. * @name ProtoBuf.Builder.Service
  8542. * @param {function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))=} rpcImpl RPC implementation receiving the method name and the message
  8543. * @class Barebone of all runtime services.
  8544. * @constructor
  8545. * @throws {Error} If the service cannot be created
  8546. */
  8547. var Service = function(rpcImpl) {
  8548. ProtoBuf.Builder.Service.call(this);
  8549. /**
  8550. * Service implementation.
  8551. * @name ProtoBuf.Builder.Service#rpcImpl
  8552. * @type {!function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))}
  8553. * @expose
  8554. */
  8555. this.rpcImpl = rpcImpl || function(name, msg, callback) {
  8556. // This is what a user has to implement: A function receiving the method name, the actual message to
  8557. // send (type checked) and the callback that's either provided with the error as its first
  8558. // argument or null and the actual response message.
  8559. setTimeout(callback.bind(this, Error("Not implemented, see: https://github.com/dcodeIO/ProtoBuf.js/wiki/Services")), 0); // Must be async!
  8560. };
  8561. };
  8562. /**
  8563. * @alias ProtoBuf.Builder.Service.prototype
  8564. * @inner
  8565. */
  8566. var ServicePrototype = Service.prototype = Object.create(ProtoBuf.Builder.Service.prototype);
  8567. /**
  8568. * Asynchronously performs an RPC call using the given RPC implementation.
  8569. * @name ProtoBuf.Builder.Service.[Method]
  8570. * @function
  8571. * @param {!function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))} rpcImpl RPC implementation
  8572. * @param {ProtoBuf.Builder.Message} req Request
  8573. * @param {function(Error, (ProtoBuf.Builder.Message|ByteBuffer|Buffer|string)=)} callback Callback receiving
  8574. * the error if any and the response either as a pre-parsed message or as its raw bytes
  8575. * @abstract
  8576. */
  8577. /**
  8578. * Asynchronously performs an RPC call using the instance's RPC implementation.
  8579. * @name ProtoBuf.Builder.Service#[Method]
  8580. * @function
  8581. * @param {ProtoBuf.Builder.Message} req Request
  8582. * @param {function(Error, (ProtoBuf.Builder.Message|ByteBuffer|Buffer|string)=)} callback Callback receiving
  8583. * the error if any and the response either as a pre-parsed message or as its raw bytes
  8584. * @abstract
  8585. */
  8586. var rpc = T.getChildren(ProtoBuf.Reflect.Service.RPCMethod);
  8587. for (var i=0; i<rpc.length; i++) {
  8588. (function(method) {
  8589. // service#Method(message, callback)
  8590. ServicePrototype[method.name] = function(req, callback) {
  8591. try {
  8592. try {
  8593. // If given as a buffer, decode the request. Will throw a TypeError if not a valid buffer.
  8594. req = method.resolvedRequestType.clazz.decode(ByteBuffer.wrap(req));
  8595. } catch (err) {
  8596. if (!(err instanceof TypeError))
  8597. throw err;
  8598. }
  8599. if (req === null || typeof req !== 'object')
  8600. throw Error("Illegal arguments");
  8601. if (!(req instanceof method.resolvedRequestType.clazz))
  8602. req = new method.resolvedRequestType.clazz(req);
  8603. this.rpcImpl(method.fqn(), req, function(err, res) { // Assumes that this is properly async
  8604. if (err) {
  8605. callback(err);
  8606. return;
  8607. }
  8608. // Coalesce to empty string when service response has empty content
  8609. if (res === null)
  8610. res = '';
  8611. try { res = method.resolvedResponseType.clazz.decode(res); } catch (notABuffer) {}
  8612. if (!res || !(res instanceof method.resolvedResponseType.clazz)) {
  8613. callback(Error("Illegal response type received in service method "+ T.name+"#"+method.name));
  8614. return;
  8615. }
  8616. callback(null, res);
  8617. });
  8618. } catch (err) {
  8619. setTimeout(callback.bind(this, err), 0);
  8620. }
  8621. };
  8622. // Service.Method(rpcImpl, message, callback)
  8623. Service[method.name] = function(rpcImpl, req, callback) {
  8624. new Service(rpcImpl)[method.name](req, callback);
  8625. };
  8626. if (Object.defineProperty)
  8627. Object.defineProperty(Service[method.name], "$options", { "value": method.buildOpt() }),
  8628. Object.defineProperty(ServicePrototype[method.name], "$options", { "value": Service[method.name]["$options"] });
  8629. })(rpc[i]);
  8630. }
  8631. if (Object.defineProperty)
  8632. Object.defineProperty(Service, "$options", { "value": T.buildOpt() }),
  8633. Object.defineProperty(ServicePrototype, "$options", { "value": Service["$options"] }),
  8634. Object.defineProperty(Service, "$type", { "value": T }),
  8635. Object.defineProperty(ServicePrototype, "$type", { "value": T });
  8636. return Service;
  8637. })(ProtoBuf, this);
  8638. };
  8639. /**
  8640. * @alias ProtoBuf.Reflect.Service
  8641. * @expose
  8642. */
  8643. Reflect.Service = Service;
  8644. /**
  8645. * Abstract service method.
  8646. * @exports ProtoBuf.Reflect.Service.Method
  8647. * @param {!ProtoBuf.Builder} builder Builder reference
  8648. * @param {!ProtoBuf.Reflect.Service} svc Service
  8649. * @param {string} name Method name
  8650. * @param {Object.<string,*>=} options Options
  8651. * @constructor
  8652. * @extends ProtoBuf.Reflect.T
  8653. */
  8654. var Method = function(builder, svc, name, options) {
  8655. T.call(this, builder, svc, name);
  8656. /**
  8657. * @override
  8658. */
  8659. this.className = "Service.Method";
  8660. /**
  8661. * Options.
  8662. * @type {Object.<string, *>}
  8663. * @expose
  8664. */
  8665. this.options = options || {};
  8666. };
  8667. /**
  8668. * @alias ProtoBuf.Reflect.Service.Method.prototype
  8669. * @inner
  8670. */
  8671. var MethodPrototype = Method.prototype = Object.create(T.prototype);
  8672. /**
  8673. * Builds the method's '$options' property.
  8674. * @name ProtoBuf.Reflect.Service.Method#buildOpt
  8675. * @function
  8676. * @return {Object.<string,*>}
  8677. */
  8678. MethodPrototype.buildOpt = NamespacePrototype.buildOpt;
  8679. /**
  8680. * @alias ProtoBuf.Reflect.Service.Method
  8681. * @expose
  8682. */
  8683. Reflect.Service.Method = Method;
  8684. /**
  8685. * RPC service method.
  8686. * @exports ProtoBuf.Reflect.Service.RPCMethod
  8687. * @param {!ProtoBuf.Builder} builder Builder reference
  8688. * @param {!ProtoBuf.Reflect.Service} svc Service
  8689. * @param {string} name Method name
  8690. * @param {string} request Request message name
  8691. * @param {string} response Response message name
  8692. * @param {boolean} request_stream Whether requests are streamed
  8693. * @param {boolean} response_stream Whether responses are streamed
  8694. * @param {Object.<string,*>=} options Options
  8695. * @constructor
  8696. * @extends ProtoBuf.Reflect.Service.Method
  8697. */
  8698. var RPCMethod = function(builder, svc, name, request, response, request_stream, response_stream, options) {
  8699. Method.call(this, builder, svc, name, options);
  8700. /**
  8701. * @override
  8702. */
  8703. this.className = "Service.RPCMethod";
  8704. /**
  8705. * Request message name.
  8706. * @type {string}
  8707. * @expose
  8708. */
  8709. this.requestName = request;
  8710. /**
  8711. * Response message name.
  8712. * @type {string}
  8713. * @expose
  8714. */
  8715. this.responseName = response;
  8716. /**
  8717. * Whether requests are streamed
  8718. * @type {bool}
  8719. * @expose
  8720. */
  8721. this.requestStream = request_stream;
  8722. /**
  8723. * Whether responses are streamed
  8724. * @type {bool}
  8725. * @expose
  8726. */
  8727. this.responseStream = response_stream;
  8728. /**
  8729. * Resolved request message type.
  8730. * @type {ProtoBuf.Reflect.Message}
  8731. * @expose
  8732. */
  8733. this.resolvedRequestType = null;
  8734. /**
  8735. * Resolved response message type.
  8736. * @type {ProtoBuf.Reflect.Message}
  8737. * @expose
  8738. */
  8739. this.resolvedResponseType = null;
  8740. };
  8741. // Extends Method
  8742. RPCMethod.prototype = Object.create(Method.prototype);
  8743. /**
  8744. * @alias ProtoBuf.Reflect.Service.RPCMethod
  8745. * @expose
  8746. */
  8747. Reflect.Service.RPCMethod = RPCMethod;
  8748. return Reflect;
  8749. })(ProtoBuf);
  8750. /**
  8751. * @alias ProtoBuf.Builder
  8752. * @expose
  8753. */
  8754. ProtoBuf.Builder = (function(ProtoBuf, Lang, Reflect) {
  8755. /**
  8756. * Constructs a new Builder.
  8757. * @exports ProtoBuf.Builder
  8758. * @class Provides the functionality to build protocol messages.
  8759. * @param {Object.<string,*>=} options Options
  8760. * @constructor
  8761. */
  8762. var Builder = function(options) {
  8763. /**
  8764. * Namespace.
  8765. * @type {ProtoBuf.Reflect.Namespace}
  8766. * @expose
  8767. */
  8768. this.ns = new Reflect.Namespace(this, null, ""); // Global namespace
  8769. /**
  8770. * Namespace pointer.
  8771. * @type {ProtoBuf.Reflect.T}
  8772. * @expose
  8773. */
  8774. this.ptr = this.ns;
  8775. /**
  8776. * Resolved flag.
  8777. * @type {boolean}
  8778. * @expose
  8779. */
  8780. this.resolved = false;
  8781. /**
  8782. * The current building result.
  8783. * @type {Object.<string,ProtoBuf.Builder.Message|Object>|null}
  8784. * @expose
  8785. */
  8786. this.result = null;
  8787. /**
  8788. * Imported files.
  8789. * @type {Array.<string>}
  8790. * @expose
  8791. */
  8792. this.files = {};
  8793. /**
  8794. * Import root override.
  8795. * @type {?string}
  8796. * @expose
  8797. */
  8798. this.importRoot = null;
  8799. /**
  8800. * Options.
  8801. * @type {!Object.<string, *>}
  8802. * @expose
  8803. */
  8804. this.options = options || {};
  8805. };
  8806. /**
  8807. * @alias ProtoBuf.Builder.prototype
  8808. * @inner
  8809. */
  8810. var BuilderPrototype = Builder.prototype;
  8811. // ----- Definition tests -----
  8812. /**
  8813. * Tests if a definition most likely describes a message.
  8814. * @param {!Object} def
  8815. * @returns {boolean}
  8816. * @expose
  8817. */
  8818. Builder.isMessage = function(def) {
  8819. // Messages require a string name
  8820. if (typeof def["name"] !== 'string')
  8821. return false;
  8822. // Messages do not contain values (enum) or rpc methods (service)
  8823. if (typeof def["values"] !== 'undefined' || typeof def["rpc"] !== 'undefined')
  8824. return false;
  8825. return true;
  8826. };
  8827. /**
  8828. * Tests if a definition most likely describes a message field.
  8829. * @param {!Object} def
  8830. * @returns {boolean}
  8831. * @expose
  8832. */
  8833. Builder.isMessageField = function(def) {
  8834. // Message fields require a string rule, name and type and an id
  8835. if (typeof def["rule"] !== 'string' || typeof def["name"] !== 'string' || typeof def["type"] !== 'string' || typeof def["id"] === 'undefined')
  8836. return false;
  8837. return true;
  8838. };
  8839. /**
  8840. * Tests if a definition most likely describes an enum.
  8841. * @param {!Object} def
  8842. * @returns {boolean}
  8843. * @expose
  8844. */
  8845. Builder.isEnum = function(def) {
  8846. // Enums require a string name
  8847. if (typeof def["name"] !== 'string')
  8848. return false;
  8849. // Enums require at least one value
  8850. if (typeof def["values"] === 'undefined' || !Array.isArray(def["values"]) || def["values"].length === 0)
  8851. return false;
  8852. return true;
  8853. };
  8854. /**
  8855. * Tests if a definition most likely describes a service.
  8856. * @param {!Object} def
  8857. * @returns {boolean}
  8858. * @expose
  8859. */
  8860. Builder.isService = function(def) {
  8861. // Services require a string name and an rpc object
  8862. if (typeof def["name"] !== 'string' || typeof def["rpc"] !== 'object' || !def["rpc"])
  8863. return false;
  8864. return true;
  8865. };
  8866. /**
  8867. * Tests if a definition most likely describes an extended message
  8868. * @param {!Object} def
  8869. * @returns {boolean}
  8870. * @expose
  8871. */
  8872. Builder.isExtend = function(def) {
  8873. // Extends rquire a string ref
  8874. if (typeof def["ref"] !== 'string')
  8875. return false;
  8876. return true;
  8877. };
  8878. // ----- Building -----
  8879. /**
  8880. * Resets the pointer to the root namespace.
  8881. * @returns {!ProtoBuf.Builder} this
  8882. * @expose
  8883. */
  8884. BuilderPrototype.reset = function() {
  8885. this.ptr = this.ns;
  8886. return this;
  8887. };
  8888. /**
  8889. * Defines a namespace on top of the current pointer position and places the pointer on it.
  8890. * @param {string} namespace
  8891. * @return {!ProtoBuf.Builder} this
  8892. * @expose
  8893. */
  8894. BuilderPrototype.define = function(namespace) {
  8895. if (typeof namespace !== 'string' || !Lang.TYPEREF.test(namespace))
  8896. throw Error("illegal namespace: "+namespace);
  8897. namespace.split(".").forEach(function(part) {
  8898. var ns = this.ptr.getChild(part);
  8899. if (ns === null) // Keep existing
  8900. this.ptr.addChild(ns = new Reflect.Namespace(this, this.ptr, part));
  8901. this.ptr = ns;
  8902. }, this);
  8903. return this;
  8904. };
  8905. /**
  8906. * Creates the specified definitions at the current pointer position.
  8907. * @param {!Array.<!Object>} defs Messages, enums or services to create
  8908. * @returns {!ProtoBuf.Builder} this
  8909. * @throws {Error} If a message definition is invalid
  8910. * @expose
  8911. */
  8912. BuilderPrototype.create = function(defs) {
  8913. if (!defs)
  8914. return this; // Nothing to create
  8915. if (!Array.isArray(defs))
  8916. defs = [defs];
  8917. else {
  8918. if (defs.length === 0)
  8919. return this;
  8920. defs = defs.slice();
  8921. }
  8922. // It's quite hard to keep track of scopes and memory here, so let's do this iteratively.
  8923. var stack = [defs];
  8924. while (stack.length > 0) {
  8925. defs = stack.pop();
  8926. if (!Array.isArray(defs)) // Stack always contains entire namespaces
  8927. throw Error("not a valid namespace: "+JSON.stringify(defs));
  8928. while (defs.length > 0) {
  8929. var def = defs.shift(); // Namespaces always contain an array of messages, enums and services
  8930. if (Builder.isMessage(def)) {
  8931. var obj = new Reflect.Message(this, this.ptr, def["name"], def["options"], def["isGroup"], def["syntax"]);
  8932. // Create OneOfs
  8933. var oneofs = {};
  8934. if (def["oneofs"])
  8935. Object.keys(def["oneofs"]).forEach(function(name) {
  8936. obj.addChild(oneofs[name] = new Reflect.Message.OneOf(this, obj, name));
  8937. }, this);
  8938. // Create fields
  8939. if (def["fields"])
  8940. def["fields"].forEach(function(fld) {
  8941. if (obj.getChild(fld["id"]|0) !== null)
  8942. throw Error("duplicate or invalid field id in "+obj.name+": "+fld['id']);
  8943. if (fld["options"] && typeof fld["options"] !== 'object')
  8944. throw Error("illegal field options in "+obj.name+"#"+fld["name"]);
  8945. var oneof = null;
  8946. if (typeof fld["oneof"] === 'string' && !(oneof = oneofs[fld["oneof"]]))
  8947. throw Error("illegal oneof in "+obj.name+"#"+fld["name"]+": "+fld["oneof"]);
  8948. fld = new Reflect.Message.Field(this, obj, fld["rule"], fld["keytype"], fld["type"], fld["name"], fld["id"], fld["options"], oneof, def["syntax"]);
  8949. if (oneof)
  8950. oneof.fields.push(fld);
  8951. obj.addChild(fld);
  8952. }, this);
  8953. // Push children to stack
  8954. var subObj = [];
  8955. if (def["enums"])
  8956. def["enums"].forEach(function(enm) {
  8957. subObj.push(enm);
  8958. });
  8959. if (def["messages"])
  8960. def["messages"].forEach(function(msg) {
  8961. subObj.push(msg);
  8962. });
  8963. if (def["services"])
  8964. def["services"].forEach(function(svc) {
  8965. subObj.push(svc);
  8966. });
  8967. // Set extension ranges
  8968. if (def["extensions"]) {
  8969. if (typeof def["extensions"][0] === 'number') // pre 5.0.1
  8970. obj.extensions = [ def["extensions"] ];
  8971. else
  8972. obj.extensions = def["extensions"];
  8973. }
  8974. // Create on top of current namespace
  8975. this.ptr.addChild(obj);
  8976. if (subObj.length > 0) {
  8977. stack.push(defs); // Push the current level back
  8978. defs = subObj; // Continue processing sub level
  8979. subObj = null;
  8980. this.ptr = obj; // And move the pointer to this namespace
  8981. obj = null;
  8982. continue;
  8983. }
  8984. subObj = null;
  8985. } else if (Builder.isEnum(def)) {
  8986. obj = new Reflect.Enum(this, this.ptr, def["name"], def["options"], def["syntax"]);
  8987. def["values"].forEach(function(val) {
  8988. obj.addChild(new Reflect.Enum.Value(this, obj, val["name"], val["id"]));
  8989. }, this);
  8990. this.ptr.addChild(obj);
  8991. } else if (Builder.isService(def)) {
  8992. obj = new Reflect.Service(this, this.ptr, def["name"], def["options"]);
  8993. Object.keys(def["rpc"]).forEach(function(name) {
  8994. var mtd = def["rpc"][name];
  8995. obj.addChild(new Reflect.Service.RPCMethod(this, obj, name, mtd["request"], mtd["response"], !!mtd["request_stream"], !!mtd["response_stream"], mtd["options"]));
  8996. }, this);
  8997. this.ptr.addChild(obj);
  8998. } else if (Builder.isExtend(def)) {
  8999. obj = this.ptr.resolve(def["ref"], true);
  9000. if (obj) {
  9001. def["fields"].forEach(function(fld) {
  9002. if (obj.getChild(fld['id']|0) !== null)
  9003. throw Error("duplicate extended field id in "+obj.name+": "+fld['id']);
  9004. // Check if field id is allowed to be extended
  9005. if (obj.extensions) {
  9006. var valid = false;
  9007. obj.extensions.forEach(function(range) {
  9008. if (fld["id"] >= range[0] && fld["id"] <= range[1])
  9009. valid = true;
  9010. });
  9011. if (!valid)
  9012. throw Error("illegal extended field id in "+obj.name+": "+fld['id']+" (not within valid ranges)");
  9013. }
  9014. // Convert extension field names to camel case notation if the override is set
  9015. var name = fld["name"];
  9016. if (this.options['convertFieldsToCamelCase'])
  9017. name = ProtoBuf.Util.toCamelCase(name);
  9018. // see #161: Extensions use their fully qualified name as their runtime key and...
  9019. var field = new Reflect.Message.ExtensionField(this, obj, fld["rule"], fld["type"], this.ptr.fqn()+'.'+name, fld["id"], fld["options"]);
  9020. // ...are added on top of the current namespace as an extension which is used for
  9021. // resolving their type later on (the extension always keeps the original name to
  9022. // prevent naming collisions)
  9023. var ext = new Reflect.Extension(this, this.ptr, fld["name"], field);
  9024. field.extension = ext;
  9025. this.ptr.addChild(ext);
  9026. obj.addChild(field);
  9027. }, this);
  9028. } else if (!/\.?google\.protobuf\./.test(def["ref"])) // Silently skip internal extensions
  9029. throw Error("extended message "+def["ref"]+" is not defined");
  9030. } else
  9031. throw Error("not a valid definition: "+JSON.stringify(def));
  9032. def = null;
  9033. obj = null;
  9034. }
  9035. // Break goes here
  9036. defs = null;
  9037. this.ptr = this.ptr.parent; // Namespace done, continue at parent
  9038. }
  9039. this.resolved = false; // Require re-resolve
  9040. this.result = null; // Require re-build
  9041. return this;
  9042. };
  9043. /**
  9044. * Propagates syntax to all children.
  9045. * @param {!Object} parent
  9046. * @inner
  9047. */
  9048. function propagateSyntax(parent) {
  9049. if (parent['messages']) {
  9050. parent['messages'].forEach(function(child) {
  9051. child["syntax"] = parent["syntax"];
  9052. propagateSyntax(child);
  9053. });
  9054. }
  9055. if (parent['enums']) {
  9056. parent['enums'].forEach(function(child) {
  9057. child["syntax"] = parent["syntax"];
  9058. });
  9059. }
  9060. }
  9061. /**
  9062. * Imports another definition into this builder.
  9063. * @param {Object.<string,*>} json Parsed import
  9064. * @param {(string|{root: string, file: string})=} filename Imported file name
  9065. * @returns {!ProtoBuf.Builder} this
  9066. * @throws {Error} If the definition or file cannot be imported
  9067. * @expose
  9068. */
  9069. BuilderPrototype["import"] = function(json, filename) {
  9070. var delim = '/';
  9071. // Make sure to skip duplicate imports
  9072. if (typeof filename === 'string') {
  9073. if (ProtoBuf.Util.IS_NODE)
  9074. filename = require$$2['resolve'](filename);
  9075. if (this.files[filename] === true)
  9076. return this.reset();
  9077. this.files[filename] = true;
  9078. } else if (typeof filename === 'object') { // Object with root, file.
  9079. var root = filename.root;
  9080. if (ProtoBuf.Util.IS_NODE)
  9081. root = require$$2['resolve'](root);
  9082. if (root.indexOf("\\") >= 0 || filename.file.indexOf("\\") >= 0)
  9083. delim = '\\';
  9084. var fname;
  9085. if (ProtoBuf.Util.IS_NODE)
  9086. fname = require$$2['join'](root, filename.file);
  9087. else
  9088. fname = root + delim + filename.file;
  9089. if (this.files[fname] === true)
  9090. return this.reset();
  9091. this.files[fname] = true;
  9092. }
  9093. // Import imports
  9094. if (json['imports'] && json['imports'].length > 0) {
  9095. var importRoot,
  9096. resetRoot = false;
  9097. if (typeof filename === 'object') { // If an import root is specified, override
  9098. this.importRoot = filename["root"]; resetRoot = true; // ... and reset afterwards
  9099. importRoot = this.importRoot;
  9100. filename = filename["file"];
  9101. if (importRoot.indexOf("\\") >= 0 || filename.indexOf("\\") >= 0)
  9102. delim = '\\';
  9103. } else if (typeof filename === 'string') {
  9104. if (this.importRoot) // If import root is overridden, use it
  9105. importRoot = this.importRoot;
  9106. else { // Otherwise compute from filename
  9107. if (filename.indexOf("/") >= 0) { // Unix
  9108. importRoot = filename.replace(/\/[^\/]*$/, "");
  9109. if (/* /file.proto */ importRoot === "")
  9110. importRoot = "/";
  9111. } else if (filename.indexOf("\\") >= 0) { // Windows
  9112. importRoot = filename.replace(/\\[^\\]*$/, "");
  9113. delim = '\\';
  9114. } else
  9115. importRoot = ".";
  9116. }
  9117. } else
  9118. importRoot = null;
  9119. for (var i=0; i<json['imports'].length; i++) {
  9120. if (typeof json['imports'][i] === 'string') { // Import file
  9121. if (!importRoot)
  9122. throw Error("cannot determine import root");
  9123. var importFilename = json['imports'][i];
  9124. if (importFilename === "google/protobuf/descriptor.proto")
  9125. continue; // Not needed and therefore not used
  9126. if (ProtoBuf.Util.IS_NODE)
  9127. importFilename = require$$2['join'](importRoot, importFilename);
  9128. else
  9129. importFilename = importRoot + delim + importFilename;
  9130. if (this.files[importFilename] === true)
  9131. continue; // Already imported
  9132. if (/\.proto$/i.test(importFilename) && !ProtoBuf.DotProto) // If this is a light build
  9133. importFilename = importFilename.replace(/\.proto$/, ".json"); // always load the JSON file
  9134. var contents = ProtoBuf.Util.fetch(importFilename);
  9135. if (contents === null)
  9136. throw Error("failed to import '"+importFilename+"' in '"+filename+"': file not found");
  9137. if (/\.json$/i.test(importFilename)) // Always possible
  9138. this["import"](JSON.parse(contents+""), importFilename); // May throw
  9139. else
  9140. this["import"](ProtoBuf.DotProto.Parser.parse(contents), importFilename); // May throw
  9141. } else // Import structure
  9142. if (!filename)
  9143. this["import"](json['imports'][i]);
  9144. else if (/\.(\w+)$/.test(filename)) // With extension: Append _importN to the name portion to make it unique
  9145. this["import"](json['imports'][i], filename.replace(/^(.+)\.(\w+)$/, function($0, $1, $2) { return $1+"_import"+i+"."+$2; }));
  9146. else // Without extension: Append _importN to make it unique
  9147. this["import"](json['imports'][i], filename+"_import"+i);
  9148. }
  9149. if (resetRoot) // Reset import root override when all imports are done
  9150. this.importRoot = null;
  9151. }
  9152. // Import structures
  9153. if (json['package'])
  9154. this.define(json['package']);
  9155. if (json['syntax'])
  9156. propagateSyntax(json);
  9157. var base = this.ptr;
  9158. if (json['options'])
  9159. Object.keys(json['options']).forEach(function(key) {
  9160. base.options[key] = json['options'][key];
  9161. });
  9162. if (json['messages'])
  9163. this.create(json['messages']),
  9164. this.ptr = base;
  9165. if (json['enums'])
  9166. this.create(json['enums']),
  9167. this.ptr = base;
  9168. if (json['services'])
  9169. this.create(json['services']),
  9170. this.ptr = base;
  9171. if (json['extends'])
  9172. this.create(json['extends']);
  9173. return this.reset();
  9174. };
  9175. /**
  9176. * Resolves all namespace objects.
  9177. * @throws {Error} If a type cannot be resolved
  9178. * @returns {!ProtoBuf.Builder} this
  9179. * @expose
  9180. */
  9181. BuilderPrototype.resolveAll = function() {
  9182. // Resolve all reflected objects
  9183. var res;
  9184. if (this.ptr == null || typeof this.ptr.type === 'object')
  9185. return this; // Done (already resolved)
  9186. if (this.ptr instanceof Reflect.Namespace) { // Resolve children
  9187. this.ptr.children.forEach(function(child) {
  9188. this.ptr = child;
  9189. this.resolveAll();
  9190. }, this);
  9191. } else if (this.ptr instanceof Reflect.Message.Field) { // Resolve type
  9192. if (!Lang.TYPE.test(this.ptr.type)) {
  9193. if (!Lang.TYPEREF.test(this.ptr.type))
  9194. throw Error("illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.type);
  9195. res = (this.ptr instanceof Reflect.Message.ExtensionField ? this.ptr.extension.parent : this.ptr.parent).resolve(this.ptr.type, true);
  9196. if (!res)
  9197. throw Error("unresolvable type reference in "+this.ptr.toString(true)+": "+this.ptr.type);
  9198. this.ptr.resolvedType = res;
  9199. if (res instanceof Reflect.Enum) {
  9200. this.ptr.type = ProtoBuf.TYPES["enum"];
  9201. if (this.ptr.syntax === 'proto3' && res.syntax !== 'proto3')
  9202. throw Error("proto3 message cannot reference proto2 enum");
  9203. }
  9204. else if (res instanceof Reflect.Message)
  9205. this.ptr.type = res.isGroup ? ProtoBuf.TYPES["group"] : ProtoBuf.TYPES["message"];
  9206. else
  9207. throw Error("illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.type);
  9208. } else
  9209. this.ptr.type = ProtoBuf.TYPES[this.ptr.type];
  9210. // If it's a map field, also resolve the key type. The key type can be only a numeric, string, or bool type
  9211. // (i.e., no enums or messages), so we don't need to resolve against the current namespace.
  9212. if (this.ptr.map) {
  9213. if (!Lang.TYPE.test(this.ptr.keyType))
  9214. throw Error("illegal key type for map field in "+this.ptr.toString(true)+": "+this.ptr.keyType);
  9215. this.ptr.keyType = ProtoBuf.TYPES[this.ptr.keyType];
  9216. }
  9217. // If it's a repeated and packable field then proto3 mandates it should be packed by
  9218. // default
  9219. if (
  9220. this.ptr.syntax === 'proto3' &&
  9221. this.ptr.repeated && this.ptr.options.packed === undefined &&
  9222. ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.ptr.type.wireType) !== -1
  9223. ) {
  9224. this.ptr.options.packed = true;
  9225. }
  9226. } else if (this.ptr instanceof ProtoBuf.Reflect.Service.Method) {
  9227. if (this.ptr instanceof ProtoBuf.Reflect.Service.RPCMethod) {
  9228. res = this.ptr.parent.resolve(this.ptr.requestName, true);
  9229. if (!res || !(res instanceof ProtoBuf.Reflect.Message))
  9230. throw Error("Illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.requestName);
  9231. this.ptr.resolvedRequestType = res;
  9232. res = this.ptr.parent.resolve(this.ptr.responseName, true);
  9233. if (!res || !(res instanceof ProtoBuf.Reflect.Message))
  9234. throw Error("Illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.responseName);
  9235. this.ptr.resolvedResponseType = res;
  9236. } else // Should not happen as nothing else is implemented
  9237. throw Error("illegal service type in "+this.ptr.toString(true));
  9238. } else if (
  9239. !(this.ptr instanceof ProtoBuf.Reflect.Message.OneOf) && // Not built
  9240. !(this.ptr instanceof ProtoBuf.Reflect.Extension) && // Not built
  9241. !(this.ptr instanceof ProtoBuf.Reflect.Enum.Value) // Built in enum
  9242. )
  9243. throw Error("illegal object in namespace: "+typeof(this.ptr)+": "+this.ptr);
  9244. return this.reset();
  9245. };
  9246. /**
  9247. * Builds the protocol. This will first try to resolve all definitions and, if this has been successful,
  9248. * return the built package.
  9249. * @param {(string|Array.<string>)=} path Specifies what to return. If omitted, the entire namespace will be returned.
  9250. * @returns {!ProtoBuf.Builder.Message|!Object.<string,*>}
  9251. * @throws {Error} If a type could not be resolved
  9252. * @expose
  9253. */
  9254. BuilderPrototype.build = function(path) {
  9255. this.reset();
  9256. if (!this.resolved)
  9257. this.resolveAll(),
  9258. this.resolved = true,
  9259. this.result = null; // Require re-build
  9260. if (this.result === null) // (Re-)Build
  9261. this.result = this.ns.build();
  9262. if (!path)
  9263. return this.result;
  9264. var part = typeof path === 'string' ? path.split(".") : path,
  9265. ptr = this.result; // Build namespace pointer (no hasChild etc.)
  9266. for (var i=0; i<part.length; i++)
  9267. if (ptr[part[i]])
  9268. ptr = ptr[part[i]];
  9269. else {
  9270. ptr = null;
  9271. break;
  9272. }
  9273. return ptr;
  9274. };
  9275. /**
  9276. * Similar to {@link ProtoBuf.Builder#build}, but looks up the internal reflection descriptor.
  9277. * @param {string=} path Specifies what to return. If omitted, the entire namespace wiil be returned.
  9278. * @param {boolean=} excludeNonNamespace Excludes non-namespace types like fields, defaults to `false`
  9279. * @returns {?ProtoBuf.Reflect.T} Reflection descriptor or `null` if not found
  9280. */
  9281. BuilderPrototype.lookup = function(path, excludeNonNamespace) {
  9282. return path ? this.ns.resolve(path, excludeNonNamespace) : this.ns;
  9283. };
  9284. /**
  9285. * Returns a string representation of this object.
  9286. * @return {string} String representation as of "Builder"
  9287. * @expose
  9288. */
  9289. BuilderPrototype.toString = function() {
  9290. return "Builder";
  9291. };
  9292. // ----- Base classes -----
  9293. // Exist for the sole purpose of being able to "... instanceof ProtoBuf.Builder.Message" etc.
  9294. /**
  9295. * @alias ProtoBuf.Builder.Message
  9296. */
  9297. Builder.Message = function() {};
  9298. /**
  9299. * @alias ProtoBuf.Builder.Enum
  9300. */
  9301. Builder.Enum = function() {};
  9302. /**
  9303. * @alias ProtoBuf.Builder.Message
  9304. */
  9305. Builder.Service = function() {};
  9306. return Builder;
  9307. })(ProtoBuf, ProtoBuf.Lang, ProtoBuf.Reflect);
  9308. /**
  9309. * @alias ProtoBuf.Map
  9310. * @expose
  9311. */
  9312. ProtoBuf.Map = (function(ProtoBuf, Reflect) {
  9313. /**
  9314. * Constructs a new Map. A Map is a container that is used to implement map
  9315. * fields on message objects. It closely follows the ES6 Map API; however,
  9316. * it is distinct because we do not want to depend on external polyfills or
  9317. * on ES6 itself.
  9318. *
  9319. * @exports ProtoBuf.Map
  9320. * @param {!ProtoBuf.Reflect.Field} field Map field
  9321. * @param {Object.<string,*>=} contents Initial contents
  9322. * @constructor
  9323. */
  9324. var Map = function(field, contents) {
  9325. if (!field.map)
  9326. throw Error("field is not a map");
  9327. /**
  9328. * The field corresponding to this map.
  9329. * @type {!ProtoBuf.Reflect.Field}
  9330. */
  9331. this.field = field;
  9332. /**
  9333. * Element instance corresponding to key type.
  9334. * @type {!ProtoBuf.Reflect.Element}
  9335. */
  9336. this.keyElem = new Reflect.Element(field.keyType, null, true, field.syntax);
  9337. /**
  9338. * Element instance corresponding to value type.
  9339. * @type {!ProtoBuf.Reflect.Element}
  9340. */
  9341. this.valueElem = new Reflect.Element(field.type, field.resolvedType, false, field.syntax);
  9342. /**
  9343. * Internal map: stores mapping of (string form of key) -> (key, value)
  9344. * pair.
  9345. *
  9346. * We provide map semantics for arbitrary key types, but we build on top
  9347. * of an Object, which has only string keys. In order to avoid the need
  9348. * to convert a string key back to its native type in many situations,
  9349. * we store the native key value alongside the value. Thus, we only need
  9350. * a one-way mapping from a key type to its string form that guarantees
  9351. * uniqueness and equality (i.e., str(K1) === str(K2) if and only if K1
  9352. * === K2).
  9353. *
  9354. * @type {!Object<string, {key: *, value: *}>}
  9355. */
  9356. this.map = {};
  9357. /**
  9358. * Returns the number of elements in the map.
  9359. */
  9360. Object.defineProperty(this, "size", {
  9361. get: function() { return Object.keys(this.map).length; }
  9362. });
  9363. // Fill initial contents from a raw object.
  9364. if (contents) {
  9365. var keys = Object.keys(contents);
  9366. for (var i = 0; i < keys.length; i++) {
  9367. var key = this.keyElem.valueFromString(keys[i]);
  9368. var val = this.valueElem.verifyValue(contents[keys[i]]);
  9369. this.map[this.keyElem.valueToString(key)] =
  9370. { key: key, value: val };
  9371. }
  9372. }
  9373. };
  9374. var MapPrototype = Map.prototype;
  9375. /**
  9376. * Helper: return an iterator over an array.
  9377. * @param {!Array<*>} arr the array
  9378. * @returns {!Object} an iterator
  9379. * @inner
  9380. */
  9381. function arrayIterator(arr) {
  9382. var idx = 0;
  9383. return {
  9384. next: function() {
  9385. if (idx < arr.length)
  9386. return { done: false, value: arr[idx++] };
  9387. return { done: true };
  9388. }
  9389. }
  9390. }
  9391. /**
  9392. * Clears the map.
  9393. */
  9394. MapPrototype.clear = function() {
  9395. this.map = {};
  9396. };
  9397. /**
  9398. * Deletes a particular key from the map.
  9399. * @returns {boolean} Whether any entry with this key was deleted.
  9400. */
  9401. MapPrototype["delete"] = function(key) {
  9402. var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));
  9403. var hadKey = keyValue in this.map;
  9404. delete this.map[keyValue];
  9405. return hadKey;
  9406. };
  9407. /**
  9408. * Returns an iterator over [key, value] pairs in the map.
  9409. * @returns {Object} The iterator
  9410. */
  9411. MapPrototype.entries = function() {
  9412. var entries = [];
  9413. var strKeys = Object.keys(this.map);
  9414. for (var i = 0, entry; i < strKeys.length; i++)
  9415. entries.push([(entry=this.map[strKeys[i]]).key, entry.value]);
  9416. return arrayIterator(entries);
  9417. };
  9418. /**
  9419. * Returns an iterator over keys in the map.
  9420. * @returns {Object} The iterator
  9421. */
  9422. MapPrototype.keys = function() {
  9423. var keys = [];
  9424. var strKeys = Object.keys(this.map);
  9425. for (var i = 0; i < strKeys.length; i++)
  9426. keys.push(this.map[strKeys[i]].key);
  9427. return arrayIterator(keys);
  9428. };
  9429. /**
  9430. * Returns an iterator over values in the map.
  9431. * @returns {!Object} The iterator
  9432. */
  9433. MapPrototype.values = function() {
  9434. var values = [];
  9435. var strKeys = Object.keys(this.map);
  9436. for (var i = 0; i < strKeys.length; i++)
  9437. values.push(this.map[strKeys[i]].value);
  9438. return arrayIterator(values);
  9439. };
  9440. /**
  9441. * Iterates over entries in the map, calling a function on each.
  9442. * @param {function(this:*, *, *, *)} cb The callback to invoke with value, key, and map arguments.
  9443. * @param {Object=} thisArg The `this` value for the callback
  9444. */
  9445. MapPrototype.forEach = function(cb, thisArg) {
  9446. var strKeys = Object.keys(this.map);
  9447. for (var i = 0, entry; i < strKeys.length; i++)
  9448. cb.call(thisArg, (entry=this.map[strKeys[i]]).value, entry.key, this);
  9449. };
  9450. /**
  9451. * Sets a key in the map to the given value.
  9452. * @param {*} key The key
  9453. * @param {*} value The value
  9454. * @returns {!ProtoBuf.Map} The map instance
  9455. */
  9456. MapPrototype.set = function(key, value) {
  9457. var keyValue = this.keyElem.verifyValue(key);
  9458. var valValue = this.valueElem.verifyValue(value);
  9459. this.map[this.keyElem.valueToString(keyValue)] =
  9460. { key: keyValue, value: valValue };
  9461. return this;
  9462. };
  9463. /**
  9464. * Gets the value corresponding to a key in the map.
  9465. * @param {*} key The key
  9466. * @returns {*|undefined} The value, or `undefined` if key not present
  9467. */
  9468. MapPrototype.get = function(key) {
  9469. var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));
  9470. if (!(keyValue in this.map))
  9471. return undefined;
  9472. return this.map[keyValue].value;
  9473. };
  9474. /**
  9475. * Determines whether the given key is present in the map.
  9476. * @param {*} key The key
  9477. * @returns {boolean} `true` if the key is present
  9478. */
  9479. MapPrototype.has = function(key) {
  9480. var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));
  9481. return (keyValue in this.map);
  9482. };
  9483. return Map;
  9484. })(ProtoBuf, ProtoBuf.Reflect);
  9485. /**
  9486. * Constructs a new empty Builder.
  9487. * @param {Object.<string,*>=} options Builder options, defaults to global options set on ProtoBuf
  9488. * @return {!ProtoBuf.Builder} Builder
  9489. * @expose
  9490. */
  9491. ProtoBuf.newBuilder = function(options) {
  9492. options = options || {};
  9493. if (typeof options['convertFieldsToCamelCase'] === 'undefined')
  9494. options['convertFieldsToCamelCase'] = ProtoBuf.convertFieldsToCamelCase;
  9495. if (typeof options['populateAccessors'] === 'undefined')
  9496. options['populateAccessors'] = ProtoBuf.populateAccessors;
  9497. return new ProtoBuf.Builder(options);
  9498. };
  9499. /**
  9500. * Loads a .json definition and returns the Builder.
  9501. * @param {!*|string} json JSON definition
  9502. * @param {(ProtoBuf.Builder|string|{root: string, file: string})=} builder Builder to append to. Will create a new one if omitted.
  9503. * @param {(string|{root: string, file: string})=} filename The corresponding file name if known. Must be specified for imports.
  9504. * @return {ProtoBuf.Builder} Builder to create new messages
  9505. * @throws {Error} If the definition cannot be parsed or built
  9506. * @expose
  9507. */
  9508. ProtoBuf.loadJson = function(json, builder, filename) {
  9509. if (typeof builder === 'string' || (builder && typeof builder["file"] === 'string' && typeof builder["root"] === 'string'))
  9510. filename = builder,
  9511. builder = null;
  9512. if (!builder || typeof builder !== 'object')
  9513. builder = ProtoBuf.newBuilder();
  9514. if (typeof json === 'string')
  9515. json = JSON.parse(json);
  9516. builder["import"](json, filename);
  9517. builder.resolveAll();
  9518. return builder;
  9519. };
  9520. /**
  9521. * Loads a .json file and returns the Builder.
  9522. * @param {string|!{root: string, file: string}} filename Path to json file or an object specifying 'file' with
  9523. * an overridden 'root' path for all imported files.
  9524. * @param {function(?Error, !ProtoBuf.Builder=)=} callback Callback that will receive `null` as the first and
  9525. * the Builder as its second argument on success, otherwise the error as its first argument. If omitted, the
  9526. * file will be read synchronously and this function will return the Builder.
  9527. * @param {ProtoBuf.Builder=} builder Builder to append to. Will create a new one if omitted.
  9528. * @return {?ProtoBuf.Builder|undefined} The Builder if synchronous (no callback specified, will be NULL if the
  9529. * request has failed), else undefined
  9530. * @expose
  9531. */
  9532. ProtoBuf.loadJsonFile = function(filename, callback, builder) {
  9533. if (callback && typeof callback === 'object')
  9534. builder = callback,
  9535. callback = null;
  9536. else if (!callback || typeof callback !== 'function')
  9537. callback = null;
  9538. if (callback)
  9539. return ProtoBuf.Util.fetch(typeof filename === 'string' ? filename : filename["root"]+"/"+filename["file"], function(contents) {
  9540. if (contents === null) {
  9541. callback(Error("Failed to fetch file"));
  9542. return;
  9543. }
  9544. try {
  9545. callback(null, ProtoBuf.loadJson(JSON.parse(contents), builder, filename));
  9546. } catch (e) {
  9547. callback(e);
  9548. }
  9549. });
  9550. var contents = ProtoBuf.Util.fetch(typeof filename === 'object' ? filename["root"]+"/"+filename["file"] : filename);
  9551. return contents === null ? null : ProtoBuf.loadJson(JSON.parse(contents), builder, filename);
  9552. };
  9553. return ProtoBuf;
  9554. });
  9555. });
  9556. var messageCompiled = protobufLight.newBuilder({})['import']({
  9557. package: 'push_server.messages2',
  9558. syntax: 'proto2',
  9559. options: {
  9560. objc_class_prefix: 'AVIM'
  9561. },
  9562. messages: [{
  9563. name: 'JsonObjectMessage',
  9564. syntax: 'proto2',
  9565. fields: [{
  9566. rule: 'required',
  9567. type: 'string',
  9568. name: 'data',
  9569. id: 1
  9570. }]
  9571. }, {
  9572. name: 'UnreadTuple',
  9573. syntax: 'proto2',
  9574. fields: [{
  9575. rule: 'required',
  9576. type: 'string',
  9577. name: 'cid',
  9578. id: 1
  9579. }, {
  9580. rule: 'required',
  9581. type: 'int32',
  9582. name: 'unread',
  9583. id: 2
  9584. }, {
  9585. rule: 'optional',
  9586. type: 'string',
  9587. name: 'mid',
  9588. id: 3
  9589. }, {
  9590. rule: 'optional',
  9591. type: 'int64',
  9592. name: 'timestamp',
  9593. id: 4
  9594. }, {
  9595. rule: 'optional',
  9596. type: 'string',
  9597. name: 'from',
  9598. id: 5
  9599. }, {
  9600. rule: 'optional',
  9601. type: 'string',
  9602. name: 'data',
  9603. id: 6
  9604. }, {
  9605. rule: 'optional',
  9606. type: 'int64',
  9607. name: 'patchTimestamp',
  9608. id: 7
  9609. }, {
  9610. rule: 'optional',
  9611. type: 'bool',
  9612. name: 'mentioned',
  9613. id: 8
  9614. }, {
  9615. rule: 'optional',
  9616. type: 'bytes',
  9617. name: 'binaryMsg',
  9618. id: 9
  9619. }, {
  9620. rule: 'optional',
  9621. type: 'int32',
  9622. name: 'convType',
  9623. id: 10
  9624. }]
  9625. }, {
  9626. name: 'LogItem',
  9627. syntax: 'proto2',
  9628. fields: [{
  9629. rule: 'optional',
  9630. type: 'string',
  9631. name: 'from',
  9632. id: 1
  9633. }, {
  9634. rule: 'optional',
  9635. type: 'string',
  9636. name: 'data',
  9637. id: 2
  9638. }, {
  9639. rule: 'optional',
  9640. type: 'int64',
  9641. name: 'timestamp',
  9642. id: 3
  9643. }, {
  9644. rule: 'optional',
  9645. type: 'string',
  9646. name: 'msgId',
  9647. id: 4
  9648. }, {
  9649. rule: 'optional',
  9650. type: 'int64',
  9651. name: 'ackAt',
  9652. id: 5
  9653. }, {
  9654. rule: 'optional',
  9655. type: 'int64',
  9656. name: 'readAt',
  9657. id: 6
  9658. }, {
  9659. rule: 'optional',
  9660. type: 'int64',
  9661. name: 'patchTimestamp',
  9662. id: 7
  9663. }, {
  9664. rule: 'optional',
  9665. type: 'bool',
  9666. name: 'mentionAll',
  9667. id: 8
  9668. }, {
  9669. rule: 'repeated',
  9670. type: 'string',
  9671. name: 'mentionPids',
  9672. id: 9
  9673. }, {
  9674. rule: 'optional',
  9675. type: 'bool',
  9676. name: 'bin',
  9677. id: 10
  9678. }, {
  9679. rule: 'optional',
  9680. type: 'int32',
  9681. name: 'convType',
  9682. id: 11
  9683. }]
  9684. }, {
  9685. name: 'ConvMemberInfo',
  9686. syntax: 'proto2',
  9687. fields: [{
  9688. rule: 'optional',
  9689. type: 'string',
  9690. name: 'pid',
  9691. id: 1
  9692. }, {
  9693. rule: 'optional',
  9694. type: 'string',
  9695. name: 'role',
  9696. id: 2
  9697. }, {
  9698. rule: 'optional',
  9699. type: 'string',
  9700. name: 'infoId',
  9701. id: 3
  9702. }]
  9703. }, {
  9704. name: 'DataCommand',
  9705. syntax: 'proto2',
  9706. fields: [{
  9707. rule: 'repeated',
  9708. type: 'string',
  9709. name: 'ids',
  9710. id: 1
  9711. }, {
  9712. rule: 'repeated',
  9713. type: 'JsonObjectMessage',
  9714. name: 'msg',
  9715. id: 2
  9716. }, {
  9717. rule: 'optional',
  9718. type: 'bool',
  9719. name: 'offline',
  9720. id: 3
  9721. }]
  9722. }, {
  9723. name: 'SessionCommand',
  9724. syntax: 'proto2',
  9725. fields: [{
  9726. rule: 'optional',
  9727. type: 'int64',
  9728. name: 't',
  9729. id: 1
  9730. }, {
  9731. rule: 'optional',
  9732. type: 'string',
  9733. name: 'n',
  9734. id: 2
  9735. }, {
  9736. rule: 'optional',
  9737. type: 'string',
  9738. name: 's',
  9739. id: 3
  9740. }, {
  9741. rule: 'optional',
  9742. type: 'string',
  9743. name: 'ua',
  9744. id: 4
  9745. }, {
  9746. rule: 'optional',
  9747. type: 'bool',
  9748. name: 'r',
  9749. id: 5
  9750. }, {
  9751. rule: 'optional',
  9752. type: 'string',
  9753. name: 'tag',
  9754. id: 6
  9755. }, {
  9756. rule: 'optional',
  9757. type: 'string',
  9758. name: 'deviceId',
  9759. id: 7
  9760. }, {
  9761. rule: 'repeated',
  9762. type: 'string',
  9763. name: 'sessionPeerIds',
  9764. id: 8
  9765. }, {
  9766. rule: 'repeated',
  9767. type: 'string',
  9768. name: 'onlineSessionPeerIds',
  9769. id: 9
  9770. }, {
  9771. rule: 'optional',
  9772. type: 'string',
  9773. name: 'st',
  9774. id: 10
  9775. }, {
  9776. rule: 'optional',
  9777. type: 'int32',
  9778. name: 'stTtl',
  9779. id: 11
  9780. }, {
  9781. rule: 'optional',
  9782. type: 'int32',
  9783. name: 'code',
  9784. id: 12
  9785. }, {
  9786. rule: 'optional',
  9787. type: 'string',
  9788. name: 'reason',
  9789. id: 13
  9790. }, {
  9791. rule: 'optional',
  9792. type: 'string',
  9793. name: 'deviceToken',
  9794. id: 14
  9795. }, {
  9796. rule: 'optional',
  9797. type: 'bool',
  9798. name: 'sp',
  9799. id: 15
  9800. }, {
  9801. rule: 'optional',
  9802. type: 'string',
  9803. name: 'detail',
  9804. id: 16
  9805. }, {
  9806. rule: 'optional',
  9807. type: 'int64',
  9808. name: 'lastUnreadNotifTime',
  9809. id: 17
  9810. }, {
  9811. rule: 'optional',
  9812. type: 'int64',
  9813. name: 'lastPatchTime',
  9814. id: 18
  9815. }, {
  9816. rule: 'optional',
  9817. type: 'int64',
  9818. name: 'configBitmap',
  9819. id: 19
  9820. }]
  9821. }, {
  9822. name: 'ErrorCommand',
  9823. syntax: 'proto2',
  9824. fields: [{
  9825. rule: 'required',
  9826. type: 'int32',
  9827. name: 'code',
  9828. id: 1
  9829. }, {
  9830. rule: 'required',
  9831. type: 'string',
  9832. name: 'reason',
  9833. id: 2
  9834. }, {
  9835. rule: 'optional',
  9836. type: 'int32',
  9837. name: 'appCode',
  9838. id: 3
  9839. }, {
  9840. rule: 'optional',
  9841. type: 'string',
  9842. name: 'detail',
  9843. id: 4
  9844. }, {
  9845. rule: 'repeated',
  9846. type: 'string',
  9847. name: 'pids',
  9848. id: 5
  9849. }, {
  9850. rule: 'optional',
  9851. type: 'string',
  9852. name: 'appMsg',
  9853. id: 6
  9854. }]
  9855. }, {
  9856. name: 'DirectCommand',
  9857. syntax: 'proto2',
  9858. fields: [{
  9859. rule: 'optional',
  9860. type: 'string',
  9861. name: 'msg',
  9862. id: 1
  9863. }, {
  9864. rule: 'optional',
  9865. type: 'string',
  9866. name: 'uid',
  9867. id: 2
  9868. }, {
  9869. rule: 'optional',
  9870. type: 'string',
  9871. name: 'fromPeerId',
  9872. id: 3
  9873. }, {
  9874. rule: 'optional',
  9875. type: 'int64',
  9876. name: 'timestamp',
  9877. id: 4
  9878. }, {
  9879. rule: 'optional',
  9880. type: 'bool',
  9881. name: 'offline',
  9882. id: 5
  9883. }, {
  9884. rule: 'optional',
  9885. type: 'bool',
  9886. name: 'hasMore',
  9887. id: 6
  9888. }, {
  9889. rule: 'repeated',
  9890. type: 'string',
  9891. name: 'toPeerIds',
  9892. id: 7
  9893. }, {
  9894. rule: 'optional',
  9895. type: 'bool',
  9896. name: 'r',
  9897. id: 10
  9898. }, {
  9899. rule: 'optional',
  9900. type: 'string',
  9901. name: 'cid',
  9902. id: 11
  9903. }, {
  9904. rule: 'optional',
  9905. type: 'string',
  9906. name: 'id',
  9907. id: 12
  9908. }, {
  9909. rule: 'optional',
  9910. type: 'bool',
  9911. name: 'transient',
  9912. id: 13
  9913. }, {
  9914. rule: 'optional',
  9915. type: 'string',
  9916. name: 'dt',
  9917. id: 14
  9918. }, {
  9919. rule: 'optional',
  9920. type: 'string',
  9921. name: 'roomId',
  9922. id: 15
  9923. }, {
  9924. rule: 'optional',
  9925. type: 'string',
  9926. name: 'pushData',
  9927. id: 16
  9928. }, {
  9929. rule: 'optional',
  9930. type: 'bool',
  9931. name: 'will',
  9932. id: 17
  9933. }, {
  9934. rule: 'optional',
  9935. type: 'int64',
  9936. name: 'patchTimestamp',
  9937. id: 18
  9938. }, {
  9939. rule: 'optional',
  9940. type: 'bytes',
  9941. name: 'binaryMsg',
  9942. id: 19
  9943. }, {
  9944. rule: 'repeated',
  9945. type: 'string',
  9946. name: 'mentionPids',
  9947. id: 20
  9948. }, {
  9949. rule: 'optional',
  9950. type: 'bool',
  9951. name: 'mentionAll',
  9952. id: 21
  9953. }, {
  9954. rule: 'optional',
  9955. type: 'int32',
  9956. name: 'convType',
  9957. id: 22
  9958. }]
  9959. }, {
  9960. name: 'AckCommand',
  9961. syntax: 'proto2',
  9962. fields: [{
  9963. rule: 'optional',
  9964. type: 'int32',
  9965. name: 'code',
  9966. id: 1
  9967. }, {
  9968. rule: 'optional',
  9969. type: 'string',
  9970. name: 'reason',
  9971. id: 2
  9972. }, {
  9973. rule: 'optional',
  9974. type: 'string',
  9975. name: 'mid',
  9976. id: 3
  9977. }, {
  9978. rule: 'optional',
  9979. type: 'string',
  9980. name: 'cid',
  9981. id: 4
  9982. }, {
  9983. rule: 'optional',
  9984. type: 'int64',
  9985. name: 't',
  9986. id: 5
  9987. }, {
  9988. rule: 'optional',
  9989. type: 'string',
  9990. name: 'uid',
  9991. id: 6
  9992. }, {
  9993. rule: 'optional',
  9994. type: 'int64',
  9995. name: 'fromts',
  9996. id: 7
  9997. }, {
  9998. rule: 'optional',
  9999. type: 'int64',
  10000. name: 'tots',
  10001. id: 8
  10002. }, {
  10003. rule: 'optional',
  10004. type: 'string',
  10005. name: 'type',
  10006. id: 9
  10007. }, {
  10008. rule: 'repeated',
  10009. type: 'string',
  10010. name: 'ids',
  10011. id: 10
  10012. }, {
  10013. rule: 'optional',
  10014. type: 'int32',
  10015. name: 'appCode',
  10016. id: 11
  10017. }, {
  10018. rule: 'optional',
  10019. type: 'string',
  10020. name: 'appMsg',
  10021. id: 12
  10022. }]
  10023. }, {
  10024. name: 'UnreadCommand',
  10025. syntax: 'proto2',
  10026. fields: [{
  10027. rule: 'repeated',
  10028. type: 'UnreadTuple',
  10029. name: 'convs',
  10030. id: 1
  10031. }, {
  10032. rule: 'optional',
  10033. type: 'int64',
  10034. name: 'notifTime',
  10035. id: 2
  10036. }]
  10037. }, {
  10038. name: 'ConvCommand',
  10039. syntax: 'proto2',
  10040. fields: [{
  10041. rule: 'repeated',
  10042. type: 'string',
  10043. name: 'm',
  10044. id: 1
  10045. }, {
  10046. rule: 'optional',
  10047. type: 'bool',
  10048. name: 'transient',
  10049. id: 2
  10050. }, {
  10051. rule: 'optional',
  10052. type: 'bool',
  10053. name: 'unique',
  10054. id: 3
  10055. }, {
  10056. rule: 'optional',
  10057. type: 'string',
  10058. name: 'cid',
  10059. id: 4
  10060. }, {
  10061. rule: 'optional',
  10062. type: 'string',
  10063. name: 'cdate',
  10064. id: 5
  10065. }, {
  10066. rule: 'optional',
  10067. type: 'string',
  10068. name: 'initBy',
  10069. id: 6
  10070. }, {
  10071. rule: 'optional',
  10072. type: 'string',
  10073. name: 'sort',
  10074. id: 7
  10075. }, {
  10076. rule: 'optional',
  10077. type: 'int32',
  10078. name: 'limit',
  10079. id: 8
  10080. }, {
  10081. rule: 'optional',
  10082. type: 'int32',
  10083. name: 'skip',
  10084. id: 9
  10085. }, {
  10086. rule: 'optional',
  10087. type: 'int32',
  10088. name: 'flag',
  10089. id: 10
  10090. }, {
  10091. rule: 'optional',
  10092. type: 'int32',
  10093. name: 'count',
  10094. id: 11
  10095. }, {
  10096. rule: 'optional',
  10097. type: 'string',
  10098. name: 'udate',
  10099. id: 12
  10100. }, {
  10101. rule: 'optional',
  10102. type: 'int64',
  10103. name: 't',
  10104. id: 13
  10105. }, {
  10106. rule: 'optional',
  10107. type: 'string',
  10108. name: 'n',
  10109. id: 14
  10110. }, {
  10111. rule: 'optional',
  10112. type: 'string',
  10113. name: 's',
  10114. id: 15
  10115. }, {
  10116. rule: 'optional',
  10117. type: 'bool',
  10118. name: 'statusSub',
  10119. id: 16
  10120. }, {
  10121. rule: 'optional',
  10122. type: 'bool',
  10123. name: 'statusPub',
  10124. id: 17
  10125. }, {
  10126. rule: 'optional',
  10127. type: 'int32',
  10128. name: 'statusTTL',
  10129. id: 18
  10130. }, {
  10131. rule: 'optional',
  10132. type: 'string',
  10133. name: 'uniqueId',
  10134. id: 19
  10135. }, {
  10136. rule: 'optional',
  10137. type: 'string',
  10138. name: 'targetClientId',
  10139. id: 20
  10140. }, {
  10141. rule: 'optional',
  10142. type: 'int64',
  10143. name: 'maxReadTimestamp',
  10144. id: 21
  10145. }, {
  10146. rule: 'optional',
  10147. type: 'int64',
  10148. name: 'maxAckTimestamp',
  10149. id: 22
  10150. }, {
  10151. rule: 'optional',
  10152. type: 'bool',
  10153. name: 'queryAllMembers',
  10154. id: 23
  10155. }, {
  10156. rule: 'repeated',
  10157. type: 'MaxReadTuple',
  10158. name: 'maxReadTuples',
  10159. id: 24
  10160. }, {
  10161. rule: 'repeated',
  10162. type: 'string',
  10163. name: 'cids',
  10164. id: 25
  10165. }, {
  10166. rule: 'optional',
  10167. type: 'ConvMemberInfo',
  10168. name: 'info',
  10169. id: 26
  10170. }, {
  10171. rule: 'optional',
  10172. type: 'bool',
  10173. name: 'tempConv',
  10174. id: 27
  10175. }, {
  10176. rule: 'optional',
  10177. type: 'int32',
  10178. name: 'tempConvTTL',
  10179. id: 28
  10180. }, {
  10181. rule: 'repeated',
  10182. type: 'string',
  10183. name: 'tempConvIds',
  10184. id: 29
  10185. }, {
  10186. rule: 'repeated',
  10187. type: 'string',
  10188. name: 'allowedPids',
  10189. id: 30
  10190. }, {
  10191. rule: 'repeated',
  10192. type: 'ErrorCommand',
  10193. name: 'failedPids',
  10194. id: 31
  10195. }, {
  10196. rule: 'optional',
  10197. type: 'string',
  10198. name: 'next',
  10199. id: 40
  10200. }, {
  10201. rule: 'optional',
  10202. type: 'JsonObjectMessage',
  10203. name: 'results',
  10204. id: 100
  10205. }, {
  10206. rule: 'optional',
  10207. type: 'JsonObjectMessage',
  10208. name: 'where',
  10209. id: 101
  10210. }, {
  10211. rule: 'optional',
  10212. type: 'JsonObjectMessage',
  10213. name: 'attr',
  10214. id: 103
  10215. }, {
  10216. rule: 'optional',
  10217. type: 'JsonObjectMessage',
  10218. name: 'attrModified',
  10219. id: 104
  10220. }]
  10221. }, {
  10222. name: 'RoomCommand',
  10223. syntax: 'proto2',
  10224. fields: [{
  10225. rule: 'optional',
  10226. type: 'string',
  10227. name: 'roomId',
  10228. id: 1
  10229. }, {
  10230. rule: 'optional',
  10231. type: 'string',
  10232. name: 's',
  10233. id: 2
  10234. }, {
  10235. rule: 'optional',
  10236. type: 'int64',
  10237. name: 't',
  10238. id: 3
  10239. }, {
  10240. rule: 'optional',
  10241. type: 'string',
  10242. name: 'n',
  10243. id: 4
  10244. }, {
  10245. rule: 'optional',
  10246. type: 'bool',
  10247. name: 'transient',
  10248. id: 5
  10249. }, {
  10250. rule: 'repeated',
  10251. type: 'string',
  10252. name: 'roomPeerIds',
  10253. id: 6
  10254. }, {
  10255. rule: 'optional',
  10256. type: 'string',
  10257. name: 'byPeerId',
  10258. id: 7
  10259. }]
  10260. }, {
  10261. name: 'LogsCommand',
  10262. syntax: 'proto2',
  10263. fields: [{
  10264. rule: 'optional',
  10265. type: 'string',
  10266. name: 'cid',
  10267. id: 1
  10268. }, {
  10269. rule: 'optional',
  10270. type: 'int32',
  10271. name: 'l',
  10272. id: 2
  10273. }, {
  10274. rule: 'optional',
  10275. type: 'int32',
  10276. name: 'limit',
  10277. id: 3
  10278. }, {
  10279. rule: 'optional',
  10280. type: 'int64',
  10281. name: 't',
  10282. id: 4
  10283. }, {
  10284. rule: 'optional',
  10285. type: 'int64',
  10286. name: 'tt',
  10287. id: 5
  10288. }, {
  10289. rule: 'optional',
  10290. type: 'string',
  10291. name: 'tmid',
  10292. id: 6
  10293. }, {
  10294. rule: 'optional',
  10295. type: 'string',
  10296. name: 'mid',
  10297. id: 7
  10298. }, {
  10299. rule: 'optional',
  10300. type: 'string',
  10301. name: 'checksum',
  10302. id: 8
  10303. }, {
  10304. rule: 'optional',
  10305. type: 'bool',
  10306. name: 'stored',
  10307. id: 9
  10308. }, {
  10309. rule: 'optional',
  10310. type: 'QueryDirection',
  10311. name: 'direction',
  10312. id: 10,
  10313. options: {
  10314. default: 'OLD'
  10315. }
  10316. }, {
  10317. rule: 'optional',
  10318. type: 'bool',
  10319. name: 'tIncluded',
  10320. id: 11
  10321. }, {
  10322. rule: 'optional',
  10323. type: 'bool',
  10324. name: 'ttIncluded',
  10325. id: 12
  10326. }, {
  10327. rule: 'optional',
  10328. type: 'int32',
  10329. name: 'lctype',
  10330. id: 13
  10331. }, {
  10332. rule: 'repeated',
  10333. type: 'LogItem',
  10334. name: 'logs',
  10335. id: 105
  10336. }],
  10337. enums: [{
  10338. name: 'QueryDirection',
  10339. syntax: 'proto2',
  10340. values: [{
  10341. name: 'OLD',
  10342. id: 1
  10343. }, {
  10344. name: 'NEW',
  10345. id: 2
  10346. }]
  10347. }]
  10348. }, {
  10349. name: 'RcpCommand',
  10350. syntax: 'proto2',
  10351. fields: [{
  10352. rule: 'optional',
  10353. type: 'string',
  10354. name: 'id',
  10355. id: 1
  10356. }, {
  10357. rule: 'optional',
  10358. type: 'string',
  10359. name: 'cid',
  10360. id: 2
  10361. }, {
  10362. rule: 'optional',
  10363. type: 'int64',
  10364. name: 't',
  10365. id: 3
  10366. }, {
  10367. rule: 'optional',
  10368. type: 'bool',
  10369. name: 'read',
  10370. id: 4
  10371. }, {
  10372. rule: 'optional',
  10373. type: 'string',
  10374. name: 'from',
  10375. id: 5
  10376. }]
  10377. }, {
  10378. name: 'ReadTuple',
  10379. syntax: 'proto2',
  10380. fields: [{
  10381. rule: 'required',
  10382. type: 'string',
  10383. name: 'cid',
  10384. id: 1
  10385. }, {
  10386. rule: 'optional',
  10387. type: 'int64',
  10388. name: 'timestamp',
  10389. id: 2
  10390. }, {
  10391. rule: 'optional',
  10392. type: 'string',
  10393. name: 'mid',
  10394. id: 3
  10395. }]
  10396. }, {
  10397. name: 'MaxReadTuple',
  10398. syntax: 'proto2',
  10399. fields: [{
  10400. rule: 'optional',
  10401. type: 'string',
  10402. name: 'pid',
  10403. id: 1
  10404. }, {
  10405. rule: 'optional',
  10406. type: 'int64',
  10407. name: 'maxAckTimestamp',
  10408. id: 2
  10409. }, {
  10410. rule: 'optional',
  10411. type: 'int64',
  10412. name: 'maxReadTimestamp',
  10413. id: 3
  10414. }]
  10415. }, {
  10416. name: 'ReadCommand',
  10417. syntax: 'proto2',
  10418. fields: [{
  10419. rule: 'optional',
  10420. type: 'string',
  10421. name: 'cid',
  10422. id: 1
  10423. }, {
  10424. rule: 'repeated',
  10425. type: 'string',
  10426. name: 'cids',
  10427. id: 2
  10428. }, {
  10429. rule: 'repeated',
  10430. type: 'ReadTuple',
  10431. name: 'convs',
  10432. id: 3
  10433. }]
  10434. }, {
  10435. name: 'PresenceCommand',
  10436. syntax: 'proto2',
  10437. fields: [{
  10438. rule: 'optional',
  10439. type: 'StatusType',
  10440. name: 'status',
  10441. id: 1
  10442. }, {
  10443. rule: 'repeated',
  10444. type: 'string',
  10445. name: 'sessionPeerIds',
  10446. id: 2
  10447. }, {
  10448. rule: 'optional',
  10449. type: 'string',
  10450. name: 'cid',
  10451. id: 3
  10452. }]
  10453. }, {
  10454. name: 'ReportCommand',
  10455. syntax: 'proto2',
  10456. fields: [{
  10457. rule: 'optional',
  10458. type: 'bool',
  10459. name: 'initiative',
  10460. id: 1
  10461. }, {
  10462. rule: 'optional',
  10463. type: 'string',
  10464. name: 'type',
  10465. id: 2
  10466. }, {
  10467. rule: 'optional',
  10468. type: 'string',
  10469. name: 'data',
  10470. id: 3
  10471. }]
  10472. }, {
  10473. name: 'PatchItem',
  10474. syntax: 'proto2',
  10475. fields: [{
  10476. rule: 'optional',
  10477. type: 'string',
  10478. name: 'cid',
  10479. id: 1
  10480. }, {
  10481. rule: 'optional',
  10482. type: 'string',
  10483. name: 'mid',
  10484. id: 2
  10485. }, {
  10486. rule: 'optional',
  10487. type: 'int64',
  10488. name: 'timestamp',
  10489. id: 3
  10490. }, {
  10491. rule: 'optional',
  10492. type: 'bool',
  10493. name: 'recall',
  10494. id: 4
  10495. }, {
  10496. rule: 'optional',
  10497. type: 'string',
  10498. name: 'data',
  10499. id: 5
  10500. }, {
  10501. rule: 'optional',
  10502. type: 'int64',
  10503. name: 'patchTimestamp',
  10504. id: 6
  10505. }, {
  10506. rule: 'optional',
  10507. type: 'string',
  10508. name: 'from',
  10509. id: 7
  10510. }, {
  10511. rule: 'optional',
  10512. type: 'bytes',
  10513. name: 'binaryMsg',
  10514. id: 8
  10515. }, {
  10516. rule: 'optional',
  10517. type: 'bool',
  10518. name: 'mentionAll',
  10519. id: 9
  10520. }, {
  10521. rule: 'repeated',
  10522. type: 'string',
  10523. name: 'mentionPids',
  10524. id: 10
  10525. }, {
  10526. rule: 'optional',
  10527. type: 'int64',
  10528. name: 'patchCode',
  10529. id: 11
  10530. }, {
  10531. rule: 'optional',
  10532. type: 'string',
  10533. name: 'patchReason',
  10534. id: 12
  10535. }]
  10536. }, {
  10537. name: 'PatchCommand',
  10538. syntax: 'proto2',
  10539. fields: [{
  10540. rule: 'repeated',
  10541. type: 'PatchItem',
  10542. name: 'patches',
  10543. id: 1
  10544. }, {
  10545. rule: 'optional',
  10546. type: 'int64',
  10547. name: 'lastPatchTime',
  10548. id: 2
  10549. }]
  10550. }, {
  10551. name: 'PubsubCommand',
  10552. syntax: 'proto2',
  10553. fields: [{
  10554. rule: 'optional',
  10555. type: 'string',
  10556. name: 'cid',
  10557. id: 1
  10558. }, {
  10559. rule: 'repeated',
  10560. type: 'string',
  10561. name: 'cids',
  10562. id: 2
  10563. }, {
  10564. rule: 'optional',
  10565. type: 'string',
  10566. name: 'topic',
  10567. id: 3
  10568. }, {
  10569. rule: 'optional',
  10570. type: 'string',
  10571. name: 'subtopic',
  10572. id: 4
  10573. }, {
  10574. rule: 'repeated',
  10575. type: 'string',
  10576. name: 'topics',
  10577. id: 5
  10578. }, {
  10579. rule: 'repeated',
  10580. type: 'string',
  10581. name: 'subtopics',
  10582. id: 6
  10583. }, {
  10584. rule: 'optional',
  10585. type: 'JsonObjectMessage',
  10586. name: 'results',
  10587. id: 7
  10588. }]
  10589. }, {
  10590. name: 'BlacklistCommand',
  10591. syntax: 'proto2',
  10592. fields: [{
  10593. rule: 'optional',
  10594. type: 'string',
  10595. name: 'srcCid',
  10596. id: 1
  10597. }, {
  10598. rule: 'repeated',
  10599. type: 'string',
  10600. name: 'toPids',
  10601. id: 2
  10602. }, {
  10603. rule: 'optional',
  10604. type: 'string',
  10605. name: 'srcPid',
  10606. id: 3
  10607. }, {
  10608. rule: 'repeated',
  10609. type: 'string',
  10610. name: 'toCids',
  10611. id: 4
  10612. }, {
  10613. rule: 'optional',
  10614. type: 'int32',
  10615. name: 'limit',
  10616. id: 5
  10617. }, {
  10618. rule: 'optional',
  10619. type: 'string',
  10620. name: 'next',
  10621. id: 6
  10622. }, {
  10623. rule: 'repeated',
  10624. type: 'string',
  10625. name: 'blockedPids',
  10626. id: 8
  10627. }, {
  10628. rule: 'repeated',
  10629. type: 'string',
  10630. name: 'blockedCids',
  10631. id: 9
  10632. }, {
  10633. rule: 'repeated',
  10634. type: 'string',
  10635. name: 'allowedPids',
  10636. id: 10
  10637. }, {
  10638. rule: 'repeated',
  10639. type: 'ErrorCommand',
  10640. name: 'failedPids',
  10641. id: 11
  10642. }, {
  10643. rule: 'optional',
  10644. type: 'int64',
  10645. name: 't',
  10646. id: 12
  10647. }, {
  10648. rule: 'optional',
  10649. type: 'string',
  10650. name: 'n',
  10651. id: 13
  10652. }, {
  10653. rule: 'optional',
  10654. type: 'string',
  10655. name: 's',
  10656. id: 14
  10657. }]
  10658. }, {
  10659. name: 'GenericCommand',
  10660. syntax: 'proto2',
  10661. fields: [{
  10662. rule: 'optional',
  10663. type: 'CommandType',
  10664. name: 'cmd',
  10665. id: 1
  10666. }, {
  10667. rule: 'optional',
  10668. type: 'OpType',
  10669. name: 'op',
  10670. id: 2
  10671. }, {
  10672. rule: 'optional',
  10673. type: 'string',
  10674. name: 'appId',
  10675. id: 3
  10676. }, {
  10677. rule: 'optional',
  10678. type: 'string',
  10679. name: 'peerId',
  10680. id: 4
  10681. }, {
  10682. rule: 'optional',
  10683. type: 'int32',
  10684. name: 'i',
  10685. id: 5
  10686. }, {
  10687. rule: 'optional',
  10688. type: 'string',
  10689. name: 'installationId',
  10690. id: 6
  10691. }, {
  10692. rule: 'optional',
  10693. type: 'int32',
  10694. name: 'priority',
  10695. id: 7
  10696. }, {
  10697. rule: 'optional',
  10698. type: 'int32',
  10699. name: 'service',
  10700. id: 8
  10701. }, {
  10702. rule: 'optional',
  10703. type: 'int64',
  10704. name: 'serverTs',
  10705. id: 9
  10706. }, {
  10707. rule: 'optional',
  10708. type: 'int64',
  10709. name: 'clientTs',
  10710. id: 10
  10711. }, {
  10712. rule: 'optional',
  10713. type: 'int32',
  10714. name: 'notificationType',
  10715. id: 11
  10716. }, {
  10717. rule: 'optional',
  10718. type: 'DataCommand',
  10719. name: 'dataMessage',
  10720. id: 101
  10721. }, {
  10722. rule: 'optional',
  10723. type: 'SessionCommand',
  10724. name: 'sessionMessage',
  10725. id: 102
  10726. }, {
  10727. rule: 'optional',
  10728. type: 'ErrorCommand',
  10729. name: 'errorMessage',
  10730. id: 103
  10731. }, {
  10732. rule: 'optional',
  10733. type: 'DirectCommand',
  10734. name: 'directMessage',
  10735. id: 104
  10736. }, {
  10737. rule: 'optional',
  10738. type: 'AckCommand',
  10739. name: 'ackMessage',
  10740. id: 105
  10741. }, {
  10742. rule: 'optional',
  10743. type: 'UnreadCommand',
  10744. name: 'unreadMessage',
  10745. id: 106
  10746. }, {
  10747. rule: 'optional',
  10748. type: 'ReadCommand',
  10749. name: 'readMessage',
  10750. id: 107
  10751. }, {
  10752. rule: 'optional',
  10753. type: 'RcpCommand',
  10754. name: 'rcpMessage',
  10755. id: 108
  10756. }, {
  10757. rule: 'optional',
  10758. type: 'LogsCommand',
  10759. name: 'logsMessage',
  10760. id: 109
  10761. }, {
  10762. rule: 'optional',
  10763. type: 'ConvCommand',
  10764. name: 'convMessage',
  10765. id: 110
  10766. }, {
  10767. rule: 'optional',
  10768. type: 'RoomCommand',
  10769. name: 'roomMessage',
  10770. id: 111
  10771. }, {
  10772. rule: 'optional',
  10773. type: 'PresenceCommand',
  10774. name: 'presenceMessage',
  10775. id: 112
  10776. }, {
  10777. rule: 'optional',
  10778. type: 'ReportCommand',
  10779. name: 'reportMessage',
  10780. id: 113
  10781. }, {
  10782. rule: 'optional',
  10783. type: 'PatchCommand',
  10784. name: 'patchMessage',
  10785. id: 114
  10786. }, {
  10787. rule: 'optional',
  10788. type: 'PubsubCommand',
  10789. name: 'pubsubMessage',
  10790. id: 115
  10791. }, {
  10792. rule: 'optional',
  10793. type: 'BlacklistCommand',
  10794. name: 'blacklistMessage',
  10795. id: 116
  10796. }]
  10797. }],
  10798. enums: [{
  10799. name: 'CommandType',
  10800. syntax: 'proto2',
  10801. values: [{
  10802. name: 'session',
  10803. id: 0
  10804. }, {
  10805. name: 'conv',
  10806. id: 1
  10807. }, {
  10808. name: 'direct',
  10809. id: 2
  10810. }, {
  10811. name: 'ack',
  10812. id: 3
  10813. }, {
  10814. name: 'rcp',
  10815. id: 4
  10816. }, {
  10817. name: 'unread',
  10818. id: 5
  10819. }, {
  10820. name: 'logs',
  10821. id: 6
  10822. }, {
  10823. name: 'error',
  10824. id: 7
  10825. }, {
  10826. name: 'login',
  10827. id: 8
  10828. }, {
  10829. name: 'data',
  10830. id: 9
  10831. }, {
  10832. name: 'room',
  10833. id: 10
  10834. }, {
  10835. name: 'read',
  10836. id: 11
  10837. }, {
  10838. name: 'presence',
  10839. id: 12
  10840. }, {
  10841. name: 'report',
  10842. id: 13
  10843. }, {
  10844. name: 'echo',
  10845. id: 14
  10846. }, {
  10847. name: 'loggedin',
  10848. id: 15
  10849. }, {
  10850. name: 'logout',
  10851. id: 16
  10852. }, {
  10853. name: 'loggedout',
  10854. id: 17
  10855. }, {
  10856. name: 'patch',
  10857. id: 18
  10858. }, {
  10859. name: 'pubsub',
  10860. id: 19
  10861. }, {
  10862. name: 'blacklist',
  10863. id: 20
  10864. }, {
  10865. name: 'goaway',
  10866. id: 21
  10867. }]
  10868. }, {
  10869. name: 'OpType',
  10870. syntax: 'proto2',
  10871. values: [{
  10872. name: 'open',
  10873. id: 1
  10874. }, {
  10875. name: 'add',
  10876. id: 2
  10877. }, {
  10878. name: 'remove',
  10879. id: 3
  10880. }, {
  10881. name: 'close',
  10882. id: 4
  10883. }, {
  10884. name: 'opened',
  10885. id: 5
  10886. }, {
  10887. name: 'closed',
  10888. id: 6
  10889. }, {
  10890. name: 'query',
  10891. id: 7
  10892. }, {
  10893. name: 'query_result',
  10894. id: 8
  10895. }, {
  10896. name: 'conflict',
  10897. id: 9
  10898. }, {
  10899. name: 'added',
  10900. id: 10
  10901. }, {
  10902. name: 'removed',
  10903. id: 11
  10904. }, {
  10905. name: 'refresh',
  10906. id: 12
  10907. }, {
  10908. name: 'refreshed',
  10909. id: 13
  10910. }, {
  10911. name: 'start',
  10912. id: 30
  10913. }, {
  10914. name: 'started',
  10915. id: 31
  10916. }, {
  10917. name: 'joined',
  10918. id: 32
  10919. }, {
  10920. name: 'members_joined',
  10921. id: 33
  10922. }, {
  10923. name: 'left',
  10924. id: 39
  10925. }, {
  10926. name: 'members_left',
  10927. id: 40
  10928. }, {
  10929. name: 'results',
  10930. id: 42
  10931. }, {
  10932. name: 'count',
  10933. id: 43
  10934. }, {
  10935. name: 'result',
  10936. id: 44
  10937. }, {
  10938. name: 'update',
  10939. id: 45
  10940. }, {
  10941. name: 'updated',
  10942. id: 46
  10943. }, {
  10944. name: 'mute',
  10945. id: 47
  10946. }, {
  10947. name: 'unmute',
  10948. id: 48
  10949. }, {
  10950. name: 'status',
  10951. id: 49
  10952. }, {
  10953. name: 'members',
  10954. id: 50
  10955. }, {
  10956. name: 'max_read',
  10957. id: 51
  10958. }, {
  10959. name: 'is_member',
  10960. id: 52
  10961. }, {
  10962. name: 'member_info_update',
  10963. id: 53
  10964. }, {
  10965. name: 'member_info_updated',
  10966. id: 54
  10967. }, {
  10968. name: 'member_info_changed',
  10969. id: 55
  10970. }, {
  10971. name: 'join',
  10972. id: 80
  10973. }, {
  10974. name: 'invite',
  10975. id: 81
  10976. }, {
  10977. name: 'leave',
  10978. id: 82
  10979. }, {
  10980. name: 'kick',
  10981. id: 83
  10982. }, {
  10983. name: 'reject',
  10984. id: 84
  10985. }, {
  10986. name: 'invited',
  10987. id: 85
  10988. }, {
  10989. name: 'kicked',
  10990. id: 86
  10991. }, {
  10992. name: 'upload',
  10993. id: 100
  10994. }, {
  10995. name: 'uploaded',
  10996. id: 101
  10997. }, {
  10998. name: 'subscribe',
  10999. id: 120
  11000. }, {
  11001. name: 'subscribed',
  11002. id: 121
  11003. }, {
  11004. name: 'unsubscribe',
  11005. id: 122
  11006. }, {
  11007. name: 'unsubscribed',
  11008. id: 123
  11009. }, {
  11010. name: 'is_subscribed',
  11011. id: 124
  11012. }, {
  11013. name: 'modify',
  11014. id: 150
  11015. }, {
  11016. name: 'modified',
  11017. id: 151
  11018. }, {
  11019. name: 'block',
  11020. id: 170
  11021. }, {
  11022. name: 'unblock',
  11023. id: 171
  11024. }, {
  11025. name: 'blocked',
  11026. id: 172
  11027. }, {
  11028. name: 'unblocked',
  11029. id: 173
  11030. }, {
  11031. name: 'members_blocked',
  11032. id: 174
  11033. }, {
  11034. name: 'members_unblocked',
  11035. id: 175
  11036. }, {
  11037. name: 'check_block',
  11038. id: 176
  11039. }, {
  11040. name: 'check_result',
  11041. id: 177
  11042. }, {
  11043. name: 'add_shutup',
  11044. id: 180
  11045. }, {
  11046. name: 'remove_shutup',
  11047. id: 181
  11048. }, {
  11049. name: 'query_shutup',
  11050. id: 182
  11051. }, {
  11052. name: 'shutup_added',
  11053. id: 183
  11054. }, {
  11055. name: 'shutup_removed',
  11056. id: 184
  11057. }, {
  11058. name: 'shutup_result',
  11059. id: 185
  11060. }, {
  11061. name: 'shutuped',
  11062. id: 186
  11063. }, {
  11064. name: 'unshutuped',
  11065. id: 187
  11066. }, {
  11067. name: 'members_shutuped',
  11068. id: 188
  11069. }, {
  11070. name: 'members_unshutuped',
  11071. id: 189
  11072. }, {
  11073. name: 'check_shutup',
  11074. id: 190
  11075. }]
  11076. }, {
  11077. name: 'StatusType',
  11078. syntax: 'proto2',
  11079. values: [{
  11080. name: 'on',
  11081. id: 1
  11082. }, {
  11083. name: 'off',
  11084. id: 2
  11085. }]
  11086. }],
  11087. isNamespace: true
  11088. }).build();
  11089. const {
  11090. JsonObjectMessage,
  11091. UnreadTuple,
  11092. LogItem,
  11093. DataCommand,
  11094. SessionCommand,
  11095. ErrorCommand,
  11096. DirectCommand,
  11097. AckCommand,
  11098. UnreadCommand,
  11099. ConvCommand,
  11100. RoomCommand,
  11101. LogsCommand,
  11102. RcpCommand,
  11103. ReadTuple,
  11104. MaxReadTuple,
  11105. ReadCommand,
  11106. PresenceCommand,
  11107. ReportCommand,
  11108. GenericCommand,
  11109. BlacklistCommand,
  11110. PatchCommand,
  11111. PatchItem,
  11112. ConvMemberInfo,
  11113. CommandType,
  11114. OpType,
  11115. StatusType
  11116. } = messageCompiled.push_server.messages2;
  11117. var message = /*#__PURE__*/Object.freeze({
  11118. __proto__: null,
  11119. JsonObjectMessage: JsonObjectMessage,
  11120. UnreadTuple: UnreadTuple,
  11121. LogItem: LogItem,
  11122. DataCommand: DataCommand,
  11123. SessionCommand: SessionCommand,
  11124. ErrorCommand: ErrorCommand,
  11125. DirectCommand: DirectCommand,
  11126. AckCommand: AckCommand,
  11127. UnreadCommand: UnreadCommand,
  11128. ConvCommand: ConvCommand,
  11129. RoomCommand: RoomCommand,
  11130. LogsCommand: LogsCommand,
  11131. RcpCommand: RcpCommand,
  11132. ReadTuple: ReadTuple,
  11133. MaxReadTuple: MaxReadTuple,
  11134. ReadCommand: ReadCommand,
  11135. PresenceCommand: PresenceCommand,
  11136. ReportCommand: ReportCommand,
  11137. GenericCommand: GenericCommand,
  11138. BlacklistCommand: BlacklistCommand,
  11139. PatchCommand: PatchCommand,
  11140. PatchItem: PatchItem,
  11141. ConvMemberInfo: ConvMemberInfo,
  11142. CommandType: CommandType,
  11143. OpType: OpType,
  11144. StatusType: StatusType
  11145. });
  11146. var eventemitter3 = createCommonjsModule(function (module) {
  11147. var has = Object.prototype.hasOwnProperty
  11148. , prefix = '~';
  11149. /**
  11150. * Constructor to create a storage for our `EE` objects.
  11151. * An `Events` instance is a plain object whose properties are event names.
  11152. *
  11153. * @constructor
  11154. * @private
  11155. */
  11156. function Events() {}
  11157. //
  11158. // We try to not inherit from `Object.prototype`. In some engines creating an
  11159. // instance in this way is faster than calling `Object.create(null)` directly.
  11160. // If `Object.create(null)` is not supported we prefix the event names with a
  11161. // character to make sure that the built-in object properties are not
  11162. // overridden or used as an attack vector.
  11163. //
  11164. if (Object.create) {
  11165. Events.prototype = Object.create(null);
  11166. //
  11167. // This hack is needed because the `__proto__` property is still inherited in
  11168. // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
  11169. //
  11170. if (!new Events().__proto__) prefix = false;
  11171. }
  11172. /**
  11173. * Representation of a single event listener.
  11174. *
  11175. * @param {Function} fn The listener function.
  11176. * @param {*} context The context to invoke the listener with.
  11177. * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
  11178. * @constructor
  11179. * @private
  11180. */
  11181. function EE(fn, context, once) {
  11182. this.fn = fn;
  11183. this.context = context;
  11184. this.once = once || false;
  11185. }
  11186. /**
  11187. * Add a listener for a given event.
  11188. *
  11189. * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
  11190. * @param {(String|Symbol)} event The event name.
  11191. * @param {Function} fn The listener function.
  11192. * @param {*} context The context to invoke the listener with.
  11193. * @param {Boolean} once Specify if the listener is a one-time listener.
  11194. * @returns {EventEmitter}
  11195. * @private
  11196. */
  11197. function addListener(emitter, event, fn, context, once) {
  11198. if (typeof fn !== 'function') {
  11199. throw new TypeError('The listener must be a function');
  11200. }
  11201. var listener = new EE(fn, context || emitter, once)
  11202. , evt = prefix ? prefix + event : event;
  11203. if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
  11204. else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
  11205. else emitter._events[evt] = [emitter._events[evt], listener];
  11206. return emitter;
  11207. }
  11208. /**
  11209. * Clear event by name.
  11210. *
  11211. * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
  11212. * @param {(String|Symbol)} evt The Event name.
  11213. * @private
  11214. */
  11215. function clearEvent(emitter, evt) {
  11216. if (--emitter._eventsCount === 0) emitter._events = new Events();
  11217. else delete emitter._events[evt];
  11218. }
  11219. /**
  11220. * Minimal `EventEmitter` interface that is molded against the Node.js
  11221. * `EventEmitter` interface.
  11222. *
  11223. * @constructor
  11224. * @public
  11225. */
  11226. function EventEmitter() {
  11227. this._events = new Events();
  11228. this._eventsCount = 0;
  11229. }
  11230. /**
  11231. * Return an array listing the events for which the emitter has registered
  11232. * listeners.
  11233. *
  11234. * @returns {Array}
  11235. * @public
  11236. */
  11237. EventEmitter.prototype.eventNames = function eventNames() {
  11238. var names = []
  11239. , events
  11240. , name;
  11241. if (this._eventsCount === 0) return names;
  11242. for (name in (events = this._events)) {
  11243. if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
  11244. }
  11245. if (Object.getOwnPropertySymbols) {
  11246. return names.concat(Object.getOwnPropertySymbols(events));
  11247. }
  11248. return names;
  11249. };
  11250. /**
  11251. * Return the listeners registered for a given event.
  11252. *
  11253. * @param {(String|Symbol)} event The event name.
  11254. * @returns {Array} The registered listeners.
  11255. * @public
  11256. */
  11257. EventEmitter.prototype.listeners = function listeners(event) {
  11258. var evt = prefix ? prefix + event : event
  11259. , handlers = this._events[evt];
  11260. if (!handlers) return [];
  11261. if (handlers.fn) return [handlers.fn];
  11262. for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
  11263. ee[i] = handlers[i].fn;
  11264. }
  11265. return ee;
  11266. };
  11267. /**
  11268. * Return the number of listeners listening to a given event.
  11269. *
  11270. * @param {(String|Symbol)} event The event name.
  11271. * @returns {Number} The number of listeners.
  11272. * @public
  11273. */
  11274. EventEmitter.prototype.listenerCount = function listenerCount(event) {
  11275. var evt = prefix ? prefix + event : event
  11276. , listeners = this._events[evt];
  11277. if (!listeners) return 0;
  11278. if (listeners.fn) return 1;
  11279. return listeners.length;
  11280. };
  11281. /**
  11282. * Calls each of the listeners registered for a given event.
  11283. *
  11284. * @param {(String|Symbol)} event The event name.
  11285. * @returns {Boolean} `true` if the event had listeners, else `false`.
  11286. * @public
  11287. */
  11288. EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
  11289. var evt = prefix ? prefix + event : event;
  11290. if (!this._events[evt]) return false;
  11291. var listeners = this._events[evt]
  11292. , len = arguments.length
  11293. , args
  11294. , i;
  11295. if (listeners.fn) {
  11296. if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
  11297. switch (len) {
  11298. case 1: return listeners.fn.call(listeners.context), true;
  11299. case 2: return listeners.fn.call(listeners.context, a1), true;
  11300. case 3: return listeners.fn.call(listeners.context, a1, a2), true;
  11301. case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
  11302. case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
  11303. case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
  11304. }
  11305. for (i = 1, args = new Array(len -1); i < len; i++) {
  11306. args[i - 1] = arguments[i];
  11307. }
  11308. listeners.fn.apply(listeners.context, args);
  11309. } else {
  11310. var length = listeners.length
  11311. , j;
  11312. for (i = 0; i < length; i++) {
  11313. if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
  11314. switch (len) {
  11315. case 1: listeners[i].fn.call(listeners[i].context); break;
  11316. case 2: listeners[i].fn.call(listeners[i].context, a1); break;
  11317. case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
  11318. case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
  11319. default:
  11320. if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
  11321. args[j - 1] = arguments[j];
  11322. }
  11323. listeners[i].fn.apply(listeners[i].context, args);
  11324. }
  11325. }
  11326. }
  11327. return true;
  11328. };
  11329. /**
  11330. * Add a listener for a given event.
  11331. *
  11332. * @param {(String|Symbol)} event The event name.
  11333. * @param {Function} fn The listener function.
  11334. * @param {*} [context=this] The context to invoke the listener with.
  11335. * @returns {EventEmitter} `this`.
  11336. * @public
  11337. */
  11338. EventEmitter.prototype.on = function on(event, fn, context) {
  11339. return addListener(this, event, fn, context, false);
  11340. };
  11341. /**
  11342. * Add a one-time listener for a given event.
  11343. *
  11344. * @param {(String|Symbol)} event The event name.
  11345. * @param {Function} fn The listener function.
  11346. * @param {*} [context=this] The context to invoke the listener with.
  11347. * @returns {EventEmitter} `this`.
  11348. * @public
  11349. */
  11350. EventEmitter.prototype.once = function once(event, fn, context) {
  11351. return addListener(this, event, fn, context, true);
  11352. };
  11353. /**
  11354. * Remove the listeners of a given event.
  11355. *
  11356. * @param {(String|Symbol)} event The event name.
  11357. * @param {Function} fn Only remove the listeners that match this function.
  11358. * @param {*} context Only remove the listeners that have this context.
  11359. * @param {Boolean} once Only remove one-time listeners.
  11360. * @returns {EventEmitter} `this`.
  11361. * @public
  11362. */
  11363. EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
  11364. var evt = prefix ? prefix + event : event;
  11365. if (!this._events[evt]) return this;
  11366. if (!fn) {
  11367. clearEvent(this, evt);
  11368. return this;
  11369. }
  11370. var listeners = this._events[evt];
  11371. if (listeners.fn) {
  11372. if (
  11373. listeners.fn === fn &&
  11374. (!once || listeners.once) &&
  11375. (!context || listeners.context === context)
  11376. ) {
  11377. clearEvent(this, evt);
  11378. }
  11379. } else {
  11380. for (var i = 0, events = [], length = listeners.length; i < length; i++) {
  11381. if (
  11382. listeners[i].fn !== fn ||
  11383. (once && !listeners[i].once) ||
  11384. (context && listeners[i].context !== context)
  11385. ) {
  11386. events.push(listeners[i]);
  11387. }
  11388. }
  11389. //
  11390. // Reset the array, or remove it completely if we have no more listeners.
  11391. //
  11392. if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
  11393. else clearEvent(this, evt);
  11394. }
  11395. return this;
  11396. };
  11397. /**
  11398. * Remove all listeners, or those of the specified event.
  11399. *
  11400. * @param {(String|Symbol)} [event] The event name.
  11401. * @returns {EventEmitter} `this`.
  11402. * @public
  11403. */
  11404. EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
  11405. var evt;
  11406. if (event) {
  11407. evt = prefix ? prefix + event : event;
  11408. if (this._events[evt]) clearEvent(this, evt);
  11409. } else {
  11410. this._events = new Events();
  11411. this._eventsCount = 0;
  11412. }
  11413. return this;
  11414. };
  11415. //
  11416. // Alias methods names because people roll like that.
  11417. //
  11418. EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
  11419. EventEmitter.prototype.addListener = EventEmitter.prototype.on;
  11420. //
  11421. // Expose the prefix.
  11422. //
  11423. EventEmitter.prefixed = prefix;
  11424. //
  11425. // Allow `EventEmitter` to be imported as module namespace.
  11426. //
  11427. EventEmitter.EventEmitter = EventEmitter;
  11428. //
  11429. // Expose the module.
  11430. //
  11431. {
  11432. module.exports = EventEmitter;
  11433. }
  11434. });
  11435. /**
  11436. * Helpers.
  11437. */
  11438. var s = 1000;
  11439. var m = s * 60;
  11440. var h = m * 60;
  11441. var d = h * 24;
  11442. var w = d * 7;
  11443. var y = d * 365.25;
  11444. /**
  11445. * Parse or format the given `val`.
  11446. *
  11447. * Options:
  11448. *
  11449. * - `long` verbose formatting [false]
  11450. *
  11451. * @param {String|Number} val
  11452. * @param {Object} [options]
  11453. * @throws {Error} throw an error if val is not a non-empty string or a number
  11454. * @return {String|Number}
  11455. * @api public
  11456. */
  11457. var ms = function(val, options) {
  11458. options = options || {};
  11459. var type = typeof val;
  11460. if (type === 'string' && val.length > 0) {
  11461. return parse(val);
  11462. } else if (type === 'number' && isNaN(val) === false) {
  11463. return options.long ? fmtLong(val) : fmtShort(val);
  11464. }
  11465. throw new Error(
  11466. 'val is not a non-empty string or a valid number. val=' +
  11467. JSON.stringify(val)
  11468. );
  11469. };
  11470. /**
  11471. * Parse the given `str` and return milliseconds.
  11472. *
  11473. * @param {String} str
  11474. * @return {Number}
  11475. * @api private
  11476. */
  11477. function parse(str) {
  11478. str = String(str);
  11479. if (str.length > 100) {
  11480. return;
  11481. }
  11482. var match = /^((?:\d+)?\-?\d?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
  11483. str
  11484. );
  11485. if (!match) {
  11486. return;
  11487. }
  11488. var n = parseFloat(match[1]);
  11489. var type = (match[2] || 'ms').toLowerCase();
  11490. switch (type) {
  11491. case 'years':
  11492. case 'year':
  11493. case 'yrs':
  11494. case 'yr':
  11495. case 'y':
  11496. return n * y;
  11497. case 'weeks':
  11498. case 'week':
  11499. case 'w':
  11500. return n * w;
  11501. case 'days':
  11502. case 'day':
  11503. case 'd':
  11504. return n * d;
  11505. case 'hours':
  11506. case 'hour':
  11507. case 'hrs':
  11508. case 'hr':
  11509. case 'h':
  11510. return n * h;
  11511. case 'minutes':
  11512. case 'minute':
  11513. case 'mins':
  11514. case 'min':
  11515. case 'm':
  11516. return n * m;
  11517. case 'seconds':
  11518. case 'second':
  11519. case 'secs':
  11520. case 'sec':
  11521. case 's':
  11522. return n * s;
  11523. case 'milliseconds':
  11524. case 'millisecond':
  11525. case 'msecs':
  11526. case 'msec':
  11527. case 'ms':
  11528. return n;
  11529. default:
  11530. return undefined;
  11531. }
  11532. }
  11533. /**
  11534. * Short format for `ms`.
  11535. *
  11536. * @param {Number} ms
  11537. * @return {String}
  11538. * @api private
  11539. */
  11540. function fmtShort(ms) {
  11541. var msAbs = Math.abs(ms);
  11542. if (msAbs >= d) {
  11543. return Math.round(ms / d) + 'd';
  11544. }
  11545. if (msAbs >= h) {
  11546. return Math.round(ms / h) + 'h';
  11547. }
  11548. if (msAbs >= m) {
  11549. return Math.round(ms / m) + 'm';
  11550. }
  11551. if (msAbs >= s) {
  11552. return Math.round(ms / s) + 's';
  11553. }
  11554. return ms + 'ms';
  11555. }
  11556. /**
  11557. * Long format for `ms`.
  11558. *
  11559. * @param {Number} ms
  11560. * @return {String}
  11561. * @api private
  11562. */
  11563. function fmtLong(ms) {
  11564. var msAbs = Math.abs(ms);
  11565. if (msAbs >= d) {
  11566. return plural(ms, msAbs, d, 'day');
  11567. }
  11568. if (msAbs >= h) {
  11569. return plural(ms, msAbs, h, 'hour');
  11570. }
  11571. if (msAbs >= m) {
  11572. return plural(ms, msAbs, m, 'minute');
  11573. }
  11574. if (msAbs >= s) {
  11575. return plural(ms, msAbs, s, 'second');
  11576. }
  11577. return ms + ' ms';
  11578. }
  11579. /**
  11580. * Pluralization helper.
  11581. */
  11582. function plural(ms, msAbs, n, name) {
  11583. var isPlural = msAbs >= n * 1.5;
  11584. return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
  11585. }
  11586. /**
  11587. * This is the common logic for both the Node.js and web browser
  11588. * implementations of `debug()`.
  11589. */
  11590. function setup(env) {
  11591. createDebug.debug = createDebug;
  11592. createDebug.default = createDebug;
  11593. createDebug.coerce = coerce;
  11594. createDebug.disable = disable;
  11595. createDebug.enable = enable;
  11596. createDebug.enabled = enabled;
  11597. createDebug.humanize = ms;
  11598. Object.keys(env).forEach(function (key) {
  11599. createDebug[key] = env[key];
  11600. });
  11601. /**
  11602. * Active `debug` instances.
  11603. */
  11604. createDebug.instances = [];
  11605. /**
  11606. * The currently active debug mode names, and names to skip.
  11607. */
  11608. createDebug.names = [];
  11609. createDebug.skips = [];
  11610. /**
  11611. * Map of special "%n" handling functions, for the debug "format" argument.
  11612. *
  11613. * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
  11614. */
  11615. createDebug.formatters = {};
  11616. /**
  11617. * Selects a color for a debug namespace
  11618. * @param {String} namespace The namespace string for the for the debug instance to be colored
  11619. * @return {Number|String} An ANSI color code for the given namespace
  11620. * @api private
  11621. */
  11622. function selectColor(namespace) {
  11623. var hash = 0;
  11624. for (var i = 0; i < namespace.length; i++) {
  11625. hash = (hash << 5) - hash + namespace.charCodeAt(i);
  11626. hash |= 0; // Convert to 32bit integer
  11627. }
  11628. return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
  11629. }
  11630. createDebug.selectColor = selectColor;
  11631. /**
  11632. * Create a debugger with the given `namespace`.
  11633. *
  11634. * @param {String} namespace
  11635. * @return {Function}
  11636. * @api public
  11637. */
  11638. function createDebug(namespace) {
  11639. var prevTime;
  11640. function debug() {
  11641. // Disabled?
  11642. if (!debug.enabled) {
  11643. return;
  11644. }
  11645. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  11646. args[_key] = arguments[_key];
  11647. }
  11648. var self = debug; // Set `diff` timestamp
  11649. var curr = Number(new Date());
  11650. var ms = curr - (prevTime || curr);
  11651. self.diff = ms;
  11652. self.prev = prevTime;
  11653. self.curr = curr;
  11654. prevTime = curr;
  11655. args[0] = createDebug.coerce(args[0]);
  11656. if (typeof args[0] !== 'string') {
  11657. // Anything else let's inspect with %O
  11658. args.unshift('%O');
  11659. } // Apply any `formatters` transformations
  11660. var index = 0;
  11661. args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) {
  11662. // If we encounter an escaped % then don't increase the array index
  11663. if (match === '%%') {
  11664. return match;
  11665. }
  11666. index++;
  11667. var formatter = createDebug.formatters[format];
  11668. if (typeof formatter === 'function') {
  11669. var val = args[index];
  11670. match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format`
  11671. args.splice(index, 1);
  11672. index--;
  11673. }
  11674. return match;
  11675. }); // Apply env-specific formatting (colors, etc.)
  11676. createDebug.formatArgs.call(self, args);
  11677. var logFn = self.log || createDebug.log;
  11678. logFn.apply(self, args);
  11679. }
  11680. debug.namespace = namespace;
  11681. debug.enabled = createDebug.enabled(namespace);
  11682. debug.useColors = createDebug.useColors();
  11683. debug.color = selectColor(namespace);
  11684. debug.destroy = destroy;
  11685. debug.extend = extend; // Debug.formatArgs = formatArgs;
  11686. // debug.rawLog = rawLog;
  11687. // env-specific initialization logic for debug instances
  11688. if (typeof createDebug.init === 'function') {
  11689. createDebug.init(debug);
  11690. }
  11691. createDebug.instances.push(debug);
  11692. return debug;
  11693. }
  11694. function destroy() {
  11695. var index = createDebug.instances.indexOf(this);
  11696. if (index !== -1) {
  11697. createDebug.instances.splice(index, 1);
  11698. return true;
  11699. }
  11700. return false;
  11701. }
  11702. function extend(namespace, delimiter) {
  11703. return createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
  11704. }
  11705. /**
  11706. * Enables a debug mode by namespaces. This can include modes
  11707. * separated by a colon and wildcards.
  11708. *
  11709. * @param {String} namespaces
  11710. * @api public
  11711. */
  11712. function enable(namespaces) {
  11713. createDebug.save(namespaces);
  11714. createDebug.names = [];
  11715. createDebug.skips = [];
  11716. var i;
  11717. var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
  11718. var len = split.length;
  11719. for (i = 0; i < len; i++) {
  11720. if (!split[i]) {
  11721. // ignore empty strings
  11722. continue;
  11723. }
  11724. namespaces = split[i].replace(/\*/g, '.*?');
  11725. if (namespaces[0] === '-') {
  11726. createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
  11727. } else {
  11728. createDebug.names.push(new RegExp('^' + namespaces + '$'));
  11729. }
  11730. }
  11731. for (i = 0; i < createDebug.instances.length; i++) {
  11732. var instance = createDebug.instances[i];
  11733. instance.enabled = createDebug.enabled(instance.namespace);
  11734. }
  11735. }
  11736. /**
  11737. * Disable debug output.
  11738. *
  11739. * @api public
  11740. */
  11741. function disable() {
  11742. createDebug.enable('');
  11743. }
  11744. /**
  11745. * Returns true if the given mode name is enabled, false otherwise.
  11746. *
  11747. * @param {String} name
  11748. * @return {Boolean}
  11749. * @api public
  11750. */
  11751. function enabled(name) {
  11752. if (name[name.length - 1] === '*') {
  11753. return true;
  11754. }
  11755. var i;
  11756. var len;
  11757. for (i = 0, len = createDebug.skips.length; i < len; i++) {
  11758. if (createDebug.skips[i].test(name)) {
  11759. return false;
  11760. }
  11761. }
  11762. for (i = 0, len = createDebug.names.length; i < len; i++) {
  11763. if (createDebug.names[i].test(name)) {
  11764. return true;
  11765. }
  11766. }
  11767. return false;
  11768. }
  11769. /**
  11770. * Coerce `val`.
  11771. *
  11772. * @param {Mixed} val
  11773. * @return {Mixed}
  11774. * @api private
  11775. */
  11776. function coerce(val) {
  11777. if (val instanceof Error) {
  11778. return val.stack || val.message;
  11779. }
  11780. return val;
  11781. }
  11782. createDebug.enable(createDebug.load());
  11783. return createDebug;
  11784. }
  11785. var common = setup;
  11786. var browser = createCommonjsModule(function (module, exports) {
  11787. function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
  11788. /* eslint-env browser */
  11789. /**
  11790. * This is the web browser implementation of `debug()`.
  11791. */
  11792. exports.log = log;
  11793. exports.formatArgs = formatArgs;
  11794. exports.save = save;
  11795. exports.load = load;
  11796. exports.useColors = useColors;
  11797. exports.storage = localstorage();
  11798. /**
  11799. * Colors.
  11800. */
  11801. exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33'];
  11802. /**
  11803. * Currently only WebKit-based Web Inspectors, Firefox >= v31,
  11804. * and the Firebug extension (any Firefox version) are known
  11805. * to support "%c" CSS customizations.
  11806. *
  11807. * TODO: add a `localStorage` variable to explicitly enable/disable colors
  11808. */
  11809. // eslint-disable-next-line complexity
  11810. function useColors() {
  11811. // NB: In an Electron preload script, document will be defined but not fully
  11812. // initialized. Since we know we're in Chrome, we'll just detect this case
  11813. // explicitly
  11814. if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
  11815. return true;
  11816. } // Internet Explorer and Edge do not support colors.
  11817. if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
  11818. return false;
  11819. } // Is webkit? http://stackoverflow.com/a/16459606/376773
  11820. // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
  11821. return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773
  11822. typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?
  11823. // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
  11824. typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker
  11825. typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
  11826. }
  11827. /**
  11828. * Colorize log arguments if enabled.
  11829. *
  11830. * @api public
  11831. */
  11832. function formatArgs(args) {
  11833. args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff);
  11834. if (!this.useColors) {
  11835. return;
  11836. }
  11837. var c = 'color: ' + this.color;
  11838. args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other
  11839. // arguments passed either before or after the %c, so we need to
  11840. // figure out the correct index to insert the CSS into
  11841. var index = 0;
  11842. var lastC = 0;
  11843. args[0].replace(/%[a-zA-Z%]/g, function (match) {
  11844. if (match === '%%') {
  11845. return;
  11846. }
  11847. index++;
  11848. if (match === '%c') {
  11849. // We only are interested in the *last* %c
  11850. // (the user may have provided their own)
  11851. lastC = index;
  11852. }
  11853. });
  11854. args.splice(lastC, 0, c);
  11855. }
  11856. /**
  11857. * Invokes `console.log()` when available.
  11858. * No-op when `console.log` is not a "function".
  11859. *
  11860. * @api public
  11861. */
  11862. function log() {
  11863. var _console;
  11864. // This hackery is required for IE8/9, where
  11865. // the `console.log` function doesn't have 'apply'
  11866. return (typeof console === "undefined" ? "undefined" : _typeof(console)) === 'object' && console.log && (_console = console).log.apply(_console, arguments);
  11867. }
  11868. /**
  11869. * Save `namespaces`.
  11870. *
  11871. * @param {String} namespaces
  11872. * @api private
  11873. */
  11874. function save(namespaces) {
  11875. try {
  11876. if (namespaces) {
  11877. exports.storage.setItem('debug', namespaces);
  11878. } else {
  11879. exports.storage.removeItem('debug');
  11880. }
  11881. } catch (error) {// Swallow
  11882. // XXX (@Qix-) should we be logging these?
  11883. }
  11884. }
  11885. /**
  11886. * Load `namespaces`.
  11887. *
  11888. * @return {String} returns the previously persisted debug modes
  11889. * @api private
  11890. */
  11891. function load() {
  11892. var r;
  11893. try {
  11894. r = exports.storage.getItem('debug');
  11895. } catch (error) {} // Swallow
  11896. // XXX (@Qix-) should we be logging these?
  11897. // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
  11898. if (!r && typeof process !== 'undefined' && 'env' in process) {
  11899. r = process.env.DEBUG;
  11900. }
  11901. return r;
  11902. }
  11903. /**
  11904. * Localstorage attempts to return the localstorage.
  11905. *
  11906. * This is necessary because safari throws
  11907. * when a user disables cookies/localstorage
  11908. * and you attempt to access it.
  11909. *
  11910. * @return {LocalStorage}
  11911. * @api private
  11912. */
  11913. function localstorage() {
  11914. try {
  11915. // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
  11916. // The Browser also has localStorage in the global context.
  11917. return localStorage;
  11918. } catch (error) {// Swallow
  11919. // XXX (@Qix-) should we be logging these?
  11920. }
  11921. }
  11922. module.exports = common(exports);
  11923. var formatters = module.exports.formatters;
  11924. /**
  11925. * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
  11926. */
  11927. formatters.j = function (v) {
  11928. try {
  11929. return JSON.stringify(v);
  11930. } catch (error) {
  11931. return '[UnexpectedJSONParseError]: ' + error.message;
  11932. }
  11933. };
  11934. });
  11935. var browser_1 = browser.log;
  11936. var browser_2 = browser.formatArgs;
  11937. var browser_3 = browser.save;
  11938. var browser_4 = browser.load;
  11939. var browser_5 = browser.useColors;
  11940. var browser_6 = browser.storage;
  11941. var browser_7 = browser.colors;
  11942. /**
  11943. * Copies the values of `source` to `array`.
  11944. *
  11945. * @private
  11946. * @param {Array} source The array to copy values from.
  11947. * @param {Array} [array=[]] The array to copy values to.
  11948. * @returns {Array} Returns `array`.
  11949. */
  11950. function copyArray(source, array) {
  11951. var index = -1,
  11952. length = source.length;
  11953. array || (array = Array(length));
  11954. while (++index < length) {
  11955. array[index] = source[index];
  11956. }
  11957. return array;
  11958. }
  11959. var _copyArray = copyArray;
  11960. /* Built-in method references for those with the same name as other `lodash` methods. */
  11961. var nativeFloor = Math.floor,
  11962. nativeRandom = Math.random;
  11963. /**
  11964. * The base implementation of `_.random` without support for returning
  11965. * floating-point numbers.
  11966. *
  11967. * @private
  11968. * @param {number} lower The lower bound.
  11969. * @param {number} upper The upper bound.
  11970. * @returns {number} Returns the random number.
  11971. */
  11972. function baseRandom(lower, upper) {
  11973. return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
  11974. }
  11975. var _baseRandom = baseRandom;
  11976. /**
  11977. * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
  11978. *
  11979. * @private
  11980. * @param {Array} array The array to shuffle.
  11981. * @param {number} [size=array.length] The size of `array`.
  11982. * @returns {Array} Returns `array`.
  11983. */
  11984. function shuffleSelf(array, size) {
  11985. var index = -1,
  11986. length = array.length,
  11987. lastIndex = length - 1;
  11988. size = size === undefined ? length : size;
  11989. while (++index < size) {
  11990. var rand = _baseRandom(index, lastIndex),
  11991. value = array[rand];
  11992. array[rand] = array[index];
  11993. array[index] = value;
  11994. }
  11995. array.length = size;
  11996. return array;
  11997. }
  11998. var _shuffleSelf = shuffleSelf;
  11999. /**
  12000. * A specialized version of `_.shuffle` for arrays.
  12001. *
  12002. * @private
  12003. * @param {Array} array The array to shuffle.
  12004. * @returns {Array} Returns the new shuffled array.
  12005. */
  12006. function arrayShuffle(array) {
  12007. return _shuffleSelf(_copyArray(array));
  12008. }
  12009. var _arrayShuffle = arrayShuffle;
  12010. /**
  12011. * A specialized version of `_.map` for arrays without support for iteratee
  12012. * shorthands.
  12013. *
  12014. * @private
  12015. * @param {Array} [array] The array to iterate over.
  12016. * @param {Function} iteratee The function invoked per iteration.
  12017. * @returns {Array} Returns the new mapped array.
  12018. */
  12019. function arrayMap(array, iteratee) {
  12020. var index = -1,
  12021. length = array == null ? 0 : array.length,
  12022. result = Array(length);
  12023. while (++index < length) {
  12024. result[index] = iteratee(array[index], index, array);
  12025. }
  12026. return result;
  12027. }
  12028. var _arrayMap = arrayMap;
  12029. /**
  12030. * The base implementation of `_.values` and `_.valuesIn` which creates an
  12031. * array of `object` property values corresponding to the property names
  12032. * of `props`.
  12033. *
  12034. * @private
  12035. * @param {Object} object The object to query.
  12036. * @param {Array} props The property names to get values for.
  12037. * @returns {Object} Returns the array of property values.
  12038. */
  12039. function baseValues(object, props) {
  12040. return _arrayMap(props, function(key) {
  12041. return object[key];
  12042. });
  12043. }
  12044. var _baseValues = baseValues;
  12045. /**
  12046. * The base implementation of `_.times` without support for iteratee shorthands
  12047. * or max array length checks.
  12048. *
  12049. * @private
  12050. * @param {number} n The number of times to invoke `iteratee`.
  12051. * @param {Function} iteratee The function invoked per iteration.
  12052. * @returns {Array} Returns the array of results.
  12053. */
  12054. function baseTimes(n, iteratee) {
  12055. var index = -1,
  12056. result = Array(n);
  12057. while (++index < n) {
  12058. result[index] = iteratee(index);
  12059. }
  12060. return result;
  12061. }
  12062. var _baseTimes = baseTimes;
  12063. /** Detect free variable `global` from Node.js. */
  12064. var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
  12065. var _freeGlobal = freeGlobal;
  12066. /** Detect free variable `self`. */
  12067. var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
  12068. /** Used as a reference to the global object. */
  12069. var root = _freeGlobal || freeSelf || Function('return this')();
  12070. var _root = root;
  12071. /** Built-in value references. */
  12072. var Symbol$1 = _root.Symbol;
  12073. var _Symbol = Symbol$1;
  12074. /** Used for built-in method references. */
  12075. var objectProto = Object.prototype;
  12076. /** Used to check objects for own properties. */
  12077. var hasOwnProperty = objectProto.hasOwnProperty;
  12078. /**
  12079. * Used to resolve the
  12080. * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
  12081. * of values.
  12082. */
  12083. var nativeObjectToString = objectProto.toString;
  12084. /** Built-in value references. */
  12085. var symToStringTag = _Symbol ? _Symbol.toStringTag : undefined;
  12086. /**
  12087. * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
  12088. *
  12089. * @private
  12090. * @param {*} value The value to query.
  12091. * @returns {string} Returns the raw `toStringTag`.
  12092. */
  12093. function getRawTag(value) {
  12094. var isOwn = hasOwnProperty.call(value, symToStringTag),
  12095. tag = value[symToStringTag];
  12096. try {
  12097. value[symToStringTag] = undefined;
  12098. var unmasked = true;
  12099. } catch (e) {}
  12100. var result = nativeObjectToString.call(value);
  12101. if (unmasked) {
  12102. if (isOwn) {
  12103. value[symToStringTag] = tag;
  12104. } else {
  12105. delete value[symToStringTag];
  12106. }
  12107. }
  12108. return result;
  12109. }
  12110. var _getRawTag = getRawTag;
  12111. /** Used for built-in method references. */
  12112. var objectProto$1 = Object.prototype;
  12113. /**
  12114. * Used to resolve the
  12115. * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
  12116. * of values.
  12117. */
  12118. var nativeObjectToString$1 = objectProto$1.toString;
  12119. /**
  12120. * Converts `value` to a string using `Object.prototype.toString`.
  12121. *
  12122. * @private
  12123. * @param {*} value The value to convert.
  12124. * @returns {string} Returns the converted string.
  12125. */
  12126. function objectToString(value) {
  12127. return nativeObjectToString$1.call(value);
  12128. }
  12129. var _objectToString = objectToString;
  12130. /** `Object#toString` result references. */
  12131. var nullTag = '[object Null]',
  12132. undefinedTag = '[object Undefined]';
  12133. /** Built-in value references. */
  12134. var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined;
  12135. /**
  12136. * The base implementation of `getTag` without fallbacks for buggy environments.
  12137. *
  12138. * @private
  12139. * @param {*} value The value to query.
  12140. * @returns {string} Returns the `toStringTag`.
  12141. */
  12142. function baseGetTag(value) {
  12143. if (value == null) {
  12144. return value === undefined ? undefinedTag : nullTag;
  12145. }
  12146. return (symToStringTag$1 && symToStringTag$1 in Object(value))
  12147. ? _getRawTag(value)
  12148. : _objectToString(value);
  12149. }
  12150. var _baseGetTag = baseGetTag;
  12151. /**
  12152. * Checks if `value` is object-like. A value is object-like if it's not `null`
  12153. * and has a `typeof` result of "object".
  12154. *
  12155. * @static
  12156. * @memberOf _
  12157. * @since 4.0.0
  12158. * @category Lang
  12159. * @param {*} value The value to check.
  12160. * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
  12161. * @example
  12162. *
  12163. * _.isObjectLike({});
  12164. * // => true
  12165. *
  12166. * _.isObjectLike([1, 2, 3]);
  12167. * // => true
  12168. *
  12169. * _.isObjectLike(_.noop);
  12170. * // => false
  12171. *
  12172. * _.isObjectLike(null);
  12173. * // => false
  12174. */
  12175. function isObjectLike(value) {
  12176. return value != null && typeof value == 'object';
  12177. }
  12178. var isObjectLike_1 = isObjectLike;
  12179. /** `Object#toString` result references. */
  12180. var argsTag = '[object Arguments]';
  12181. /**
  12182. * The base implementation of `_.isArguments`.
  12183. *
  12184. * @private
  12185. * @param {*} value The value to check.
  12186. * @returns {boolean} Returns `true` if `value` is an `arguments` object,
  12187. */
  12188. function baseIsArguments(value) {
  12189. return isObjectLike_1(value) && _baseGetTag(value) == argsTag;
  12190. }
  12191. var _baseIsArguments = baseIsArguments;
  12192. /** Used for built-in method references. */
  12193. var objectProto$2 = Object.prototype;
  12194. /** Used to check objects for own properties. */
  12195. var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
  12196. /** Built-in value references. */
  12197. var propertyIsEnumerable = objectProto$2.propertyIsEnumerable;
  12198. /**
  12199. * Checks if `value` is likely an `arguments` object.
  12200. *
  12201. * @static
  12202. * @memberOf _
  12203. * @since 0.1.0
  12204. * @category Lang
  12205. * @param {*} value The value to check.
  12206. * @returns {boolean} Returns `true` if `value` is an `arguments` object,
  12207. * else `false`.
  12208. * @example
  12209. *
  12210. * _.isArguments(function() { return arguments; }());
  12211. * // => true
  12212. *
  12213. * _.isArguments([1, 2, 3]);
  12214. * // => false
  12215. */
  12216. var isArguments = _baseIsArguments(function() { return arguments; }()) ? _baseIsArguments : function(value) {
  12217. return isObjectLike_1(value) && hasOwnProperty$1.call(value, 'callee') &&
  12218. !propertyIsEnumerable.call(value, 'callee');
  12219. };
  12220. var isArguments_1 = isArguments;
  12221. /**
  12222. * Checks if `value` is classified as an `Array` object.
  12223. *
  12224. * @static
  12225. * @memberOf _
  12226. * @since 0.1.0
  12227. * @category Lang
  12228. * @param {*} value The value to check.
  12229. * @returns {boolean} Returns `true` if `value` is an array, else `false`.
  12230. * @example
  12231. *
  12232. * _.isArray([1, 2, 3]);
  12233. * // => true
  12234. *
  12235. * _.isArray(document.body.children);
  12236. * // => false
  12237. *
  12238. * _.isArray('abc');
  12239. * // => false
  12240. *
  12241. * _.isArray(_.noop);
  12242. * // => false
  12243. */
  12244. var isArray = Array.isArray;
  12245. var isArray_1 = isArray;
  12246. /**
  12247. * This method returns `false`.
  12248. *
  12249. * @static
  12250. * @memberOf _
  12251. * @since 4.13.0
  12252. * @category Util
  12253. * @returns {boolean} Returns `false`.
  12254. * @example
  12255. *
  12256. * _.times(2, _.stubFalse);
  12257. * // => [false, false]
  12258. */
  12259. function stubFalse() {
  12260. return false;
  12261. }
  12262. var stubFalse_1 = stubFalse;
  12263. var isBuffer_1 = createCommonjsModule(function (module, exports) {
  12264. /** Detect free variable `exports`. */
  12265. var freeExports = exports && !exports.nodeType && exports;
  12266. /** Detect free variable `module`. */
  12267. var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
  12268. /** Detect the popular CommonJS extension `module.exports`. */
  12269. var moduleExports = freeModule && freeModule.exports === freeExports;
  12270. /** Built-in value references. */
  12271. var Buffer = moduleExports ? _root.Buffer : undefined;
  12272. /* Built-in method references for those with the same name as other `lodash` methods. */
  12273. var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
  12274. /**
  12275. * Checks if `value` is a buffer.
  12276. *
  12277. * @static
  12278. * @memberOf _
  12279. * @since 4.3.0
  12280. * @category Lang
  12281. * @param {*} value The value to check.
  12282. * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
  12283. * @example
  12284. *
  12285. * _.isBuffer(new Buffer(2));
  12286. * // => true
  12287. *
  12288. * _.isBuffer(new Uint8Array(2));
  12289. * // => false
  12290. */
  12291. var isBuffer = nativeIsBuffer || stubFalse_1;
  12292. module.exports = isBuffer;
  12293. });
  12294. /** Used as references for various `Number` constants. */
  12295. var MAX_SAFE_INTEGER = 9007199254740991;
  12296. /** Used to detect unsigned integer values. */
  12297. var reIsUint = /^(?:0|[1-9]\d*)$/;
  12298. /**
  12299. * Checks if `value` is a valid array-like index.
  12300. *
  12301. * @private
  12302. * @param {*} value The value to check.
  12303. * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
  12304. * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
  12305. */
  12306. function isIndex(value, length) {
  12307. var type = typeof value;
  12308. length = length == null ? MAX_SAFE_INTEGER : length;
  12309. return !!length &&
  12310. (type == 'number' ||
  12311. (type != 'symbol' && reIsUint.test(value))) &&
  12312. (value > -1 && value % 1 == 0 && value < length);
  12313. }
  12314. var _isIndex = isIndex;
  12315. /** Used as references for various `Number` constants. */
  12316. var MAX_SAFE_INTEGER$1 = 9007199254740991;
  12317. /**
  12318. * Checks if `value` is a valid array-like length.
  12319. *
  12320. * **Note:** This method is loosely based on
  12321. * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
  12322. *
  12323. * @static
  12324. * @memberOf _
  12325. * @since 4.0.0
  12326. * @category Lang
  12327. * @param {*} value The value to check.
  12328. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
  12329. * @example
  12330. *
  12331. * _.isLength(3);
  12332. * // => true
  12333. *
  12334. * _.isLength(Number.MIN_VALUE);
  12335. * // => false
  12336. *
  12337. * _.isLength(Infinity);
  12338. * // => false
  12339. *
  12340. * _.isLength('3');
  12341. * // => false
  12342. */
  12343. function isLength(value) {
  12344. return typeof value == 'number' &&
  12345. value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1;
  12346. }
  12347. var isLength_1 = isLength;
  12348. /** `Object#toString` result references. */
  12349. var argsTag$1 = '[object Arguments]',
  12350. arrayTag = '[object Array]',
  12351. boolTag = '[object Boolean]',
  12352. dateTag = '[object Date]',
  12353. errorTag = '[object Error]',
  12354. funcTag = '[object Function]',
  12355. mapTag = '[object Map]',
  12356. numberTag = '[object Number]',
  12357. objectTag = '[object Object]',
  12358. regexpTag = '[object RegExp]',
  12359. setTag = '[object Set]',
  12360. stringTag = '[object String]',
  12361. weakMapTag = '[object WeakMap]';
  12362. var arrayBufferTag = '[object ArrayBuffer]',
  12363. dataViewTag = '[object DataView]',
  12364. float32Tag = '[object Float32Array]',
  12365. float64Tag = '[object Float64Array]',
  12366. int8Tag = '[object Int8Array]',
  12367. int16Tag = '[object Int16Array]',
  12368. int32Tag = '[object Int32Array]',
  12369. uint8Tag = '[object Uint8Array]',
  12370. uint8ClampedTag = '[object Uint8ClampedArray]',
  12371. uint16Tag = '[object Uint16Array]',
  12372. uint32Tag = '[object Uint32Array]';
  12373. /** Used to identify `toStringTag` values of typed arrays. */
  12374. var typedArrayTags = {};
  12375. typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
  12376. typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
  12377. typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
  12378. typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
  12379. typedArrayTags[uint32Tag] = true;
  12380. typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] =
  12381. typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
  12382. typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
  12383. typedArrayTags[errorTag] = typedArrayTags[funcTag] =
  12384. typedArrayTags[mapTag] = typedArrayTags[numberTag] =
  12385. typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
  12386. typedArrayTags[setTag] = typedArrayTags[stringTag] =
  12387. typedArrayTags[weakMapTag] = false;
  12388. /**
  12389. * The base implementation of `_.isTypedArray` without Node.js optimizations.
  12390. *
  12391. * @private
  12392. * @param {*} value The value to check.
  12393. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
  12394. */
  12395. function baseIsTypedArray(value) {
  12396. return isObjectLike_1(value) &&
  12397. isLength_1(value.length) && !!typedArrayTags[_baseGetTag(value)];
  12398. }
  12399. var _baseIsTypedArray = baseIsTypedArray;
  12400. /**
  12401. * The base implementation of `_.unary` without support for storing metadata.
  12402. *
  12403. * @private
  12404. * @param {Function} func The function to cap arguments for.
  12405. * @returns {Function} Returns the new capped function.
  12406. */
  12407. function baseUnary(func) {
  12408. return function(value) {
  12409. return func(value);
  12410. };
  12411. }
  12412. var _baseUnary = baseUnary;
  12413. var _nodeUtil = createCommonjsModule(function (module, exports) {
  12414. /** Detect free variable `exports`. */
  12415. var freeExports = exports && !exports.nodeType && exports;
  12416. /** Detect free variable `module`. */
  12417. var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
  12418. /** Detect the popular CommonJS extension `module.exports`. */
  12419. var moduleExports = freeModule && freeModule.exports === freeExports;
  12420. /** Detect free variable `process` from Node.js. */
  12421. var freeProcess = moduleExports && _freeGlobal.process;
  12422. /** Used to access faster Node.js helpers. */
  12423. var nodeUtil = (function() {
  12424. try {
  12425. // Use `util.types` for Node.js 10+.
  12426. var types = freeModule && freeModule.require && freeModule.require('util').types;
  12427. if (types) {
  12428. return types;
  12429. }
  12430. // Legacy `process.binding('util')` for Node.js < 10.
  12431. return freeProcess && freeProcess.binding && freeProcess.binding('util');
  12432. } catch (e) {}
  12433. }());
  12434. module.exports = nodeUtil;
  12435. });
  12436. /* Node.js helper references. */
  12437. var nodeIsTypedArray = _nodeUtil && _nodeUtil.isTypedArray;
  12438. /**
  12439. * Checks if `value` is classified as a typed array.
  12440. *
  12441. * @static
  12442. * @memberOf _
  12443. * @since 3.0.0
  12444. * @category Lang
  12445. * @param {*} value The value to check.
  12446. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
  12447. * @example
  12448. *
  12449. * _.isTypedArray(new Uint8Array);
  12450. * // => true
  12451. *
  12452. * _.isTypedArray([]);
  12453. * // => false
  12454. */
  12455. var isTypedArray = nodeIsTypedArray ? _baseUnary(nodeIsTypedArray) : _baseIsTypedArray;
  12456. var isTypedArray_1 = isTypedArray;
  12457. /** Used for built-in method references. */
  12458. var objectProto$3 = Object.prototype;
  12459. /** Used to check objects for own properties. */
  12460. var hasOwnProperty$2 = objectProto$3.hasOwnProperty;
  12461. /**
  12462. * Creates an array of the enumerable property names of the array-like `value`.
  12463. *
  12464. * @private
  12465. * @param {*} value The value to query.
  12466. * @param {boolean} inherited Specify returning inherited property names.
  12467. * @returns {Array} Returns the array of property names.
  12468. */
  12469. function arrayLikeKeys(value, inherited) {
  12470. var isArr = isArray_1(value),
  12471. isArg = !isArr && isArguments_1(value),
  12472. isBuff = !isArr && !isArg && isBuffer_1(value),
  12473. isType = !isArr && !isArg && !isBuff && isTypedArray_1(value),
  12474. skipIndexes = isArr || isArg || isBuff || isType,
  12475. result = skipIndexes ? _baseTimes(value.length, String) : [],
  12476. length = result.length;
  12477. for (var key in value) {
  12478. if ((inherited || hasOwnProperty$2.call(value, key)) &&
  12479. !(skipIndexes && (
  12480. // Safari 9 has enumerable `arguments.length` in strict mode.
  12481. key == 'length' ||
  12482. // Node.js 0.10 has enumerable non-index properties on buffers.
  12483. (isBuff && (key == 'offset' || key == 'parent')) ||
  12484. // PhantomJS 2 has enumerable non-index properties on typed arrays.
  12485. (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
  12486. // Skip index properties.
  12487. _isIndex(key, length)
  12488. ))) {
  12489. result.push(key);
  12490. }
  12491. }
  12492. return result;
  12493. }
  12494. var _arrayLikeKeys = arrayLikeKeys;
  12495. /** Used for built-in method references. */
  12496. var objectProto$4 = Object.prototype;
  12497. /**
  12498. * Checks if `value` is likely a prototype object.
  12499. *
  12500. * @private
  12501. * @param {*} value The value to check.
  12502. * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
  12503. */
  12504. function isPrototype(value) {
  12505. var Ctor = value && value.constructor,
  12506. proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$4;
  12507. return value === proto;
  12508. }
  12509. var _isPrototype = isPrototype;
  12510. /**
  12511. * Creates a unary function that invokes `func` with its argument transformed.
  12512. *
  12513. * @private
  12514. * @param {Function} func The function to wrap.
  12515. * @param {Function} transform The argument transform.
  12516. * @returns {Function} Returns the new function.
  12517. */
  12518. function overArg(func, transform) {
  12519. return function(arg) {
  12520. return func(transform(arg));
  12521. };
  12522. }
  12523. var _overArg = overArg;
  12524. /* Built-in method references for those with the same name as other `lodash` methods. */
  12525. var nativeKeys = _overArg(Object.keys, Object);
  12526. var _nativeKeys = nativeKeys;
  12527. /** Used for built-in method references. */
  12528. var objectProto$5 = Object.prototype;
  12529. /** Used to check objects for own properties. */
  12530. var hasOwnProperty$3 = objectProto$5.hasOwnProperty;
  12531. /**
  12532. * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
  12533. *
  12534. * @private
  12535. * @param {Object} object The object to query.
  12536. * @returns {Array} Returns the array of property names.
  12537. */
  12538. function baseKeys(object) {
  12539. if (!_isPrototype(object)) {
  12540. return _nativeKeys(object);
  12541. }
  12542. var result = [];
  12543. for (var key in Object(object)) {
  12544. if (hasOwnProperty$3.call(object, key) && key != 'constructor') {
  12545. result.push(key);
  12546. }
  12547. }
  12548. return result;
  12549. }
  12550. var _baseKeys = baseKeys;
  12551. /**
  12552. * Checks if `value` is the
  12553. * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
  12554. * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  12555. *
  12556. * @static
  12557. * @memberOf _
  12558. * @since 0.1.0
  12559. * @category Lang
  12560. * @param {*} value The value to check.
  12561. * @returns {boolean} Returns `true` if `value` is an object, else `false`.
  12562. * @example
  12563. *
  12564. * _.isObject({});
  12565. * // => true
  12566. *
  12567. * _.isObject([1, 2, 3]);
  12568. * // => true
  12569. *
  12570. * _.isObject(_.noop);
  12571. * // => true
  12572. *
  12573. * _.isObject(null);
  12574. * // => false
  12575. */
  12576. function isObject(value) {
  12577. var type = typeof value;
  12578. return value != null && (type == 'object' || type == 'function');
  12579. }
  12580. var isObject_1 = isObject;
  12581. /** `Object#toString` result references. */
  12582. var asyncTag = '[object AsyncFunction]',
  12583. funcTag$1 = '[object Function]',
  12584. genTag = '[object GeneratorFunction]',
  12585. proxyTag = '[object Proxy]';
  12586. /**
  12587. * Checks if `value` is classified as a `Function` object.
  12588. *
  12589. * @static
  12590. * @memberOf _
  12591. * @since 0.1.0
  12592. * @category Lang
  12593. * @param {*} value The value to check.
  12594. * @returns {boolean} Returns `true` if `value` is a function, else `false`.
  12595. * @example
  12596. *
  12597. * _.isFunction(_);
  12598. * // => true
  12599. *
  12600. * _.isFunction(/abc/);
  12601. * // => false
  12602. */
  12603. function isFunction(value) {
  12604. if (!isObject_1(value)) {
  12605. return false;
  12606. }
  12607. // The use of `Object#toString` avoids issues with the `typeof` operator
  12608. // in Safari 9 which returns 'object' for typed arrays and other constructors.
  12609. var tag = _baseGetTag(value);
  12610. return tag == funcTag$1 || tag == genTag || tag == asyncTag || tag == proxyTag;
  12611. }
  12612. var isFunction_1 = isFunction;
  12613. /**
  12614. * Checks if `value` is array-like. A value is considered array-like if it's
  12615. * not a function and has a `value.length` that's an integer greater than or
  12616. * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
  12617. *
  12618. * @static
  12619. * @memberOf _
  12620. * @since 4.0.0
  12621. * @category Lang
  12622. * @param {*} value The value to check.
  12623. * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
  12624. * @example
  12625. *
  12626. * _.isArrayLike([1, 2, 3]);
  12627. * // => true
  12628. *
  12629. * _.isArrayLike(document.body.children);
  12630. * // => true
  12631. *
  12632. * _.isArrayLike('abc');
  12633. * // => true
  12634. *
  12635. * _.isArrayLike(_.noop);
  12636. * // => false
  12637. */
  12638. function isArrayLike(value) {
  12639. return value != null && isLength_1(value.length) && !isFunction_1(value);
  12640. }
  12641. var isArrayLike_1 = isArrayLike;
  12642. /**
  12643. * Creates an array of the own enumerable property names of `object`.
  12644. *
  12645. * **Note:** Non-object values are coerced to objects. See the
  12646. * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
  12647. * for more details.
  12648. *
  12649. * @static
  12650. * @since 0.1.0
  12651. * @memberOf _
  12652. * @category Object
  12653. * @param {Object} object The object to query.
  12654. * @returns {Array} Returns the array of property names.
  12655. * @example
  12656. *
  12657. * function Foo() {
  12658. * this.a = 1;
  12659. * this.b = 2;
  12660. * }
  12661. *
  12662. * Foo.prototype.c = 3;
  12663. *
  12664. * _.keys(new Foo);
  12665. * // => ['a', 'b'] (iteration order is not guaranteed)
  12666. *
  12667. * _.keys('hi');
  12668. * // => ['0', '1']
  12669. */
  12670. function keys(object) {
  12671. return isArrayLike_1(object) ? _arrayLikeKeys(object) : _baseKeys(object);
  12672. }
  12673. var keys_1 = keys;
  12674. /**
  12675. * Creates an array of the own enumerable string keyed property values of `object`.
  12676. *
  12677. * **Note:** Non-object values are coerced to objects.
  12678. *
  12679. * @static
  12680. * @since 0.1.0
  12681. * @memberOf _
  12682. * @category Object
  12683. * @param {Object} object The object to query.
  12684. * @returns {Array} Returns the array of property values.
  12685. * @example
  12686. *
  12687. * function Foo() {
  12688. * this.a = 1;
  12689. * this.b = 2;
  12690. * }
  12691. *
  12692. * Foo.prototype.c = 3;
  12693. *
  12694. * _.values(new Foo);
  12695. * // => [1, 2] (iteration order is not guaranteed)
  12696. *
  12697. * _.values('hi');
  12698. * // => ['h', 'i']
  12699. */
  12700. function values(object) {
  12701. return object == null ? [] : _baseValues(object, keys_1(object));
  12702. }
  12703. var values_1 = values;
  12704. /**
  12705. * The base implementation of `_.shuffle`.
  12706. *
  12707. * @private
  12708. * @param {Array|Object} collection The collection to shuffle.
  12709. * @returns {Array} Returns the new shuffled array.
  12710. */
  12711. function baseShuffle(collection) {
  12712. return _shuffleSelf(values_1(collection));
  12713. }
  12714. var _baseShuffle = baseShuffle;
  12715. /**
  12716. * Creates an array of shuffled values, using a version of the
  12717. * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
  12718. *
  12719. * @static
  12720. * @memberOf _
  12721. * @since 0.1.0
  12722. * @category Collection
  12723. * @param {Array|Object} collection The collection to shuffle.
  12724. * @returns {Array} Returns the new shuffled array.
  12725. * @example
  12726. *
  12727. * _.shuffle([1, 2, 3, 4]);
  12728. * // => [4, 1, 3, 2]
  12729. */
  12730. function shuffle(collection) {
  12731. var func = isArray_1(collection) ? _arrayShuffle : _baseShuffle;
  12732. return func(collection);
  12733. }
  12734. var shuffle_1 = shuffle;
  12735. function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
  12736. var desc = {};
  12737. Object.keys(descriptor).forEach(function (key) {
  12738. desc[key] = descriptor[key];
  12739. });
  12740. desc.enumerable = !!desc.enumerable;
  12741. desc.configurable = !!desc.configurable;
  12742. if ('value' in desc || desc.initializer) {
  12743. desc.writable = true;
  12744. }
  12745. desc = decorators.slice().reverse().reduce(function (desc, decorator) {
  12746. return decorator(target, property, desc) || desc;
  12747. }, desc);
  12748. if (context && desc.initializer !== void 0) {
  12749. desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
  12750. desc.initializer = undefined;
  12751. }
  12752. if (desc.initializer === void 0) {
  12753. Object.defineProperty(target, property, desc);
  12754. desc = null;
  12755. }
  12756. return desc;
  12757. }
  12758. var stateMachine = createCommonjsModule(function (module, exports) {
  12759. /*
  12760. Javascript State Machine Library - https://github.com/jakesgordon/javascript-state-machine
  12761. Copyright (c) 2012, 2013, 2014, 2015, Jake Gordon and contributors
  12762. Released under the MIT license - https://github.com/jakesgordon/javascript-state-machine/blob/master/LICENSE
  12763. */
  12764. (function () {
  12765. var StateMachine = {
  12766. //---------------------------------------------------------------------------
  12767. VERSION: "2.4.0",
  12768. //---------------------------------------------------------------------------
  12769. Result: {
  12770. SUCCEEDED: 1, // the event transitioned successfully from one state to another
  12771. NOTRANSITION: 2, // the event was successfull but no state transition was necessary
  12772. CANCELLED: 3, // the event was cancelled by the caller in a beforeEvent callback
  12773. PENDING: 4 // the event is asynchronous and the caller is in control of when the transition occurs
  12774. },
  12775. Error: {
  12776. INVALID_TRANSITION: 100, // caller tried to fire an event that was innapropriate in the current state
  12777. PENDING_TRANSITION: 200, // caller tried to fire an event while an async transition was still pending
  12778. INVALID_CALLBACK: 300 // caller provided callback function threw an exception
  12779. },
  12780. WILDCARD: '*',
  12781. ASYNC: 'async',
  12782. //---------------------------------------------------------------------------
  12783. create: function(cfg, target) {
  12784. var initial = (typeof cfg.initial == 'string') ? { state: cfg.initial } : cfg.initial; // allow for a simple string, or an object with { state: 'foo', event: 'setup', defer: true|false }
  12785. var terminal = cfg.terminal || cfg['final'];
  12786. var fsm = target || cfg.target || {};
  12787. var events = cfg.events || [];
  12788. var callbacks = cfg.callbacks || {};
  12789. var map = {}; // track state transitions allowed for an event { event: { from: [ to ] } }
  12790. var transitions = {}; // track events allowed from a state { state: [ event ] }
  12791. var add = function(e) {
  12792. var from = Array.isArray(e.from) ? e.from : (e.from ? [e.from] : [StateMachine.WILDCARD]); // allow 'wildcard' transition if 'from' is not specified
  12793. map[e.name] = map[e.name] || {};
  12794. for (var n = 0 ; n < from.length ; n++) {
  12795. transitions[from[n]] = transitions[from[n]] || [];
  12796. transitions[from[n]].push(e.name);
  12797. map[e.name][from[n]] = e.to || from[n]; // allow no-op transition if 'to' is not specified
  12798. }
  12799. if (e.to)
  12800. transitions[e.to] = transitions[e.to] || [];
  12801. };
  12802. if (initial) {
  12803. initial.event = initial.event || 'startup';
  12804. add({ name: initial.event, from: 'none', to: initial.state });
  12805. }
  12806. for(var n = 0 ; n < events.length ; n++)
  12807. add(events[n]);
  12808. for(var name in map) {
  12809. if (map.hasOwnProperty(name))
  12810. fsm[name] = StateMachine.buildEvent(name, map[name]);
  12811. }
  12812. for(var name in callbacks) {
  12813. if (callbacks.hasOwnProperty(name))
  12814. fsm[name] = callbacks[name];
  12815. }
  12816. fsm.current = 'none';
  12817. fsm.is = function(state) { return Array.isArray(state) ? (state.indexOf(this.current) >= 0) : (this.current === state); };
  12818. fsm.can = function(event) { return !this.transition && (map[event] !== undefined) && (map[event].hasOwnProperty(this.current) || map[event].hasOwnProperty(StateMachine.WILDCARD)); };
  12819. fsm.cannot = function(event) { return !this.can(event); };
  12820. fsm.transitions = function() { return (transitions[this.current] || []).concat(transitions[StateMachine.WILDCARD] || []); };
  12821. fsm.isFinished = function() { return this.is(terminal); };
  12822. fsm.error = cfg.error || function(name, from, to, args, error, msg, e) { throw e || msg; }; // default behavior when something unexpected happens is to throw an exception, but caller can override this behavior if desired (see github issue #3 and #17)
  12823. fsm.states = function() { return Object.keys(transitions).sort() };
  12824. if (initial && !initial.defer)
  12825. fsm[initial.event]();
  12826. return fsm;
  12827. },
  12828. //===========================================================================
  12829. doCallback: function(fsm, func, name, from, to, args) {
  12830. if (func) {
  12831. try {
  12832. return func.apply(fsm, [name, from, to].concat(args));
  12833. }
  12834. catch(e) {
  12835. return fsm.error(name, from, to, args, StateMachine.Error.INVALID_CALLBACK, "an exception occurred in a caller-provided callback function", e);
  12836. }
  12837. }
  12838. },
  12839. beforeAnyEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbeforeevent'], name, from, to, args); },
  12840. afterAnyEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafterevent'] || fsm['onevent'], name, from, to, args); },
  12841. leaveAnyState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleavestate'], name, from, to, args); },
  12842. enterAnyState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenterstate'] || fsm['onstate'], name, from, to, args); },
  12843. changeState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onchangestate'], name, from, to, args); },
  12844. beforeThisEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbefore' + name], name, from, to, args); },
  12845. afterThisEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafter' + name] || fsm['on' + name], name, from, to, args); },
  12846. leaveThisState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleave' + from], name, from, to, args); },
  12847. enterThisState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenter' + to] || fsm['on' + to], name, from, to, args); },
  12848. beforeEvent: function(fsm, name, from, to, args) {
  12849. if ((false === StateMachine.beforeThisEvent(fsm, name, from, to, args)) ||
  12850. (false === StateMachine.beforeAnyEvent( fsm, name, from, to, args)))
  12851. return false;
  12852. },
  12853. afterEvent: function(fsm, name, from, to, args) {
  12854. StateMachine.afterThisEvent(fsm, name, from, to, args);
  12855. StateMachine.afterAnyEvent( fsm, name, from, to, args);
  12856. },
  12857. leaveState: function(fsm, name, from, to, args) {
  12858. var specific = StateMachine.leaveThisState(fsm, name, from, to, args),
  12859. general = StateMachine.leaveAnyState( fsm, name, from, to, args);
  12860. if ((false === specific) || (false === general))
  12861. return false;
  12862. else if ((StateMachine.ASYNC === specific) || (StateMachine.ASYNC === general))
  12863. return StateMachine.ASYNC;
  12864. },
  12865. enterState: function(fsm, name, from, to, args) {
  12866. StateMachine.enterThisState(fsm, name, from, to, args);
  12867. StateMachine.enterAnyState( fsm, name, from, to, args);
  12868. },
  12869. //===========================================================================
  12870. buildEvent: function(name, map) {
  12871. return function() {
  12872. var from = this.current;
  12873. var to = map[from] || (map[StateMachine.WILDCARD] != StateMachine.WILDCARD ? map[StateMachine.WILDCARD] : from) || from;
  12874. var args = Array.prototype.slice.call(arguments); // turn arguments into pure array
  12875. if (this.transition)
  12876. return this.error(name, from, to, args, StateMachine.Error.PENDING_TRANSITION, "event " + name + " inappropriate because previous transition did not complete");
  12877. if (this.cannot(name))
  12878. return this.error(name, from, to, args, StateMachine.Error.INVALID_TRANSITION, "event " + name + " inappropriate in current state " + this.current);
  12879. if (false === StateMachine.beforeEvent(this, name, from, to, args))
  12880. return StateMachine.Result.CANCELLED;
  12881. if (from === to) {
  12882. StateMachine.afterEvent(this, name, from, to, args);
  12883. return StateMachine.Result.NOTRANSITION;
  12884. }
  12885. // prepare a transition method for use EITHER lower down, or by caller if they want an async transition (indicated by an ASYNC return value from leaveState)
  12886. var fsm = this;
  12887. this.transition = function() {
  12888. fsm.transition = null; // this method should only ever be called once
  12889. fsm.current = to;
  12890. StateMachine.enterState( fsm, name, from, to, args);
  12891. StateMachine.changeState(fsm, name, from, to, args);
  12892. StateMachine.afterEvent( fsm, name, from, to, args);
  12893. return StateMachine.Result.SUCCEEDED;
  12894. };
  12895. this.transition.cancel = function() { // provide a way for caller to cancel async transition if desired (issue #22)
  12896. fsm.transition = null;
  12897. StateMachine.afterEvent(fsm, name, from, to, args);
  12898. };
  12899. var leave = StateMachine.leaveState(this, name, from, to, args);
  12900. if (false === leave) {
  12901. this.transition = null;
  12902. return StateMachine.Result.CANCELLED;
  12903. }
  12904. else if (StateMachine.ASYNC === leave) {
  12905. return StateMachine.Result.PENDING;
  12906. }
  12907. else {
  12908. if (this.transition) // need to check in case user manually called transition() but forgot to return StateMachine.ASYNC
  12909. return this.transition();
  12910. }
  12911. };
  12912. }
  12913. }; // StateMachine
  12914. //===========================================================================
  12915. //======
  12916. // NODE
  12917. //======
  12918. {
  12919. if ( module.exports) {
  12920. exports = module.exports = StateMachine;
  12921. }
  12922. exports.StateMachine = StateMachine;
  12923. }
  12924. }());
  12925. });
  12926. var stateMachine_1 = stateMachine.StateMachine;
  12927. const adapters = {};
  12928. const getAdapter = name => {
  12929. const adapter = adapters[name];
  12930. if (adapter === undefined) {
  12931. throw new Error(`${name} adapter is not configured`);
  12932. }
  12933. return adapter;
  12934. };
  12935. /**
  12936. * 指定 Adapters
  12937. * @function
  12938. * @memberof module:leancloud-realtime
  12939. * @param {Adapters} newAdapters Adapters 的类型请参考 {@link https://url.leanapp.cn/adapter-type-definitions @leancloud/adapter-types} 中的定义
  12940. */
  12941. const setAdapters = newAdapters => {
  12942. Object.assign(adapters, newAdapters);
  12943. };
  12944. /** Built-in value references. */
  12945. var getPrototype = _overArg(Object.getPrototypeOf, Object);
  12946. var _getPrototype = getPrototype;
  12947. /** `Object#toString` result references. */
  12948. var objectTag$1 = '[object Object]';
  12949. /** Used for built-in method references. */
  12950. var funcProto = Function.prototype,
  12951. objectProto$6 = Object.prototype;
  12952. /** Used to resolve the decompiled source of functions. */
  12953. var funcToString = funcProto.toString;
  12954. /** Used to check objects for own properties. */
  12955. var hasOwnProperty$4 = objectProto$6.hasOwnProperty;
  12956. /** Used to infer the `Object` constructor. */
  12957. var objectCtorString = funcToString.call(Object);
  12958. /**
  12959. * Checks if `value` is a plain object, that is, an object created by the
  12960. * `Object` constructor or one with a `[[Prototype]]` of `null`.
  12961. *
  12962. * @static
  12963. * @memberOf _
  12964. * @since 0.8.0
  12965. * @category Lang
  12966. * @param {*} value The value to check.
  12967. * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
  12968. * @example
  12969. *
  12970. * function Foo() {
  12971. * this.a = 1;
  12972. * }
  12973. *
  12974. * _.isPlainObject(new Foo);
  12975. * // => false
  12976. *
  12977. * _.isPlainObject([1, 2, 3]);
  12978. * // => false
  12979. *
  12980. * _.isPlainObject({ 'x': 0, 'y': 0 });
  12981. * // => true
  12982. *
  12983. * _.isPlainObject(Object.create(null));
  12984. * // => true
  12985. */
  12986. function isPlainObject(value) {
  12987. if (!isObjectLike_1(value) || _baseGetTag(value) != objectTag$1) {
  12988. return false;
  12989. }
  12990. var proto = _getPrototype(value);
  12991. if (proto === null) {
  12992. return true;
  12993. }
  12994. var Ctor = hasOwnProperty$4.call(proto, 'constructor') && proto.constructor;
  12995. return typeof Ctor == 'function' && Ctor instanceof Ctor &&
  12996. funcToString.call(Ctor) == objectCtorString;
  12997. }
  12998. var isPlainObject_1 = isPlainObject;
  12999. /* eslint-disable */
  13000. var global$1 = typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : {};
  13001. const EXPIRED = Symbol('expired');
  13002. const debug = browser('LC:Expirable');
  13003. class Expirable {
  13004. constructor(value, ttl) {
  13005. this.originalValue = value;
  13006. if (typeof ttl === 'number') {
  13007. this.expiredAt = Date.now() + ttl;
  13008. }
  13009. }
  13010. get value() {
  13011. const expired = this.expiredAt && this.expiredAt <= Date.now();
  13012. if (expired) debug(`expired: ${this.originalValue}`);
  13013. return expired ? EXPIRED : this.originalValue;
  13014. }
  13015. }
  13016. Expirable.EXPIRED = EXPIRED;
  13017. const debug$1 = browser('LC:Cache');
  13018. class Cache {
  13019. constructor(name = 'anonymous') {
  13020. this.name = name;
  13021. this._map = {};
  13022. }
  13023. get(key) {
  13024. const cache = this._map[key];
  13025. if (cache) {
  13026. const {
  13027. value
  13028. } = cache;
  13029. if (value !== Expirable.EXPIRED) {
  13030. debug$1('[%s] hit: %s', this.name, key);
  13031. return value;
  13032. }
  13033. delete this._map[key];
  13034. }
  13035. debug$1(`[${this.name}] missed: ${key}`);
  13036. return null;
  13037. }
  13038. set(key, value, ttl) {
  13039. debug$1('[%s] set: %s %d', this.name, key, ttl);
  13040. this._map[key] = new Expirable(value, ttl);
  13041. }
  13042. }
  13043. /**
  13044. * 调试日志控制器
  13045. * @const
  13046. * @memberof module:leancloud-realtime
  13047. * @example
  13048. * debug.enable(); // 启用调试日志
  13049. * debug.disable(); // 关闭调试日志
  13050. */
  13051. const debug$2 = {
  13052. enable: (namespaces = 'LC*') => browser.enable(namespaces),
  13053. disable: browser.disable
  13054. };
  13055. const tryAll = promiseConstructors => {
  13056. const promise = new Promise(promiseConstructors[0]);
  13057. if (promiseConstructors.length === 1) {
  13058. return promise;
  13059. }
  13060. return promise.catch(() => tryAll(promiseConstructors.slice(1)));
  13061. }; // eslint-disable-next-line no-sequences
  13062. const tap = interceptor => value => (interceptor(value), value);
  13063. const finalize = callback => [// eslint-disable-next-line no-sequences
  13064. value => (callback(), value), error => {
  13065. callback();
  13066. throw error;
  13067. }];
  13068. /**
  13069. * 将对象转换为 Date,支持 string、number、ProtoBuf Long 以及 LeanCloud 的 Date 类型,
  13070. * 其他情况下(包括对象为 falsy)返回原值。
  13071. * @private
  13072. */
  13073. const decodeDate = date => {
  13074. if (!date) return date;
  13075. if (typeof date === 'string' || typeof date === 'number') {
  13076. return new Date(date);
  13077. }
  13078. if (date.__type === 'Date' && date.iso) {
  13079. return new Date(date.iso);
  13080. } // Long
  13081. if (typeof date.toNumber === 'function') {
  13082. return new Date(date.toNumber());
  13083. }
  13084. return date;
  13085. };
  13086. /**
  13087. * 获取 Date 的毫秒数,如果不是一个 Date 返回 undefined。
  13088. * @private
  13089. */
  13090. const getTime = date => date && date.getTime ? date.getTime() : undefined;
  13091. /**
  13092. * 解码对象中的 LeanCloud 数据结构。
  13093. * 目前仅会处理 Date 类型。
  13094. * @private
  13095. */
  13096. const decode = value => {
  13097. if (!value) return value;
  13098. if (value.__type === 'Date' && value.iso) {
  13099. return new Date(value.iso);
  13100. }
  13101. if (Array.isArray(value)) {
  13102. return value.map(decode);
  13103. }
  13104. if (isPlainObject_1(value)) {
  13105. return Object.keys(value).reduce((result, key) => ({ ...result,
  13106. [key]: decode(value[key])
  13107. }), {});
  13108. }
  13109. return value;
  13110. };
  13111. /**
  13112. * 将对象中的特殊类型编码为 LeanCloud 数据结构。
  13113. * 目前仅会处理 Date 类型。
  13114. * @private
  13115. */
  13116. const encode = value => {
  13117. if (value instanceof Date) return {
  13118. __type: 'Date',
  13119. iso: value.toJSON()
  13120. };
  13121. if (Array.isArray(value)) {
  13122. return value.map(encode);
  13123. }
  13124. if (isPlainObject_1(value)) {
  13125. return Object.keys(value).reduce((result, key) => ({ ...result,
  13126. [key]: encode(value[key])
  13127. }), {});
  13128. }
  13129. return value;
  13130. };
  13131. const keyRemap = (keymap, obj) => Object.keys(obj).reduce((newObj, key) => {
  13132. const newKey = keymap[key] || key;
  13133. return Object.assign(newObj, {
  13134. [newKey]: obj[key]
  13135. });
  13136. }, {});
  13137. const isIE10 = global$1.navigator && global$1.navigator.userAgent && global$1.navigator.userAgent.indexOf('MSIE 10.') !== -1;
  13138. /* eslint-disable no-proto */
  13139. const getStaticProperty = (klass, property) => klass[property] || (klass.__proto__ ? getStaticProperty(klass.__proto__, property) : undefined);
  13140. /* eslint-enable no-proto */
  13141. const union = (a, b) => Array.from(new Set([...a, ...b]));
  13142. const difference = (a, b) => Array.from((bSet => new Set(a.filter(x => !bSet.has(x))))(new Set(b)));
  13143. const map = new WeakMap(); // protected property helper
  13144. const internal = object => {
  13145. if (!map.has(object)) {
  13146. map.set(object, {});
  13147. }
  13148. return map.get(object);
  13149. };
  13150. const compact = (obj, filter) => {
  13151. if (!isPlainObject_1(obj)) return obj;
  13152. const object = { ...obj
  13153. };
  13154. Object.keys(object).forEach(prop => {
  13155. const value = object[prop];
  13156. if (value === filter) {
  13157. delete object[prop];
  13158. } else {
  13159. object[prop] = compact(value, filter);
  13160. }
  13161. });
  13162. return object;
  13163. }; // debug utility
  13164. const removeNull = obj => compact(obj, null);
  13165. const trim = message => removeNull(JSON.parse(JSON.stringify(message)));
  13166. const ensureArray = target => {
  13167. if (Array.isArray(target)) {
  13168. return target;
  13169. }
  13170. if (target === undefined || target === null) {
  13171. return [];
  13172. }
  13173. return [target];
  13174. };
  13175. const setValue = (target, key, value) => {
  13176. // '.' is not allowed in Class keys, escaping is not in concern now.
  13177. const segs = key.split('.');
  13178. const lastSeg = segs.pop();
  13179. let currentTarget = target;
  13180. segs.forEach(seg => {
  13181. if (currentTarget[seg] === undefined) currentTarget[seg] = {};
  13182. currentTarget = currentTarget[seg];
  13183. });
  13184. currentTarget[lastSeg] = value;
  13185. return target;
  13186. };
  13187. const isWeapp = // eslint-disable-next-line no-undef
  13188. typeof wx === 'object' && typeof wx.connectSocket === 'function'; // throttle decorator
  13189. const throttle = wait => (target, property, descriptor) => {
  13190. const callback = descriptor.value; // very naive, internal use only
  13191. if (callback.length) {
  13192. throw new Error('throttled function should not accept any arguments');
  13193. }
  13194. return { ...descriptor,
  13195. value() {
  13196. let {
  13197. throttleMeta
  13198. } = internal(this);
  13199. if (!throttleMeta) {
  13200. throttleMeta = {};
  13201. internal(this).throttleMeta = throttleMeta;
  13202. }
  13203. let {
  13204. [property]: propertyMeta
  13205. } = throttleMeta;
  13206. if (!propertyMeta) {
  13207. propertyMeta = {};
  13208. throttleMeta[property] = propertyMeta;
  13209. }
  13210. const {
  13211. previouseTimestamp = 0,
  13212. timeout
  13213. } = propertyMeta;
  13214. const now = Date.now();
  13215. const remainingTime = wait - (now - previouseTimestamp);
  13216. if (remainingTime <= 0) {
  13217. throttleMeta[property].previouseTimestamp = now;
  13218. callback.apply(this);
  13219. } else if (!timeout) {
  13220. propertyMeta.timeout = setTimeout(() => {
  13221. propertyMeta.previouseTimestamp = Date.now();
  13222. delete propertyMeta.timeout;
  13223. callback.apply(this);
  13224. }, remainingTime);
  13225. }
  13226. }
  13227. };
  13228. };
  13229. const isCNApp = appId => appId.slice(-9) !== '-MdYXbMMI';
  13230. const equalBuffer = (buffer1, buffer2) => {
  13231. if (!buffer1 || !buffer2) return false;
  13232. if (buffer1.byteLength !== buffer2.byteLength) return false;
  13233. const a = new Uint8Array(buffer1);
  13234. const b = new Uint8Array(buffer2);
  13235. return !a.some((value, index) => value !== b[index]);
  13236. };
  13237. var _class;
  13238. const debug$3 = browser('LC:WebSocketPlus');
  13239. const OPEN = 'open';
  13240. const DISCONNECT = 'disconnect';
  13241. const RECONNECT = 'reconnect';
  13242. const RETRY = 'retry';
  13243. const SCHEDULE = 'schedule';
  13244. const OFFLINE = 'offline';
  13245. const ONLINE = 'online';
  13246. const ERROR = 'error';
  13247. const MESSAGE = 'message';
  13248. const HEARTBEAT_TIME = 180000;
  13249. const TIMEOUT_TIME = 380000;
  13250. const DEFAULT_RETRY_STRATEGY = attempt => Math.min(1000 * 2 ** attempt, 300000);
  13251. const requireConnected = (target, name, descriptor) => ({ ...descriptor,
  13252. value: function requireConnectedWrapper(...args) {
  13253. this.checkConnectionAvailability(name);
  13254. return descriptor.value.call(this, ...args);
  13255. }
  13256. });
  13257. let WebSocketPlus = (_class = class WebSocketPlus extends eventemitter3 {
  13258. get urls() {
  13259. return this._urls;
  13260. }
  13261. set urls(urls) {
  13262. this._urls = ensureArray(urls);
  13263. }
  13264. constructor(getUrls, protocol) {
  13265. super();
  13266. this.init();
  13267. this._protocol = protocol;
  13268. Promise.resolve(typeof getUrls === 'function' ? getUrls() : getUrls).then(ensureArray).then(urls => {
  13269. this._urls = urls;
  13270. return this._open();
  13271. }).then(() => {
  13272. this.__postponeTimeoutTimer = this._postponeTimeoutTimer.bind(this);
  13273. if (global$1.addEventListener) {
  13274. this.__pause = () => {
  13275. if (this.can('pause')) this.pause();
  13276. };
  13277. this.__resume = () => {
  13278. if (this.can('resume')) this.resume();
  13279. };
  13280. global$1.addEventListener('offline', this.__pause);
  13281. global$1.addEventListener('online', this.__resume);
  13282. }
  13283. this.open();
  13284. }).catch(this.throw.bind(this));
  13285. }
  13286. _open() {
  13287. return this._createWs(this._urls, this._protocol).then(ws => {
  13288. const [first, ...reset] = this._urls;
  13289. this._urls = [...reset, first];
  13290. return ws;
  13291. });
  13292. }
  13293. _createWs(urls, protocol) {
  13294. return tryAll(urls.map(url => (resolve, reject) => {
  13295. debug$3(`connect [${url}] ${protocol}`);
  13296. const WebSocket = getAdapter('WebSocket');
  13297. const ws = protocol ? new WebSocket(url, protocol) : new WebSocket(url);
  13298. ws.binaryType = this.binaryType || 'arraybuffer';
  13299. ws.onopen = () => resolve(ws);
  13300. ws.onclose = error => {
  13301. if (error instanceof Error) {
  13302. return reject(error);
  13303. } // in browser, error event is useless
  13304. return reject(new Error(`Failed to connect [${url}]`));
  13305. };
  13306. ws.onerror = ws.onclose;
  13307. })).then(ws => {
  13308. this._ws = ws;
  13309. this._ws.onclose = this._handleClose.bind(this);
  13310. this._ws.onmessage = this._handleMessage.bind(this);
  13311. return ws;
  13312. });
  13313. }
  13314. _destroyWs() {
  13315. const ws = this._ws;
  13316. if (!ws) return;
  13317. ws.onopen = null;
  13318. ws.onclose = null;
  13319. ws.onerror = null;
  13320. ws.onmessage = null;
  13321. this._ws = null;
  13322. ws.close();
  13323. } // eslint-disable-next-line class-methods-use-this
  13324. onbeforeevent(event, from, to, ...payload) {
  13325. debug$3(`${event}: ${from} -> ${to} %o`, payload);
  13326. }
  13327. onopen() {
  13328. this.emit(OPEN);
  13329. }
  13330. onconnected() {
  13331. this._startConnectionKeeper();
  13332. }
  13333. onleaveconnected(event, from, to) {
  13334. this._stopConnectionKeeper();
  13335. this._destroyWs();
  13336. if (to === 'offline' || to === 'disconnected') {
  13337. this.emit(DISCONNECT);
  13338. }
  13339. }
  13340. onpause() {
  13341. this.emit(OFFLINE);
  13342. }
  13343. onbeforeresume() {
  13344. this.emit(ONLINE);
  13345. }
  13346. onreconnect() {
  13347. this.emit(RECONNECT);
  13348. }
  13349. ondisconnected(event, from, to, attempt = 0) {
  13350. const delay = from === OFFLINE ? 0 : DEFAULT_RETRY_STRATEGY.call(null, attempt);
  13351. debug$3(`schedule attempt=${attempt} delay=${delay}`);
  13352. this.emit(SCHEDULE, attempt, delay);
  13353. if (this.__scheduledRetry) {
  13354. clearTimeout(this.__scheduledRetry);
  13355. }
  13356. this.__scheduledRetry = setTimeout(() => {
  13357. if (this.is('disconnected')) {
  13358. this.retry(attempt);
  13359. }
  13360. }, delay);
  13361. }
  13362. onretry(event, from, to, attempt = 0) {
  13363. this.emit(RETRY, attempt);
  13364. this._open().then(() => this.can('reconnect') && this.reconnect(), () => this.can('fail') && this.fail(attempt + 1));
  13365. }
  13366. onerror(event, from, to, error) {
  13367. this.emit(ERROR, error);
  13368. }
  13369. onclose() {
  13370. if (global$1.removeEventListener) {
  13371. if (this.__pause) global$1.removeEventListener('offline', this.__pause);
  13372. if (this.__resume) global$1.removeEventListener('online', this.__resume);
  13373. }
  13374. }
  13375. checkConnectionAvailability(name = 'API') {
  13376. if (!this.is('connected')) {
  13377. const currentState = this.current;
  13378. console.warn(`${name} should not be called when the connection is ${currentState}`);
  13379. if (this.is('disconnected') || this.is('reconnecting')) {
  13380. console.warn('disconnect and reconnect event should be handled to avoid such calls.');
  13381. }
  13382. throw new Error('Connection unavailable');
  13383. }
  13384. } // jsdoc-ignore-start
  13385. // jsdoc-ignore-end
  13386. _ping() {
  13387. debug$3('ping');
  13388. try {
  13389. this.ping();
  13390. } catch (error) {
  13391. console.warn(`websocket ping error: ${error.message}`);
  13392. }
  13393. }
  13394. ping() {
  13395. if (this._ws.ping) {
  13396. this._ws.ping();
  13397. } else {
  13398. console.warn(`The WebSocket implement does not support sending ping frame.
  13399. Override ping method to use application defined ping/pong mechanism.`);
  13400. }
  13401. }
  13402. _postponeTimeoutTimer() {
  13403. debug$3('_postponeTimeoutTimer');
  13404. this._clearTimeoutTimers();
  13405. this._timeoutTimer = setTimeout(() => {
  13406. debug$3('timeout');
  13407. this.disconnect();
  13408. }, TIMEOUT_TIME);
  13409. }
  13410. _clearTimeoutTimers() {
  13411. if (this._timeoutTimer) {
  13412. clearTimeout(this._timeoutTimer);
  13413. }
  13414. }
  13415. _startConnectionKeeper() {
  13416. debug$3('start connection keeper');
  13417. this._heartbeatTimer = setInterval(this._ping.bind(this), HEARTBEAT_TIME);
  13418. const addListener = this._ws.addListener || this._ws.addEventListener;
  13419. if (!addListener) {
  13420. debug$3('connection keeper disabled due to the lack of #addEventListener.');
  13421. return;
  13422. }
  13423. addListener.call(this._ws, 'message', this.__postponeTimeoutTimer);
  13424. addListener.call(this._ws, 'pong', this.__postponeTimeoutTimer);
  13425. this._postponeTimeoutTimer();
  13426. }
  13427. _stopConnectionKeeper() {
  13428. debug$3('stop connection keeper'); // websockets/ws#489
  13429. const removeListener = this._ws.removeListener || this._ws.removeEventListener;
  13430. if (removeListener) {
  13431. removeListener.call(this._ws, 'message', this.__postponeTimeoutTimer);
  13432. removeListener.call(this._ws, 'pong', this.__postponeTimeoutTimer);
  13433. this._clearTimeoutTimers();
  13434. }
  13435. if (this._heartbeatTimer) {
  13436. clearInterval(this._heartbeatTimer);
  13437. }
  13438. }
  13439. _handleClose(event) {
  13440. debug$3(`ws closed [${event.code}] ${event.reason}`); // socket closed manually, ignore close event.
  13441. if (this.isFinished()) return;
  13442. this.handleClose(event);
  13443. }
  13444. handleClose() {
  13445. // reconnect
  13446. this.disconnect();
  13447. } // jsdoc-ignore-start
  13448. // jsdoc-ignore-end
  13449. send(data) {
  13450. debug$3('send', data);
  13451. this._ws.send(data);
  13452. }
  13453. _handleMessage(event) {
  13454. debug$3('message', event.data);
  13455. this.handleMessage(event.data);
  13456. }
  13457. handleMessage(message) {
  13458. this.emit(MESSAGE, message);
  13459. }
  13460. }, (_applyDecoratedDescriptor(_class.prototype, "_ping", [requireConnected], Object.getOwnPropertyDescriptor(_class.prototype, "_ping"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "send", [requireConnected], Object.getOwnPropertyDescriptor(_class.prototype, "send"), _class.prototype)), _class);
  13461. stateMachine.create({
  13462. target: WebSocketPlus.prototype,
  13463. initial: {
  13464. state: 'initialized',
  13465. event: 'init',
  13466. defer: true
  13467. },
  13468. terminal: 'closed',
  13469. events: [{
  13470. name: 'open',
  13471. from: 'initialized',
  13472. to: 'connected'
  13473. }, {
  13474. name: 'disconnect',
  13475. from: 'connected',
  13476. to: 'disconnected'
  13477. }, {
  13478. name: 'retry',
  13479. from: 'disconnected',
  13480. to: 'reconnecting'
  13481. }, {
  13482. name: 'fail',
  13483. from: 'reconnecting',
  13484. to: 'disconnected'
  13485. }, {
  13486. name: 'reconnect',
  13487. from: 'reconnecting',
  13488. to: 'connected'
  13489. }, {
  13490. name: 'pause',
  13491. from: ['connected', 'disconnected', 'reconnecting'],
  13492. to: 'offline'
  13493. }, {}, {
  13494. name: 'resume',
  13495. from: 'offline',
  13496. to: 'disconnected'
  13497. }, {
  13498. name: 'close',
  13499. from: ['connected', 'disconnected', 'reconnecting', 'offline'],
  13500. to: 'closed'
  13501. }, {
  13502. name: 'throw',
  13503. from: '*',
  13504. to: 'error'
  13505. }]
  13506. });
  13507. const error = Object.freeze({
  13508. 1000: {
  13509. name: 'CLOSE_NORMAL'
  13510. },
  13511. 1006: {
  13512. name: 'CLOSE_ABNORMAL'
  13513. },
  13514. 4100: {
  13515. name: 'APP_NOT_AVAILABLE',
  13516. message: 'App not exists or realtime message service is disabled.'
  13517. },
  13518. 4102: {
  13519. name: 'SIGNATURE_FAILED',
  13520. message: 'Login signature mismatch.'
  13521. },
  13522. 4103: {
  13523. name: 'INVALID_LOGIN',
  13524. message: 'Malformed clientId.'
  13525. },
  13526. 4105: {
  13527. name: 'SESSION_REQUIRED',
  13528. message: 'Message sent before session opened.'
  13529. },
  13530. 4107: {
  13531. name: 'READ_TIMEOUT'
  13532. },
  13533. 4108: {
  13534. name: 'LOGIN_TIMEOUT'
  13535. },
  13536. 4109: {
  13537. name: 'FRAME_TOO_LONG'
  13538. },
  13539. 4110: {
  13540. name: 'INVALID_ORIGIN',
  13541. message: 'Access denied by domain whitelist.'
  13542. },
  13543. 4111: {
  13544. name: 'SESSION_CONFLICT'
  13545. },
  13546. 4112: {
  13547. name: 'SESSION_TOKEN_EXPIRED'
  13548. },
  13549. 4113: {
  13550. name: 'APP_QUOTA_EXCEEDED',
  13551. message: 'The daily active users limit exceeded.'
  13552. },
  13553. 4116: {
  13554. name: 'MESSAGE_SENT_QUOTA_EXCEEDED',
  13555. message: 'Command sent too fast.'
  13556. },
  13557. 4200: {
  13558. name: 'INTERNAL_ERROR',
  13559. message: 'Internal error, please contact LeanCloud for support.'
  13560. },
  13561. 4301: {
  13562. name: 'CONVERSATION_API_FAILED',
  13563. message: 'Upstream Conversatoin API failed, see error.detail for details.'
  13564. },
  13565. 4302: {
  13566. name: 'CONVERSATION_SIGNATURE_FAILED',
  13567. message: 'Conversation action signature mismatch.'
  13568. },
  13569. 4303: {
  13570. name: 'CONVERSATION_NOT_FOUND'
  13571. },
  13572. 4304: {
  13573. name: 'CONVERSATION_FULL'
  13574. },
  13575. 4305: {
  13576. name: 'CONVERSATION_REJECTED_BY_APP',
  13577. message: 'Conversation action rejected by hook.'
  13578. },
  13579. 4306: {
  13580. name: 'CONVERSATION_UPDATE_FAILED'
  13581. },
  13582. 4307: {
  13583. name: 'CONVERSATION_READ_ONLY'
  13584. },
  13585. 4308: {
  13586. name: 'CONVERSATION_NOT_ALLOWED'
  13587. },
  13588. 4309: {
  13589. name: 'CONVERSATION_UPDATE_REJECTED',
  13590. message: 'Conversation update rejected because the client is not a member.'
  13591. },
  13592. 4310: {
  13593. name: 'CONVERSATION_QUERY_FAILED',
  13594. message: 'Conversation query failed because it is too expansive.'
  13595. },
  13596. 4311: {
  13597. name: 'CONVERSATION_LOG_FAILED'
  13598. },
  13599. 4312: {
  13600. name: 'CONVERSATION_LOG_REJECTED',
  13601. message: 'Message query rejected because the client is not a member of the conversation.'
  13602. },
  13603. 4313: {
  13604. name: 'SYSTEM_CONVERSATION_REQUIRED'
  13605. },
  13606. 4314: {
  13607. name: 'NORMAL_CONVERSATION_REQUIRED'
  13608. },
  13609. 4315: {
  13610. name: 'CONVERSATION_BLACKLISTED',
  13611. message: 'Blacklisted in the conversation.'
  13612. },
  13613. 4316: {
  13614. name: 'TRANSIENT_CONVERSATION_REQUIRED'
  13615. },
  13616. 4317: {
  13617. name: 'CONVERSATION_MEMBERSHIP_REQUIRED'
  13618. },
  13619. 4318: {
  13620. name: 'CONVERSATION_API_QUOTA_EXCEEDED',
  13621. message: 'LeanCloud API quota exceeded. You may upgrade your plan.'
  13622. },
  13623. 4323: {
  13624. name: 'TEMPORARY_CONVERSATION_EXPIRED',
  13625. message: 'Temporary conversation expired or does not exist.'
  13626. },
  13627. 4401: {
  13628. name: 'INVALID_MESSAGING_TARGET',
  13629. message: 'Conversation does not exist or client is not a member.'
  13630. },
  13631. 4402: {
  13632. name: 'MESSAGE_REJECTED_BY_APP',
  13633. message: 'Message rejected by hook.'
  13634. },
  13635. 4403: {
  13636. name: 'MESSAGE_OWNERSHIP_REQUIRED'
  13637. },
  13638. 4404: {
  13639. name: 'MESSAGE_NOT_FOUND'
  13640. },
  13641. 4405: {
  13642. name: 'MESSAGE_UPDATE_REJECTED_BY_APP',
  13643. message: 'Message update rejected by hook.'
  13644. },
  13645. 4406: {
  13646. name: 'MESSAGE_EDIT_DISABLED'
  13647. },
  13648. 4407: {
  13649. name: 'MESSAGE_RECALL_DISABLED'
  13650. },
  13651. 5130: {
  13652. name: 'OWNER_PROMOTION_NOT_ALLOWED',
  13653. message: "Updating a member's role to owner is not allowed."
  13654. }
  13655. });
  13656. const ErrorCode = Object.freeze(Object.keys(error).reduce((result, code) => Object.assign(result, {
  13657. [error[code].name]: Number(code)
  13658. }), {}));
  13659. const createError = ({
  13660. code,
  13661. reason,
  13662. appCode,
  13663. detail,
  13664. error: errorMessage
  13665. }) => {
  13666. let message = reason || detail || errorMessage;
  13667. let name = reason;
  13668. if (!message && error[code]) {
  13669. ({
  13670. name
  13671. } = error[code]);
  13672. message = error[code].message || name;
  13673. }
  13674. if (!message) {
  13675. message = `Unknow Error: ${code}`;
  13676. }
  13677. const err = new Error(message);
  13678. return Object.assign(err, {
  13679. code,
  13680. appCode,
  13681. detail,
  13682. name
  13683. });
  13684. };
  13685. const debug$4 = browser('LC:Connection');
  13686. const COMMAND_TIMEOUT = 20000;
  13687. const EXPIRE = Symbol('expire');
  13688. const isIdempotentCommand = command => !(command.cmd === CommandType.direct || command.cmd === CommandType.session && command.op === OpType.open || command.cmd === CommandType.conv && (command.op === OpType.start || command.op === OpType.update || command.op === OpType.members));
  13689. class Connection extends WebSocketPlus {
  13690. constructor(getUrl, {
  13691. format,
  13692. version
  13693. }) {
  13694. debug$4('initializing Connection');
  13695. const protocolString = `lc.${format}.${version}`;
  13696. super(getUrl, protocolString);
  13697. this._protocolFormat = format;
  13698. this._commands = {};
  13699. this._serialId = 0;
  13700. }
  13701. async send(command, waitingForRespond = true) {
  13702. let buffer;
  13703. let serialId;
  13704. if (waitingForRespond) {
  13705. if (isIdempotentCommand(command)) {
  13706. buffer = command.toArrayBuffer();
  13707. const duplicatedCommand = values_1(this._commands).find(({
  13708. buffer: targetBuffer,
  13709. command: targetCommand
  13710. }) => targetCommand.cmd === command.cmd && targetCommand.op === command.op && equalBuffer(targetBuffer, buffer));
  13711. if (duplicatedCommand) {
  13712. console.warn(`Duplicated command [cmd:${command.cmd} op:${command.op}] is throttled.`);
  13713. return duplicatedCommand.promise;
  13714. }
  13715. }
  13716. this._serialId += 1;
  13717. serialId = this._serialId;
  13718. command.i = serialId; // eslint-disable-line no-param-reassign
  13719. }
  13720. if (debug$4.enabled) debug$4('↑ %O sent', trim(command));
  13721. let message;
  13722. if (this._protocolFormat === 'proto2base64') {
  13723. message = command.toBase64();
  13724. } else if (command.toArrayBuffer) {
  13725. message = command.toArrayBuffer();
  13726. }
  13727. if (!message) {
  13728. throw new TypeError(`${command} is not a GenericCommand`);
  13729. }
  13730. super.send(message);
  13731. if (!waitingForRespond) return undefined;
  13732. const promise = new Promise((resolve, reject) => {
  13733. this._commands[serialId] = {
  13734. command,
  13735. buffer,
  13736. resolve,
  13737. reject,
  13738. timeout: setTimeout(() => {
  13739. if (this._commands[serialId]) {
  13740. if (debug$4.enabled) debug$4('✗ %O timeout', trim(command));
  13741. reject(createError({
  13742. error: `Command Timeout [cmd:${command.cmd} op:${command.op}]`,
  13743. name: 'COMMAND_TIMEOUT'
  13744. }));
  13745. delete this._commands[serialId];
  13746. }
  13747. }, COMMAND_TIMEOUT)
  13748. };
  13749. });
  13750. this._commands[serialId].promise = promise;
  13751. return promise;
  13752. }
  13753. handleMessage(msg) {
  13754. let message;
  13755. try {
  13756. message = GenericCommand.decode(msg);
  13757. if (debug$4.enabled) debug$4('↓ %O received', trim(message));
  13758. } catch (e) {
  13759. console.warn('Decode message failed:', e.message, msg);
  13760. return;
  13761. }
  13762. const serialId = message.i;
  13763. if (serialId) {
  13764. if (this._commands[serialId]) {
  13765. clearTimeout(this._commands[serialId].timeout);
  13766. if (message.cmd === CommandType.error) {
  13767. this._commands[serialId].reject(createError(message.errorMessage));
  13768. } else {
  13769. this._commands[serialId].resolve(message);
  13770. }
  13771. delete this._commands[serialId];
  13772. } else {
  13773. console.warn(`Unexpected command received with serialId [${serialId}],
  13774. which have timed out or never been requested.`);
  13775. }
  13776. } else {
  13777. switch (message.cmd) {
  13778. case CommandType.error:
  13779. {
  13780. this.emit(ERROR, createError(message.errorMessage));
  13781. return;
  13782. }
  13783. case CommandType.goaway:
  13784. {
  13785. this.emit(EXPIRE);
  13786. return;
  13787. }
  13788. default:
  13789. {
  13790. this.emit(MESSAGE, message);
  13791. }
  13792. }
  13793. }
  13794. }
  13795. ping() {
  13796. return this.send(new GenericCommand({
  13797. cmd: CommandType.echo
  13798. })).catch(error => debug$4('ping failed:', error));
  13799. }
  13800. }
  13801. var promiseTimeout = createCommonjsModule(function (module) {
  13802. /**
  13803. * Local reference to TimeoutError
  13804. * @private
  13805. */
  13806. var TimeoutError;
  13807. /**
  13808. * Rejects a promise with a {@link TimeoutError} if it does not settle within
  13809. * the specified timeout.
  13810. *
  13811. * @param {Promise} promise The promise.
  13812. * @param {number} timeoutMillis Number of milliseconds to wait on settling.
  13813. * @returns {Promise} Either resolves/rejects with `promise`, or rejects with
  13814. * `TimeoutError`, whichever settles first.
  13815. */
  13816. var timeout = module.exports.timeout = function (promise, timeoutMillis) {
  13817. var error = new TimeoutError(),
  13818. timeout;
  13819. return Promise.race([promise, new Promise(function (resolve, reject) {
  13820. timeout = setTimeout(function () {
  13821. reject(error);
  13822. }, timeoutMillis);
  13823. })]).then(function (v) {
  13824. clearTimeout(timeout);
  13825. return v;
  13826. }, function (err) {
  13827. clearTimeout(timeout);
  13828. throw err;
  13829. });
  13830. };
  13831. /**
  13832. * Exception indicating that the timeout expired.
  13833. */
  13834. TimeoutError = module.exports.TimeoutError = function () {
  13835. Error.call(this);
  13836. this.stack = Error().stack;
  13837. this.message = 'Timeout';
  13838. };
  13839. TimeoutError.prototype = Object.create(Error.prototype);
  13840. TimeoutError.prototype.name = "TimeoutError";
  13841. });
  13842. var promiseTimeout_1 = promiseTimeout.timeout;
  13843. var promiseTimeout_2 = promiseTimeout.TimeoutError;
  13844. const debug$5 = browser('LC:request');
  13845. var request = (({
  13846. method = 'GET',
  13847. url: _url,
  13848. query,
  13849. headers,
  13850. data,
  13851. timeout: time
  13852. }) => {
  13853. let url = _url;
  13854. if (query) {
  13855. const queryString = Object.keys(query).map(key => {
  13856. const value = query[key];
  13857. if (value === undefined) return undefined;
  13858. const v = isPlainObject_1(value) ? JSON.stringify(value) : value;
  13859. return `${encodeURIComponent(key)}=${encodeURIComponent(v)}`;
  13860. }).filter(qs => qs).join('&');
  13861. url = `${url}?${queryString}`;
  13862. }
  13863. debug$5('Req: %O %O %O', method, url, {
  13864. headers,
  13865. data
  13866. });
  13867. const request = getAdapter('request');
  13868. const promise = request(url, {
  13869. method,
  13870. headers,
  13871. data
  13872. }).then(response => {
  13873. if (response.ok === false) {
  13874. const error = createError(response.data);
  13875. error.response = response;
  13876. throw error;
  13877. }
  13878. debug$5('Res: %O %O %O', url, response.status, response.data);
  13879. return response.data;
  13880. }).catch(error => {
  13881. if (error.response) {
  13882. debug$5('Error: %O %O %O', url, error.response.status, error.response.data);
  13883. }
  13884. throw error;
  13885. });
  13886. return time ? promiseTimeout_1(promise, time) : promise;
  13887. });
  13888. /* eslint-disable max-len */
  13889. const checkType = middleware => param => {
  13890. const {
  13891. constructor
  13892. } = param;
  13893. return Promise.resolve(param).then(middleware).then(tap(result => {
  13894. if (result === undefined || result === null) {
  13895. // eslint-disable-next-line max-len
  13896. return console.warn(`Middleware[${middleware._pluginName || 'anonymous plugin'}:${middleware.name || 'anonymous middleware'}] param/return types not match. It returns ${result} while a ${param.constructor.name} expected.`);
  13897. }
  13898. if (!(result instanceof constructor)) {
  13899. // eslint-disable-next-line max-len
  13900. return console.warn(`Middleware[${middleware._pluginName || 'anonymous plugin'}:${middleware.name || 'anonymous middleware'}] param/return types not match. It returns a ${result.constructor.name} while a ${param.constructor.name} expected.`);
  13901. }
  13902. return 0;
  13903. }));
  13904. };
  13905. const applyDecorators = (decorators, target) => {
  13906. if (decorators) {
  13907. decorators.forEach(decorator => {
  13908. try {
  13909. decorator(target);
  13910. } catch (error) {
  13911. if (decorator._pluginName) {
  13912. error.message += `[${decorator._pluginName}]`;
  13913. }
  13914. throw error;
  13915. }
  13916. });
  13917. }
  13918. };
  13919. const applyMiddlewares = middlewares => target => ensureArray(middlewares).reduce((previousPromise, middleware) => previousPromise.then(checkType(middleware)).catch(error => {
  13920. if (middleware._pluginName) {
  13921. // eslint-disable-next-line no-param-reassign
  13922. error.message += `[${middleware._pluginName}]`;
  13923. }
  13924. throw error;
  13925. }), Promise.resolve(target));
  13926. const applyDispatcher = (dispatchers, payload) => ensureArray(dispatchers).reduce((resultPromise, dispatcher) => resultPromise.then(shouldDispatch => shouldDispatch === false ? false : dispatcher(...payload)).catch(error => {
  13927. if (dispatcher._pluginName) {
  13928. // eslint-disable-next-line no-param-reassign
  13929. error.message += `[${dispatcher._pluginName}]`;
  13930. }
  13931. throw error;
  13932. }), Promise.resolve(true));
  13933. var version = "5.0.0-rc.7";
  13934. // eslint-disable-next-line max-classes-per-file
  13935. const debug$6 = browser('LC:Realtime');
  13936. const routerCache = new Cache('push-router');
  13937. const initializedApp = {};
  13938. class Realtime extends eventemitter3 {
  13939. /**
  13940. * @extends EventEmitter
  13941. * @param {Object} options
  13942. * @param {String} options.appId
  13943. * @param {String} options.appKey (since 4.0.0)
  13944. * @param {String|Object} [options.server] 指定服务器域名,中国节点应用此参数必填(since 4.0.0)
  13945. * @param {Boolean} [options.noBinary=false] 设置 WebSocket 使用字符串格式收发消息(默认为二进制格式)。
  13946. * 适用于 WebSocket 实现不支持二进制数据格式的情况
  13947. * @param {Boolean} [options.ssl=true] 使用 wss 进行连接
  13948. * @param {String|String[]} [options.RTMServers] 指定私有部署的 RTM 服务器地址(since 4.0.0)
  13949. * @param {Plugin[]} [options.plugins] 加载插件(since 3.1.0)
  13950. */
  13951. constructor({
  13952. plugins,
  13953. ...options
  13954. }) {
  13955. debug$6('initializing Realtime %s %O', version, options);
  13956. super();
  13957. const {
  13958. appId
  13959. } = options;
  13960. if (typeof appId !== 'string') {
  13961. throw new TypeError(`appId [${appId}] is not a string`);
  13962. }
  13963. if (initializedApp[appId]) {
  13964. throw new Error(`App [${appId}] is already initialized.`);
  13965. }
  13966. initializedApp[appId] = true;
  13967. if (typeof options.appKey !== 'string') {
  13968. throw new TypeError(`appKey [${options.appKey}] is not a string`);
  13969. }
  13970. if (isCNApp(appId)) {
  13971. if (!options.server) {
  13972. throw new TypeError(`server option is required for apps from CN region`);
  13973. }
  13974. }
  13975. this._options = {
  13976. appId: undefined,
  13977. appKey: undefined,
  13978. noBinary: false,
  13979. ssl: true,
  13980. RTMServerName: typeof process !== 'undefined' ? process.env.RTM_SERVER_NAME : undefined,
  13981. // undocumented on purpose, internal use only
  13982. ...options
  13983. };
  13984. this._cache = new Cache('endpoints');
  13985. const _this = internal(this);
  13986. _this.clients = new Set();
  13987. _this.pendingClients = new Set();
  13988. const mergedPlugins = [...ensureArray(Realtime.__preRegisteredPlugins), ...ensureArray(plugins)];
  13989. debug$6('Using plugins %o', mergedPlugins.map(plugin => plugin.name));
  13990. this._plugins = mergedPlugins.reduce((result, plugin) => {
  13991. Object.keys(plugin).forEach(hook => {
  13992. if ({}.hasOwnProperty.call(plugin, hook) && hook !== 'name') {
  13993. if (plugin.name) {
  13994. ensureArray(plugin[hook]).forEach(value => {
  13995. // eslint-disable-next-line no-param-reassign
  13996. value._pluginName = plugin.name;
  13997. });
  13998. } // eslint-disable-next-line no-param-reassign
  13999. result[hook] = ensureArray(result[hook]).concat(plugin[hook]);
  14000. }
  14001. });
  14002. return result;
  14003. }, {}); // onRealtimeCreate hook
  14004. applyDecorators(this._plugins.onRealtimeCreate, this);
  14005. }
  14006. async _request({
  14007. method,
  14008. url: _url,
  14009. version = '1.1',
  14010. path,
  14011. query,
  14012. headers,
  14013. data
  14014. }) {
  14015. let url = _url;
  14016. if (!url) {
  14017. const {
  14018. appId,
  14019. server
  14020. } = this._options;
  14021. const {
  14022. api
  14023. } = await this.constructor._getServerUrls({
  14024. appId,
  14025. server
  14026. });
  14027. url = `${api}/${version}${path}`;
  14028. }
  14029. return request({
  14030. url,
  14031. method,
  14032. query,
  14033. headers: {
  14034. 'X-LC-Id': this._options.appId,
  14035. 'X-LC-Key': this._options.appKey,
  14036. ...headers
  14037. },
  14038. data
  14039. });
  14040. }
  14041. _open() {
  14042. if (this._openPromise) return this._openPromise;
  14043. let format = 'protobuf2';
  14044. if (this._options.noBinary) {
  14045. // 不发送 binary data,fallback to base64 string
  14046. format = 'proto2base64';
  14047. }
  14048. const version = 3;
  14049. const protocol = {
  14050. format,
  14051. version
  14052. };
  14053. this._openPromise = new Promise((resolve, reject) => {
  14054. debug$6('No connection established, create a new one.');
  14055. const connection = new Connection(() => this._getRTMServers(this._options), protocol);
  14056. connection.on(OPEN, () => resolve(connection)).on(ERROR, error => {
  14057. delete this._openPromise;
  14058. reject(error);
  14059. }).on(EXPIRE, async () => {
  14060. debug$6('Connection expired. Refresh endpoints.');
  14061. this._cache.set('endpoints', null, 0);
  14062. connection.urls = await this._getRTMServers(this._options);
  14063. connection.disconnect();
  14064. }).on(MESSAGE, this._dispatchCommand.bind(this));
  14065. /**
  14066. * 连接断开。
  14067. * 连接断开可能是因为 SDK 进入了离线状态(see {@link Realtime#event:OFFLINE}),或长时间没有收到服务器心跳。
  14068. * 连接断开后所有的网络操作都会失败,请在连接断开后禁用相关的 UI 元素。
  14069. * @event Realtime#DISCONNECT
  14070. */
  14071. /**
  14072. * 计划在一段时间后尝试重新连接
  14073. * @event Realtime#SCHEDULE
  14074. * @param {Number} attempt 尝试重连的次数
  14075. * @param {Number} delay 延迟的毫秒数
  14076. */
  14077. /**
  14078. * 正在尝试重新连接
  14079. * @event Realtime#RETRY
  14080. * @param {Number} attempt 尝试重连的次数
  14081. */
  14082. /**
  14083. * 连接恢复正常。
  14084. * 请重新启用在 {@link Realtime#event:DISCONNECT} 事件中禁用的相关 UI 元素
  14085. * @event Realtime#RECONNECT
  14086. */
  14087. /**
  14088. * 客户端连接断开
  14089. * @event IMClient#DISCONNECT
  14090. * @see Realtime#event:DISCONNECT
  14091. * @since 3.2.0
  14092. */
  14093. /**
  14094. * 计划在一段时间后尝试重新连接
  14095. * @event IMClient#SCHEDULE
  14096. * @param {Number} attempt 尝试重连的次数
  14097. * @param {Number} delay 延迟的毫秒数
  14098. * @since 3.2.0
  14099. */
  14100. /**
  14101. * 正在尝试重新连接
  14102. * @event IMClient#RETRY
  14103. * @param {Number} attempt 尝试重连的次数
  14104. * @since 3.2.0
  14105. */
  14106. /**
  14107. * 客户端进入离线状态。
  14108. * 这通常意味着网络已断开,或者 {@link Realtime#pause} 被调用
  14109. * @event Realtime#OFFLINE
  14110. * @since 3.4.0
  14111. */
  14112. /**
  14113. * 客户端恢复在线状态
  14114. * 这通常意味着网络已恢复,或者 {@link Realtime#resume} 被调用
  14115. * @event Realtime#ONLINE
  14116. * @since 3.4.0
  14117. */
  14118. /**
  14119. * 进入离线状态。
  14120. * 这通常意味着网络已断开,或者 {@link Realtime#pause} 被调用
  14121. * @event IMClient#OFFLINE
  14122. * @since 3.4.0
  14123. */
  14124. /**
  14125. * 恢复在线状态
  14126. * 这通常意味着网络已恢复,或者 {@link Realtime#resume} 被调用
  14127. * @event IMClient#ONLINE
  14128. * @since 3.4.0
  14129. */
  14130. // event proxy
  14131. [DISCONNECT, RECONNECT, RETRY, SCHEDULE, OFFLINE, ONLINE].forEach(event => connection.on(event, (...payload) => {
  14132. debug$6(`${event} event emitted. %o`, payload);
  14133. this.emit(event, ...payload);
  14134. if (event !== RECONNECT) {
  14135. internal(this).clients.forEach(client => {
  14136. client.emit(event, ...payload);
  14137. });
  14138. }
  14139. })); // override handleClose
  14140. connection.handleClose = function handleClose(event) {
  14141. const isFatal = [ErrorCode.APP_NOT_AVAILABLE, ErrorCode.INVALID_LOGIN, ErrorCode.INVALID_ORIGIN].some(errorCode => errorCode === event.code);
  14142. if (isFatal) {
  14143. // in these cases, SDK should throw.
  14144. this.throw(createError(event));
  14145. } else {
  14146. // reconnect
  14147. this.disconnect();
  14148. }
  14149. };
  14150. internal(this).connection = connection;
  14151. });
  14152. return this._openPromise;
  14153. }
  14154. async _getRTMServers(options) {
  14155. if (options.RTMServers) return shuffle_1(ensureArray(options.RTMServers));
  14156. let info;
  14157. const cachedEndPoints = this._cache.get('endpoints');
  14158. if (cachedEndPoints) {
  14159. info = cachedEndPoints;
  14160. } else {
  14161. info = await this.constructor._fetchRTMServers(options);
  14162. const {
  14163. server,
  14164. secondary,
  14165. ttl
  14166. } = info;
  14167. if (typeof server !== 'string' && typeof secondary !== 'string' && typeof ttl !== 'number') {
  14168. throw new Error(`malformed RTM route response: ${JSON.stringify(info)}`);
  14169. }
  14170. this._cache.set('endpoints', info, info.ttl * 1000);
  14171. }
  14172. debug$6('endpoint info: %O', info);
  14173. return [info.server, info.secondary];
  14174. }
  14175. static async _getServerUrls({
  14176. appId,
  14177. server
  14178. }) {
  14179. debug$6('fetch server urls');
  14180. if (server) {
  14181. if (typeof server !== 'string') return server;
  14182. return {
  14183. RTMRouter: server,
  14184. api: server
  14185. };
  14186. }
  14187. const cachedRouter = routerCache.get(appId);
  14188. if (cachedRouter) return cachedRouter;
  14189. const defaultProtocol = 'https://';
  14190. return request({
  14191. url: 'https://app-router.com/2/route',
  14192. query: {
  14193. appId
  14194. },
  14195. timeout: 20000
  14196. }).then(tap(debug$6)).then(({
  14197. rtm_router_server: RTMRouterServer,
  14198. api_server: APIServer,
  14199. ttl = 3600
  14200. }) => {
  14201. if (!RTMRouterServer) {
  14202. throw new Error('rtm router not exists');
  14203. }
  14204. const serverUrls = {
  14205. RTMRouter: `${defaultProtocol}${RTMRouterServer}`,
  14206. api: `${defaultProtocol}${APIServer}`
  14207. };
  14208. routerCache.set(appId, serverUrls, ttl * 1000);
  14209. return serverUrls;
  14210. }).catch(() => {
  14211. const id = appId.slice(0, 8).toLowerCase();
  14212. const domain = 'lncldglobal.com';
  14213. return {
  14214. RTMRouter: `${defaultProtocol}${id}.rtm.${domain}`,
  14215. api: `${defaultProtocol}${id}.api.${domain}`
  14216. };
  14217. });
  14218. }
  14219. static _fetchRTMServers({
  14220. appId,
  14221. ssl,
  14222. server,
  14223. RTMServerName
  14224. }) {
  14225. debug$6('fetch endpoint info');
  14226. return this._getServerUrls({
  14227. appId,
  14228. server
  14229. }).then(tap(debug$6)).then(({
  14230. RTMRouter
  14231. }) => request({
  14232. url: `${RTMRouter}/v1/route`,
  14233. query: {
  14234. appId,
  14235. secure: ssl,
  14236. features: isWeapp ? 'wechat' : undefined,
  14237. server: RTMServerName,
  14238. _t: Date.now()
  14239. },
  14240. timeout: 20000
  14241. }).then(tap(debug$6)));
  14242. }
  14243. _close() {
  14244. if (this._openPromise) {
  14245. this._openPromise.then(connection => connection.close());
  14246. }
  14247. delete this._openPromise;
  14248. }
  14249. /**
  14250. * 手动进行重连。
  14251. * SDK 在网络出现异常时会自动按照一定的时间间隔尝试重连,调用该方法会立即尝试重连并重置重连尝试计数器。
  14252. * 只能在 `SCHEDULE` 事件之后,`RETRY` 事件之前调用,如果当前网络正常或者正在进行重连,调用该方法会抛异常。
  14253. */
  14254. retry() {
  14255. const {
  14256. connection
  14257. } = internal(this);
  14258. if (!connection) {
  14259. throw new Error('no connection established');
  14260. }
  14261. if (connection.cannot('retry')) {
  14262. throw new Error(`retrying not allowed when not disconnected. the connection is now ${connection.current}`);
  14263. }
  14264. return connection.retry();
  14265. }
  14266. /**
  14267. * 暂停,使 SDK 进入离线状态。
  14268. * 你可以在网络断开、应用进入后台等时刻调用该方法让 SDK 进入离线状态,离线状态下不会尝试重连。
  14269. * 在浏览器中 SDK 会自动监听网络变化,因此无需手动调用该方法。
  14270. *
  14271. * @since 3.4.0
  14272. * @see Realtime#event:OFFLINE
  14273. */
  14274. pause() {
  14275. // 这个方法常常在网络断开、进入后台时被调用,此时 connection 可能没有建立或者已经 close。
  14276. // 因此不像 retry,这个方法应该尽可能 loose
  14277. const {
  14278. connection
  14279. } = internal(this);
  14280. if (!connection) return;
  14281. if (connection.can('pause')) connection.pause();
  14282. }
  14283. /**
  14284. * 恢复在线状态。
  14285. * 你可以在网络恢复、应用回到前台等时刻调用该方法让 SDK 恢复在线状态,恢复在线状态后 SDK 会开始尝试重连。
  14286. *
  14287. * @since 3.4.0
  14288. * @see Realtime#event:ONLINE
  14289. */
  14290. resume() {
  14291. // 与 pause 一样,这个方法应该尽可能 loose
  14292. const {
  14293. connection
  14294. } = internal(this);
  14295. if (!connection) return;
  14296. if (connection.can('resume')) connection.resume();
  14297. }
  14298. _registerPending(value) {
  14299. internal(this).pendingClients.add(value);
  14300. }
  14301. _deregisterPending(client) {
  14302. internal(this).pendingClients.delete(client);
  14303. }
  14304. _register(client) {
  14305. internal(this).clients.add(client);
  14306. }
  14307. _deregister(client) {
  14308. const _this = internal(this);
  14309. _this.clients.delete(client);
  14310. if (_this.clients.size + _this.pendingClients.size === 0) {
  14311. this._close();
  14312. }
  14313. }
  14314. _dispatchCommand(command) {
  14315. return applyDispatcher(this._plugins.beforeCommandDispatch, [command, this]).then(shouldDispatch => {
  14316. // no plugin handled this command
  14317. if (shouldDispatch) return debug$6('[WARN] Unexpected message received: %O', trim(command));
  14318. return false;
  14319. });
  14320. }
  14321. } // For test purpose only
  14322. const polyfilledPromise = Promise;
  14323. var rngBrowser = createCommonjsModule(function (module) {
  14324. // Unique ID creation requires a high quality random # generator. In the
  14325. // browser this is a little complicated due to unknown quality of Math.random()
  14326. // and inconsistent support for the `crypto` API. We do the best we can via
  14327. // feature-detection
  14328. // getRandomValues needs to be invoked in a context where "this" is a Crypto
  14329. // implementation. Also, find the complete implementation of crypto on IE11.
  14330. var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||
  14331. (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));
  14332. if (getRandomValues) {
  14333. // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
  14334. var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef
  14335. module.exports = function whatwgRNG() {
  14336. getRandomValues(rnds8);
  14337. return rnds8;
  14338. };
  14339. } else {
  14340. // Math.random()-based (RNG)
  14341. //
  14342. // If all else fails, use Math.random(). It's fast, but is of unspecified
  14343. // quality.
  14344. var rnds = new Array(16);
  14345. module.exports = function mathRNG() {
  14346. for (var i = 0, r; i < 16; i++) {
  14347. if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
  14348. rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
  14349. }
  14350. return rnds;
  14351. };
  14352. }
  14353. });
  14354. /**
  14355. * Convert array of 16 byte values to UUID string format of the form:
  14356. * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
  14357. */
  14358. var byteToHex = [];
  14359. for (var i = 0; i < 256; ++i) {
  14360. byteToHex[i] = (i + 0x100).toString(16).substr(1);
  14361. }
  14362. function bytesToUuid(buf, offset) {
  14363. var i = offset || 0;
  14364. var bth = byteToHex;
  14365. // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
  14366. return ([bth[buf[i++]], bth[buf[i++]],
  14367. bth[buf[i++]], bth[buf[i++]], '-',
  14368. bth[buf[i++]], bth[buf[i++]], '-',
  14369. bth[buf[i++]], bth[buf[i++]], '-',
  14370. bth[buf[i++]], bth[buf[i++]], '-',
  14371. bth[buf[i++]], bth[buf[i++]],
  14372. bth[buf[i++]], bth[buf[i++]],
  14373. bth[buf[i++]], bth[buf[i++]]]).join('');
  14374. }
  14375. var bytesToUuid_1 = bytesToUuid;
  14376. function v4(options, buf, offset) {
  14377. var i = buf && offset || 0;
  14378. if (typeof(options) == 'string') {
  14379. buf = options === 'binary' ? new Array(16) : null;
  14380. options = null;
  14381. }
  14382. options = options || {};
  14383. var rnds = options.random || (options.rng || rngBrowser)();
  14384. // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
  14385. rnds[6] = (rnds[6] & 0x0f) | 0x40;
  14386. rnds[8] = (rnds[8] & 0x3f) | 0x80;
  14387. // Copy bytes to buffer, if provided
  14388. if (buf) {
  14389. for (var ii = 0; ii < 16; ++ii) {
  14390. buf[i + ii] = rnds[ii];
  14391. }
  14392. }
  14393. return buf || bytesToUuid_1(rnds);
  14394. }
  14395. var v4_1 = v4;
  14396. var base64Arraybuffer = createCommonjsModule(function (module, exports) {
  14397. /*
  14398. * base64-arraybuffer
  14399. * https://github.com/niklasvh/base64-arraybuffer
  14400. *
  14401. * Copyright (c) 2012 Niklas von Hertzen
  14402. * Licensed under the MIT license.
  14403. */
  14404. (function(){
  14405. var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  14406. // Use a lookup table to find the index.
  14407. var lookup = new Uint8Array(256);
  14408. for (var i = 0; i < chars.length; i++) {
  14409. lookup[chars.charCodeAt(i)] = i;
  14410. }
  14411. exports.encode = function(arraybuffer) {
  14412. var bytes = new Uint8Array(arraybuffer),
  14413. i, len = bytes.length, base64 = "";
  14414. for (i = 0; i < len; i+=3) {
  14415. base64 += chars[bytes[i] >> 2];
  14416. base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
  14417. base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
  14418. base64 += chars[bytes[i + 2] & 63];
  14419. }
  14420. if ((len % 3) === 2) {
  14421. base64 = base64.substring(0, base64.length - 1) + "=";
  14422. } else if (len % 3 === 1) {
  14423. base64 = base64.substring(0, base64.length - 2) + "==";
  14424. }
  14425. return base64;
  14426. };
  14427. exports.decode = function(base64) {
  14428. var bufferLength = base64.length * 0.75,
  14429. len = base64.length, i, p = 0,
  14430. encoded1, encoded2, encoded3, encoded4;
  14431. if (base64[base64.length - 1] === "=") {
  14432. bufferLength--;
  14433. if (base64[base64.length - 2] === "=") {
  14434. bufferLength--;
  14435. }
  14436. }
  14437. var arraybuffer = new ArrayBuffer(bufferLength),
  14438. bytes = new Uint8Array(arraybuffer);
  14439. for (i = 0; i < len; i+=4) {
  14440. encoded1 = lookup[base64.charCodeAt(i)];
  14441. encoded2 = lookup[base64.charCodeAt(i+1)];
  14442. encoded3 = lookup[base64.charCodeAt(i+2)];
  14443. encoded4 = lookup[base64.charCodeAt(i+3)];
  14444. bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
  14445. bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
  14446. bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
  14447. }
  14448. return arraybuffer;
  14449. };
  14450. })();
  14451. });
  14452. var base64Arraybuffer_1 = base64Arraybuffer.encode;
  14453. var base64Arraybuffer_2 = base64Arraybuffer.decode;
  14454. /**
  14455. * Removes all key-value entries from the list cache.
  14456. *
  14457. * @private
  14458. * @name clear
  14459. * @memberOf ListCache
  14460. */
  14461. function listCacheClear() {
  14462. this.__data__ = [];
  14463. this.size = 0;
  14464. }
  14465. var _listCacheClear = listCacheClear;
  14466. /**
  14467. * Performs a
  14468. * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  14469. * comparison between two values to determine if they are equivalent.
  14470. *
  14471. * @static
  14472. * @memberOf _
  14473. * @since 4.0.0
  14474. * @category Lang
  14475. * @param {*} value The value to compare.
  14476. * @param {*} other The other value to compare.
  14477. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  14478. * @example
  14479. *
  14480. * var object = { 'a': 1 };
  14481. * var other = { 'a': 1 };
  14482. *
  14483. * _.eq(object, object);
  14484. * // => true
  14485. *
  14486. * _.eq(object, other);
  14487. * // => false
  14488. *
  14489. * _.eq('a', 'a');
  14490. * // => true
  14491. *
  14492. * _.eq('a', Object('a'));
  14493. * // => false
  14494. *
  14495. * _.eq(NaN, NaN);
  14496. * // => true
  14497. */
  14498. function eq(value, other) {
  14499. return value === other || (value !== value && other !== other);
  14500. }
  14501. var eq_1 = eq;
  14502. /**
  14503. * Gets the index at which the `key` is found in `array` of key-value pairs.
  14504. *
  14505. * @private
  14506. * @param {Array} array The array to inspect.
  14507. * @param {*} key The key to search for.
  14508. * @returns {number} Returns the index of the matched value, else `-1`.
  14509. */
  14510. function assocIndexOf(array, key) {
  14511. var length = array.length;
  14512. while (length--) {
  14513. if (eq_1(array[length][0], key)) {
  14514. return length;
  14515. }
  14516. }
  14517. return -1;
  14518. }
  14519. var _assocIndexOf = assocIndexOf;
  14520. /** Used for built-in method references. */
  14521. var arrayProto = Array.prototype;
  14522. /** Built-in value references. */
  14523. var splice = arrayProto.splice;
  14524. /**
  14525. * Removes `key` and its value from the list cache.
  14526. *
  14527. * @private
  14528. * @name delete
  14529. * @memberOf ListCache
  14530. * @param {string} key The key of the value to remove.
  14531. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  14532. */
  14533. function listCacheDelete(key) {
  14534. var data = this.__data__,
  14535. index = _assocIndexOf(data, key);
  14536. if (index < 0) {
  14537. return false;
  14538. }
  14539. var lastIndex = data.length - 1;
  14540. if (index == lastIndex) {
  14541. data.pop();
  14542. } else {
  14543. splice.call(data, index, 1);
  14544. }
  14545. --this.size;
  14546. return true;
  14547. }
  14548. var _listCacheDelete = listCacheDelete;
  14549. /**
  14550. * Gets the list cache value for `key`.
  14551. *
  14552. * @private
  14553. * @name get
  14554. * @memberOf ListCache
  14555. * @param {string} key The key of the value to get.
  14556. * @returns {*} Returns the entry value.
  14557. */
  14558. function listCacheGet(key) {
  14559. var data = this.__data__,
  14560. index = _assocIndexOf(data, key);
  14561. return index < 0 ? undefined : data[index][1];
  14562. }
  14563. var _listCacheGet = listCacheGet;
  14564. /**
  14565. * Checks if a list cache value for `key` exists.
  14566. *
  14567. * @private
  14568. * @name has
  14569. * @memberOf ListCache
  14570. * @param {string} key The key of the entry to check.
  14571. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  14572. */
  14573. function listCacheHas(key) {
  14574. return _assocIndexOf(this.__data__, key) > -1;
  14575. }
  14576. var _listCacheHas = listCacheHas;
  14577. /**
  14578. * Sets the list cache `key` to `value`.
  14579. *
  14580. * @private
  14581. * @name set
  14582. * @memberOf ListCache
  14583. * @param {string} key The key of the value to set.
  14584. * @param {*} value The value to set.
  14585. * @returns {Object} Returns the list cache instance.
  14586. */
  14587. function listCacheSet(key, value) {
  14588. var data = this.__data__,
  14589. index = _assocIndexOf(data, key);
  14590. if (index < 0) {
  14591. ++this.size;
  14592. data.push([key, value]);
  14593. } else {
  14594. data[index][1] = value;
  14595. }
  14596. return this;
  14597. }
  14598. var _listCacheSet = listCacheSet;
  14599. /**
  14600. * Creates an list cache object.
  14601. *
  14602. * @private
  14603. * @constructor
  14604. * @param {Array} [entries] The key-value pairs to cache.
  14605. */
  14606. function ListCache(entries) {
  14607. var index = -1,
  14608. length = entries == null ? 0 : entries.length;
  14609. this.clear();
  14610. while (++index < length) {
  14611. var entry = entries[index];
  14612. this.set(entry[0], entry[1]);
  14613. }
  14614. }
  14615. // Add methods to `ListCache`.
  14616. ListCache.prototype.clear = _listCacheClear;
  14617. ListCache.prototype['delete'] = _listCacheDelete;
  14618. ListCache.prototype.get = _listCacheGet;
  14619. ListCache.prototype.has = _listCacheHas;
  14620. ListCache.prototype.set = _listCacheSet;
  14621. var _ListCache = ListCache;
  14622. /**
  14623. * Removes all key-value entries from the stack.
  14624. *
  14625. * @private
  14626. * @name clear
  14627. * @memberOf Stack
  14628. */
  14629. function stackClear() {
  14630. this.__data__ = new _ListCache;
  14631. this.size = 0;
  14632. }
  14633. var _stackClear = stackClear;
  14634. /**
  14635. * Removes `key` and its value from the stack.
  14636. *
  14637. * @private
  14638. * @name delete
  14639. * @memberOf Stack
  14640. * @param {string} key The key of the value to remove.
  14641. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  14642. */
  14643. function stackDelete(key) {
  14644. var data = this.__data__,
  14645. result = data['delete'](key);
  14646. this.size = data.size;
  14647. return result;
  14648. }
  14649. var _stackDelete = stackDelete;
  14650. /**
  14651. * Gets the stack value for `key`.
  14652. *
  14653. * @private
  14654. * @name get
  14655. * @memberOf Stack
  14656. * @param {string} key The key of the value to get.
  14657. * @returns {*} Returns the entry value.
  14658. */
  14659. function stackGet(key) {
  14660. return this.__data__.get(key);
  14661. }
  14662. var _stackGet = stackGet;
  14663. /**
  14664. * Checks if a stack value for `key` exists.
  14665. *
  14666. * @private
  14667. * @name has
  14668. * @memberOf Stack
  14669. * @param {string} key The key of the entry to check.
  14670. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  14671. */
  14672. function stackHas(key) {
  14673. return this.__data__.has(key);
  14674. }
  14675. var _stackHas = stackHas;
  14676. /** Used to detect overreaching core-js shims. */
  14677. var coreJsData = _root['__core-js_shared__'];
  14678. var _coreJsData = coreJsData;
  14679. /** Used to detect methods masquerading as native. */
  14680. var maskSrcKey = (function() {
  14681. var uid = /[^.]+$/.exec(_coreJsData && _coreJsData.keys && _coreJsData.keys.IE_PROTO || '');
  14682. return uid ? ('Symbol(src)_1.' + uid) : '';
  14683. }());
  14684. /**
  14685. * Checks if `func` has its source masked.
  14686. *
  14687. * @private
  14688. * @param {Function} func The function to check.
  14689. * @returns {boolean} Returns `true` if `func` is masked, else `false`.
  14690. */
  14691. function isMasked(func) {
  14692. return !!maskSrcKey && (maskSrcKey in func);
  14693. }
  14694. var _isMasked = isMasked;
  14695. /** Used for built-in method references. */
  14696. var funcProto$1 = Function.prototype;
  14697. /** Used to resolve the decompiled source of functions. */
  14698. var funcToString$1 = funcProto$1.toString;
  14699. /**
  14700. * Converts `func` to its source code.
  14701. *
  14702. * @private
  14703. * @param {Function} func The function to convert.
  14704. * @returns {string} Returns the source code.
  14705. */
  14706. function toSource(func) {
  14707. if (func != null) {
  14708. try {
  14709. return funcToString$1.call(func);
  14710. } catch (e) {}
  14711. try {
  14712. return (func + '');
  14713. } catch (e) {}
  14714. }
  14715. return '';
  14716. }
  14717. var _toSource = toSource;
  14718. /**
  14719. * Used to match `RegExp`
  14720. * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
  14721. */
  14722. var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
  14723. /** Used to detect host constructors (Safari). */
  14724. var reIsHostCtor = /^\[object .+?Constructor\]$/;
  14725. /** Used for built-in method references. */
  14726. var funcProto$2 = Function.prototype,
  14727. objectProto$7 = Object.prototype;
  14728. /** Used to resolve the decompiled source of functions. */
  14729. var funcToString$2 = funcProto$2.toString;
  14730. /** Used to check objects for own properties. */
  14731. var hasOwnProperty$5 = objectProto$7.hasOwnProperty;
  14732. /** Used to detect if a method is native. */
  14733. var reIsNative = RegExp('^' +
  14734. funcToString$2.call(hasOwnProperty$5).replace(reRegExpChar, '\\$&')
  14735. .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
  14736. );
  14737. /**
  14738. * The base implementation of `_.isNative` without bad shim checks.
  14739. *
  14740. * @private
  14741. * @param {*} value The value to check.
  14742. * @returns {boolean} Returns `true` if `value` is a native function,
  14743. * else `false`.
  14744. */
  14745. function baseIsNative(value) {
  14746. if (!isObject_1(value) || _isMasked(value)) {
  14747. return false;
  14748. }
  14749. var pattern = isFunction_1(value) ? reIsNative : reIsHostCtor;
  14750. return pattern.test(_toSource(value));
  14751. }
  14752. var _baseIsNative = baseIsNative;
  14753. /**
  14754. * Gets the value at `key` of `object`.
  14755. *
  14756. * @private
  14757. * @param {Object} [object] The object to query.
  14758. * @param {string} key The key of the property to get.
  14759. * @returns {*} Returns the property value.
  14760. */
  14761. function getValue(object, key) {
  14762. return object == null ? undefined : object[key];
  14763. }
  14764. var _getValue = getValue;
  14765. /**
  14766. * Gets the native function at `key` of `object`.
  14767. *
  14768. * @private
  14769. * @param {Object} object The object to query.
  14770. * @param {string} key The key of the method to get.
  14771. * @returns {*} Returns the function if it's native, else `undefined`.
  14772. */
  14773. function getNative(object, key) {
  14774. var value = _getValue(object, key);
  14775. return _baseIsNative(value) ? value : undefined;
  14776. }
  14777. var _getNative = getNative;
  14778. /* Built-in method references that are verified to be native. */
  14779. var Map$1 = _getNative(_root, 'Map');
  14780. var _Map = Map$1;
  14781. /* Built-in method references that are verified to be native. */
  14782. var nativeCreate = _getNative(Object, 'create');
  14783. var _nativeCreate = nativeCreate;
  14784. /**
  14785. * Removes all key-value entries from the hash.
  14786. *
  14787. * @private
  14788. * @name clear
  14789. * @memberOf Hash
  14790. */
  14791. function hashClear() {
  14792. this.__data__ = _nativeCreate ? _nativeCreate(null) : {};
  14793. this.size = 0;
  14794. }
  14795. var _hashClear = hashClear;
  14796. /**
  14797. * Removes `key` and its value from the hash.
  14798. *
  14799. * @private
  14800. * @name delete
  14801. * @memberOf Hash
  14802. * @param {Object} hash The hash to modify.
  14803. * @param {string} key The key of the value to remove.
  14804. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  14805. */
  14806. function hashDelete(key) {
  14807. var result = this.has(key) && delete this.__data__[key];
  14808. this.size -= result ? 1 : 0;
  14809. return result;
  14810. }
  14811. var _hashDelete = hashDelete;
  14812. /** Used to stand-in for `undefined` hash values. */
  14813. var HASH_UNDEFINED = '__lodash_hash_undefined__';
  14814. /** Used for built-in method references. */
  14815. var objectProto$8 = Object.prototype;
  14816. /** Used to check objects for own properties. */
  14817. var hasOwnProperty$6 = objectProto$8.hasOwnProperty;
  14818. /**
  14819. * Gets the hash value for `key`.
  14820. *
  14821. * @private
  14822. * @name get
  14823. * @memberOf Hash
  14824. * @param {string} key The key of the value to get.
  14825. * @returns {*} Returns the entry value.
  14826. */
  14827. function hashGet(key) {
  14828. var data = this.__data__;
  14829. if (_nativeCreate) {
  14830. var result = data[key];
  14831. return result === HASH_UNDEFINED ? undefined : result;
  14832. }
  14833. return hasOwnProperty$6.call(data, key) ? data[key] : undefined;
  14834. }
  14835. var _hashGet = hashGet;
  14836. /** Used for built-in method references. */
  14837. var objectProto$9 = Object.prototype;
  14838. /** Used to check objects for own properties. */
  14839. var hasOwnProperty$7 = objectProto$9.hasOwnProperty;
  14840. /**
  14841. * Checks if a hash value for `key` exists.
  14842. *
  14843. * @private
  14844. * @name has
  14845. * @memberOf Hash
  14846. * @param {string} key The key of the entry to check.
  14847. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  14848. */
  14849. function hashHas(key) {
  14850. var data = this.__data__;
  14851. return _nativeCreate ? (data[key] !== undefined) : hasOwnProperty$7.call(data, key);
  14852. }
  14853. var _hashHas = hashHas;
  14854. /** Used to stand-in for `undefined` hash values. */
  14855. var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';
  14856. /**
  14857. * Sets the hash `key` to `value`.
  14858. *
  14859. * @private
  14860. * @name set
  14861. * @memberOf Hash
  14862. * @param {string} key The key of the value to set.
  14863. * @param {*} value The value to set.
  14864. * @returns {Object} Returns the hash instance.
  14865. */
  14866. function hashSet(key, value) {
  14867. var data = this.__data__;
  14868. this.size += this.has(key) ? 0 : 1;
  14869. data[key] = (_nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value;
  14870. return this;
  14871. }
  14872. var _hashSet = hashSet;
  14873. /**
  14874. * Creates a hash object.
  14875. *
  14876. * @private
  14877. * @constructor
  14878. * @param {Array} [entries] The key-value pairs to cache.
  14879. */
  14880. function Hash(entries) {
  14881. var index = -1,
  14882. length = entries == null ? 0 : entries.length;
  14883. this.clear();
  14884. while (++index < length) {
  14885. var entry = entries[index];
  14886. this.set(entry[0], entry[1]);
  14887. }
  14888. }
  14889. // Add methods to `Hash`.
  14890. Hash.prototype.clear = _hashClear;
  14891. Hash.prototype['delete'] = _hashDelete;
  14892. Hash.prototype.get = _hashGet;
  14893. Hash.prototype.has = _hashHas;
  14894. Hash.prototype.set = _hashSet;
  14895. var _Hash = Hash;
  14896. /**
  14897. * Removes all key-value entries from the map.
  14898. *
  14899. * @private
  14900. * @name clear
  14901. * @memberOf MapCache
  14902. */
  14903. function mapCacheClear() {
  14904. this.size = 0;
  14905. this.__data__ = {
  14906. 'hash': new _Hash,
  14907. 'map': new (_Map || _ListCache),
  14908. 'string': new _Hash
  14909. };
  14910. }
  14911. var _mapCacheClear = mapCacheClear;
  14912. /**
  14913. * Checks if `value` is suitable for use as unique object key.
  14914. *
  14915. * @private
  14916. * @param {*} value The value to check.
  14917. * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
  14918. */
  14919. function isKeyable(value) {
  14920. var type = typeof value;
  14921. return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
  14922. ? (value !== '__proto__')
  14923. : (value === null);
  14924. }
  14925. var _isKeyable = isKeyable;
  14926. /**
  14927. * Gets the data for `map`.
  14928. *
  14929. * @private
  14930. * @param {Object} map The map to query.
  14931. * @param {string} key The reference key.
  14932. * @returns {*} Returns the map data.
  14933. */
  14934. function getMapData(map, key) {
  14935. var data = map.__data__;
  14936. return _isKeyable(key)
  14937. ? data[typeof key == 'string' ? 'string' : 'hash']
  14938. : data.map;
  14939. }
  14940. var _getMapData = getMapData;
  14941. /**
  14942. * Removes `key` and its value from the map.
  14943. *
  14944. * @private
  14945. * @name delete
  14946. * @memberOf MapCache
  14947. * @param {string} key The key of the value to remove.
  14948. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  14949. */
  14950. function mapCacheDelete(key) {
  14951. var result = _getMapData(this, key)['delete'](key);
  14952. this.size -= result ? 1 : 0;
  14953. return result;
  14954. }
  14955. var _mapCacheDelete = mapCacheDelete;
  14956. /**
  14957. * Gets the map value for `key`.
  14958. *
  14959. * @private
  14960. * @name get
  14961. * @memberOf MapCache
  14962. * @param {string} key The key of the value to get.
  14963. * @returns {*} Returns the entry value.
  14964. */
  14965. function mapCacheGet(key) {
  14966. return _getMapData(this, key).get(key);
  14967. }
  14968. var _mapCacheGet = mapCacheGet;
  14969. /**
  14970. * Checks if a map value for `key` exists.
  14971. *
  14972. * @private
  14973. * @name has
  14974. * @memberOf MapCache
  14975. * @param {string} key The key of the entry to check.
  14976. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  14977. */
  14978. function mapCacheHas(key) {
  14979. return _getMapData(this, key).has(key);
  14980. }
  14981. var _mapCacheHas = mapCacheHas;
  14982. /**
  14983. * Sets the map `key` to `value`.
  14984. *
  14985. * @private
  14986. * @name set
  14987. * @memberOf MapCache
  14988. * @param {string} key The key of the value to set.
  14989. * @param {*} value The value to set.
  14990. * @returns {Object} Returns the map cache instance.
  14991. */
  14992. function mapCacheSet(key, value) {
  14993. var data = _getMapData(this, key),
  14994. size = data.size;
  14995. data.set(key, value);
  14996. this.size += data.size == size ? 0 : 1;
  14997. return this;
  14998. }
  14999. var _mapCacheSet = mapCacheSet;
  15000. /**
  15001. * Creates a map cache object to store key-value pairs.
  15002. *
  15003. * @private
  15004. * @constructor
  15005. * @param {Array} [entries] The key-value pairs to cache.
  15006. */
  15007. function MapCache(entries) {
  15008. var index = -1,
  15009. length = entries == null ? 0 : entries.length;
  15010. this.clear();
  15011. while (++index < length) {
  15012. var entry = entries[index];
  15013. this.set(entry[0], entry[1]);
  15014. }
  15015. }
  15016. // Add methods to `MapCache`.
  15017. MapCache.prototype.clear = _mapCacheClear;
  15018. MapCache.prototype['delete'] = _mapCacheDelete;
  15019. MapCache.prototype.get = _mapCacheGet;
  15020. MapCache.prototype.has = _mapCacheHas;
  15021. MapCache.prototype.set = _mapCacheSet;
  15022. var _MapCache = MapCache;
  15023. /** Used as the size to enable large array optimizations. */
  15024. var LARGE_ARRAY_SIZE = 200;
  15025. /**
  15026. * Sets the stack `key` to `value`.
  15027. *
  15028. * @private
  15029. * @name set
  15030. * @memberOf Stack
  15031. * @param {string} key The key of the value to set.
  15032. * @param {*} value The value to set.
  15033. * @returns {Object} Returns the stack cache instance.
  15034. */
  15035. function stackSet(key, value) {
  15036. var data = this.__data__;
  15037. if (data instanceof _ListCache) {
  15038. var pairs = data.__data__;
  15039. if (!_Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
  15040. pairs.push([key, value]);
  15041. this.size = ++data.size;
  15042. return this;
  15043. }
  15044. data = this.__data__ = new _MapCache(pairs);
  15045. }
  15046. data.set(key, value);
  15047. this.size = data.size;
  15048. return this;
  15049. }
  15050. var _stackSet = stackSet;
  15051. /**
  15052. * Creates a stack cache object to store key-value pairs.
  15053. *
  15054. * @private
  15055. * @constructor
  15056. * @param {Array} [entries] The key-value pairs to cache.
  15057. */
  15058. function Stack(entries) {
  15059. var data = this.__data__ = new _ListCache(entries);
  15060. this.size = data.size;
  15061. }
  15062. // Add methods to `Stack`.
  15063. Stack.prototype.clear = _stackClear;
  15064. Stack.prototype['delete'] = _stackDelete;
  15065. Stack.prototype.get = _stackGet;
  15066. Stack.prototype.has = _stackHas;
  15067. Stack.prototype.set = _stackSet;
  15068. var _Stack = Stack;
  15069. /** Used to stand-in for `undefined` hash values. */
  15070. var HASH_UNDEFINED$2 = '__lodash_hash_undefined__';
  15071. /**
  15072. * Adds `value` to the array cache.
  15073. *
  15074. * @private
  15075. * @name add
  15076. * @memberOf SetCache
  15077. * @alias push
  15078. * @param {*} value The value to cache.
  15079. * @returns {Object} Returns the cache instance.
  15080. */
  15081. function setCacheAdd(value) {
  15082. this.__data__.set(value, HASH_UNDEFINED$2);
  15083. return this;
  15084. }
  15085. var _setCacheAdd = setCacheAdd;
  15086. /**
  15087. * Checks if `value` is in the array cache.
  15088. *
  15089. * @private
  15090. * @name has
  15091. * @memberOf SetCache
  15092. * @param {*} value The value to search for.
  15093. * @returns {number} Returns `true` if `value` is found, else `false`.
  15094. */
  15095. function setCacheHas(value) {
  15096. return this.__data__.has(value);
  15097. }
  15098. var _setCacheHas = setCacheHas;
  15099. /**
  15100. *
  15101. * Creates an array cache object to store unique values.
  15102. *
  15103. * @private
  15104. * @constructor
  15105. * @param {Array} [values] The values to cache.
  15106. */
  15107. function SetCache(values) {
  15108. var index = -1,
  15109. length = values == null ? 0 : values.length;
  15110. this.__data__ = new _MapCache;
  15111. while (++index < length) {
  15112. this.add(values[index]);
  15113. }
  15114. }
  15115. // Add methods to `SetCache`.
  15116. SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd;
  15117. SetCache.prototype.has = _setCacheHas;
  15118. var _SetCache = SetCache;
  15119. /**
  15120. * A specialized version of `_.some` for arrays without support for iteratee
  15121. * shorthands.
  15122. *
  15123. * @private
  15124. * @param {Array} [array] The array to iterate over.
  15125. * @param {Function} predicate The function invoked per iteration.
  15126. * @returns {boolean} Returns `true` if any element passes the predicate check,
  15127. * else `false`.
  15128. */
  15129. function arraySome(array, predicate) {
  15130. var index = -1,
  15131. length = array == null ? 0 : array.length;
  15132. while (++index < length) {
  15133. if (predicate(array[index], index, array)) {
  15134. return true;
  15135. }
  15136. }
  15137. return false;
  15138. }
  15139. var _arraySome = arraySome;
  15140. /**
  15141. * Checks if a `cache` value for `key` exists.
  15142. *
  15143. * @private
  15144. * @param {Object} cache The cache to query.
  15145. * @param {string} key The key of the entry to check.
  15146. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  15147. */
  15148. function cacheHas(cache, key) {
  15149. return cache.has(key);
  15150. }
  15151. var _cacheHas = cacheHas;
  15152. /** Used to compose bitmasks for value comparisons. */
  15153. var COMPARE_PARTIAL_FLAG = 1,
  15154. COMPARE_UNORDERED_FLAG = 2;
  15155. /**
  15156. * A specialized version of `baseIsEqualDeep` for arrays with support for
  15157. * partial deep comparisons.
  15158. *
  15159. * @private
  15160. * @param {Array} array The array to compare.
  15161. * @param {Array} other The other array to compare.
  15162. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  15163. * @param {Function} customizer The function to customize comparisons.
  15164. * @param {Function} equalFunc The function to determine equivalents of values.
  15165. * @param {Object} stack Tracks traversed `array` and `other` objects.
  15166. * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
  15167. */
  15168. function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
  15169. var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
  15170. arrLength = array.length,
  15171. othLength = other.length;
  15172. if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
  15173. return false;
  15174. }
  15175. // Check that cyclic values are equal.
  15176. var arrStacked = stack.get(array);
  15177. var othStacked = stack.get(other);
  15178. if (arrStacked && othStacked) {
  15179. return arrStacked == other && othStacked == array;
  15180. }
  15181. var index = -1,
  15182. result = true,
  15183. seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache : undefined;
  15184. stack.set(array, other);
  15185. stack.set(other, array);
  15186. // Ignore non-index properties.
  15187. while (++index < arrLength) {
  15188. var arrValue = array[index],
  15189. othValue = other[index];
  15190. if (customizer) {
  15191. var compared = isPartial
  15192. ? customizer(othValue, arrValue, index, other, array, stack)
  15193. : customizer(arrValue, othValue, index, array, other, stack);
  15194. }
  15195. if (compared !== undefined) {
  15196. if (compared) {
  15197. continue;
  15198. }
  15199. result = false;
  15200. break;
  15201. }
  15202. // Recursively compare arrays (susceptible to call stack limits).
  15203. if (seen) {
  15204. if (!_arraySome(other, function(othValue, othIndex) {
  15205. if (!_cacheHas(seen, othIndex) &&
  15206. (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
  15207. return seen.push(othIndex);
  15208. }
  15209. })) {
  15210. result = false;
  15211. break;
  15212. }
  15213. } else if (!(
  15214. arrValue === othValue ||
  15215. equalFunc(arrValue, othValue, bitmask, customizer, stack)
  15216. )) {
  15217. result = false;
  15218. break;
  15219. }
  15220. }
  15221. stack['delete'](array);
  15222. stack['delete'](other);
  15223. return result;
  15224. }
  15225. var _equalArrays = equalArrays;
  15226. /** Built-in value references. */
  15227. var Uint8Array$1 = _root.Uint8Array;
  15228. var _Uint8Array = Uint8Array$1;
  15229. /**
  15230. * Converts `map` to its key-value pairs.
  15231. *
  15232. * @private
  15233. * @param {Object} map The map to convert.
  15234. * @returns {Array} Returns the key-value pairs.
  15235. */
  15236. function mapToArray(map) {
  15237. var index = -1,
  15238. result = Array(map.size);
  15239. map.forEach(function(value, key) {
  15240. result[++index] = [key, value];
  15241. });
  15242. return result;
  15243. }
  15244. var _mapToArray = mapToArray;
  15245. /**
  15246. * Converts `set` to an array of its values.
  15247. *
  15248. * @private
  15249. * @param {Object} set The set to convert.
  15250. * @returns {Array} Returns the values.
  15251. */
  15252. function setToArray(set) {
  15253. var index = -1,
  15254. result = Array(set.size);
  15255. set.forEach(function(value) {
  15256. result[++index] = value;
  15257. });
  15258. return result;
  15259. }
  15260. var _setToArray = setToArray;
  15261. /** Used to compose bitmasks for value comparisons. */
  15262. var COMPARE_PARTIAL_FLAG$1 = 1,
  15263. COMPARE_UNORDERED_FLAG$1 = 2;
  15264. /** `Object#toString` result references. */
  15265. var boolTag$1 = '[object Boolean]',
  15266. dateTag$1 = '[object Date]',
  15267. errorTag$1 = '[object Error]',
  15268. mapTag$1 = '[object Map]',
  15269. numberTag$1 = '[object Number]',
  15270. regexpTag$1 = '[object RegExp]',
  15271. setTag$1 = '[object Set]',
  15272. stringTag$1 = '[object String]',
  15273. symbolTag = '[object Symbol]';
  15274. var arrayBufferTag$1 = '[object ArrayBuffer]',
  15275. dataViewTag$1 = '[object DataView]';
  15276. /** Used to convert symbols to primitives and strings. */
  15277. var symbolProto = _Symbol ? _Symbol.prototype : undefined,
  15278. symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
  15279. /**
  15280. * A specialized version of `baseIsEqualDeep` for comparing objects of
  15281. * the same `toStringTag`.
  15282. *
  15283. * **Note:** This function only supports comparing values with tags of
  15284. * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
  15285. *
  15286. * @private
  15287. * @param {Object} object The object to compare.
  15288. * @param {Object} other The other object to compare.
  15289. * @param {string} tag The `toStringTag` of the objects to compare.
  15290. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  15291. * @param {Function} customizer The function to customize comparisons.
  15292. * @param {Function} equalFunc The function to determine equivalents of values.
  15293. * @param {Object} stack Tracks traversed `object` and `other` objects.
  15294. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  15295. */
  15296. function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
  15297. switch (tag) {
  15298. case dataViewTag$1:
  15299. if ((object.byteLength != other.byteLength) ||
  15300. (object.byteOffset != other.byteOffset)) {
  15301. return false;
  15302. }
  15303. object = object.buffer;
  15304. other = other.buffer;
  15305. case arrayBufferTag$1:
  15306. if ((object.byteLength != other.byteLength) ||
  15307. !equalFunc(new _Uint8Array(object), new _Uint8Array(other))) {
  15308. return false;
  15309. }
  15310. return true;
  15311. case boolTag$1:
  15312. case dateTag$1:
  15313. case numberTag$1:
  15314. // Coerce booleans to `1` or `0` and dates to milliseconds.
  15315. // Invalid dates are coerced to `NaN`.
  15316. return eq_1(+object, +other);
  15317. case errorTag$1:
  15318. return object.name == other.name && object.message == other.message;
  15319. case regexpTag$1:
  15320. case stringTag$1:
  15321. // Coerce regexes to strings and treat strings, primitives and objects,
  15322. // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
  15323. // for more details.
  15324. return object == (other + '');
  15325. case mapTag$1:
  15326. var convert = _mapToArray;
  15327. case setTag$1:
  15328. var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1;
  15329. convert || (convert = _setToArray);
  15330. if (object.size != other.size && !isPartial) {
  15331. return false;
  15332. }
  15333. // Assume cyclic values are equal.
  15334. var stacked = stack.get(object);
  15335. if (stacked) {
  15336. return stacked == other;
  15337. }
  15338. bitmask |= COMPARE_UNORDERED_FLAG$1;
  15339. // Recursively compare objects (susceptible to call stack limits).
  15340. stack.set(object, other);
  15341. var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
  15342. stack['delete'](object);
  15343. return result;
  15344. case symbolTag:
  15345. if (symbolValueOf) {
  15346. return symbolValueOf.call(object) == symbolValueOf.call(other);
  15347. }
  15348. }
  15349. return false;
  15350. }
  15351. var _equalByTag = equalByTag;
  15352. /**
  15353. * Appends the elements of `values` to `array`.
  15354. *
  15355. * @private
  15356. * @param {Array} array The array to modify.
  15357. * @param {Array} values The values to append.
  15358. * @returns {Array} Returns `array`.
  15359. */
  15360. function arrayPush(array, values) {
  15361. var index = -1,
  15362. length = values.length,
  15363. offset = array.length;
  15364. while (++index < length) {
  15365. array[offset + index] = values[index];
  15366. }
  15367. return array;
  15368. }
  15369. var _arrayPush = arrayPush;
  15370. /**
  15371. * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
  15372. * `keysFunc` and `symbolsFunc` to get the enumerable property names and
  15373. * symbols of `object`.
  15374. *
  15375. * @private
  15376. * @param {Object} object The object to query.
  15377. * @param {Function} keysFunc The function to get the keys of `object`.
  15378. * @param {Function} symbolsFunc The function to get the symbols of `object`.
  15379. * @returns {Array} Returns the array of property names and symbols.
  15380. */
  15381. function baseGetAllKeys(object, keysFunc, symbolsFunc) {
  15382. var result = keysFunc(object);
  15383. return isArray_1(object) ? result : _arrayPush(result, symbolsFunc(object));
  15384. }
  15385. var _baseGetAllKeys = baseGetAllKeys;
  15386. /**
  15387. * A specialized version of `_.filter` for arrays without support for
  15388. * iteratee shorthands.
  15389. *
  15390. * @private
  15391. * @param {Array} [array] The array to iterate over.
  15392. * @param {Function} predicate The function invoked per iteration.
  15393. * @returns {Array} Returns the new filtered array.
  15394. */
  15395. function arrayFilter(array, predicate) {
  15396. var index = -1,
  15397. length = array == null ? 0 : array.length,
  15398. resIndex = 0,
  15399. result = [];
  15400. while (++index < length) {
  15401. var value = array[index];
  15402. if (predicate(value, index, array)) {
  15403. result[resIndex++] = value;
  15404. }
  15405. }
  15406. return result;
  15407. }
  15408. var _arrayFilter = arrayFilter;
  15409. /**
  15410. * This method returns a new empty array.
  15411. *
  15412. * @static
  15413. * @memberOf _
  15414. * @since 4.13.0
  15415. * @category Util
  15416. * @returns {Array} Returns the new empty array.
  15417. * @example
  15418. *
  15419. * var arrays = _.times(2, _.stubArray);
  15420. *
  15421. * console.log(arrays);
  15422. * // => [[], []]
  15423. *
  15424. * console.log(arrays[0] === arrays[1]);
  15425. * // => false
  15426. */
  15427. function stubArray() {
  15428. return [];
  15429. }
  15430. var stubArray_1 = stubArray;
  15431. /** Used for built-in method references. */
  15432. var objectProto$a = Object.prototype;
  15433. /** Built-in value references. */
  15434. var propertyIsEnumerable$1 = objectProto$a.propertyIsEnumerable;
  15435. /* Built-in method references for those with the same name as other `lodash` methods. */
  15436. var nativeGetSymbols = Object.getOwnPropertySymbols;
  15437. /**
  15438. * Creates an array of the own enumerable symbols of `object`.
  15439. *
  15440. * @private
  15441. * @param {Object} object The object to query.
  15442. * @returns {Array} Returns the array of symbols.
  15443. */
  15444. var getSymbols = !nativeGetSymbols ? stubArray_1 : function(object) {
  15445. if (object == null) {
  15446. return [];
  15447. }
  15448. object = Object(object);
  15449. return _arrayFilter(nativeGetSymbols(object), function(symbol) {
  15450. return propertyIsEnumerable$1.call(object, symbol);
  15451. });
  15452. };
  15453. var _getSymbols = getSymbols;
  15454. /**
  15455. * Creates an array of own enumerable property names and symbols of `object`.
  15456. *
  15457. * @private
  15458. * @param {Object} object The object to query.
  15459. * @returns {Array} Returns the array of property names and symbols.
  15460. */
  15461. function getAllKeys(object) {
  15462. return _baseGetAllKeys(object, keys_1, _getSymbols);
  15463. }
  15464. var _getAllKeys = getAllKeys;
  15465. /** Used to compose bitmasks for value comparisons. */
  15466. var COMPARE_PARTIAL_FLAG$2 = 1;
  15467. /** Used for built-in method references. */
  15468. var objectProto$b = Object.prototype;
  15469. /** Used to check objects for own properties. */
  15470. var hasOwnProperty$8 = objectProto$b.hasOwnProperty;
  15471. /**
  15472. * A specialized version of `baseIsEqualDeep` for objects with support for
  15473. * partial deep comparisons.
  15474. *
  15475. * @private
  15476. * @param {Object} object The object to compare.
  15477. * @param {Object} other The other object to compare.
  15478. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  15479. * @param {Function} customizer The function to customize comparisons.
  15480. * @param {Function} equalFunc The function to determine equivalents of values.
  15481. * @param {Object} stack Tracks traversed `object` and `other` objects.
  15482. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  15483. */
  15484. function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
  15485. var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2,
  15486. objProps = _getAllKeys(object),
  15487. objLength = objProps.length,
  15488. othProps = _getAllKeys(other),
  15489. othLength = othProps.length;
  15490. if (objLength != othLength && !isPartial) {
  15491. return false;
  15492. }
  15493. var index = objLength;
  15494. while (index--) {
  15495. var key = objProps[index];
  15496. if (!(isPartial ? key in other : hasOwnProperty$8.call(other, key))) {
  15497. return false;
  15498. }
  15499. }
  15500. // Check that cyclic values are equal.
  15501. var objStacked = stack.get(object);
  15502. var othStacked = stack.get(other);
  15503. if (objStacked && othStacked) {
  15504. return objStacked == other && othStacked == object;
  15505. }
  15506. var result = true;
  15507. stack.set(object, other);
  15508. stack.set(other, object);
  15509. var skipCtor = isPartial;
  15510. while (++index < objLength) {
  15511. key = objProps[index];
  15512. var objValue = object[key],
  15513. othValue = other[key];
  15514. if (customizer) {
  15515. var compared = isPartial
  15516. ? customizer(othValue, objValue, key, other, object, stack)
  15517. : customizer(objValue, othValue, key, object, other, stack);
  15518. }
  15519. // Recursively compare objects (susceptible to call stack limits).
  15520. if (!(compared === undefined
  15521. ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
  15522. : compared
  15523. )) {
  15524. result = false;
  15525. break;
  15526. }
  15527. skipCtor || (skipCtor = key == 'constructor');
  15528. }
  15529. if (result && !skipCtor) {
  15530. var objCtor = object.constructor,
  15531. othCtor = other.constructor;
  15532. // Non `Object` object instances with different constructors are not equal.
  15533. if (objCtor != othCtor &&
  15534. ('constructor' in object && 'constructor' in other) &&
  15535. !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
  15536. typeof othCtor == 'function' && othCtor instanceof othCtor)) {
  15537. result = false;
  15538. }
  15539. }
  15540. stack['delete'](object);
  15541. stack['delete'](other);
  15542. return result;
  15543. }
  15544. var _equalObjects = equalObjects;
  15545. /* Built-in method references that are verified to be native. */
  15546. var DataView = _getNative(_root, 'DataView');
  15547. var _DataView = DataView;
  15548. /* Built-in method references that are verified to be native. */
  15549. var Promise$1 = _getNative(_root, 'Promise');
  15550. var _Promise = Promise$1;
  15551. /* Built-in method references that are verified to be native. */
  15552. var Set$1 = _getNative(_root, 'Set');
  15553. var _Set = Set$1;
  15554. /* Built-in method references that are verified to be native. */
  15555. var WeakMap$1 = _getNative(_root, 'WeakMap');
  15556. var _WeakMap = WeakMap$1;
  15557. /** `Object#toString` result references. */
  15558. var mapTag$2 = '[object Map]',
  15559. objectTag$2 = '[object Object]',
  15560. promiseTag = '[object Promise]',
  15561. setTag$2 = '[object Set]',
  15562. weakMapTag$1 = '[object WeakMap]';
  15563. var dataViewTag$2 = '[object DataView]';
  15564. /** Used to detect maps, sets, and weakmaps. */
  15565. var dataViewCtorString = _toSource(_DataView),
  15566. mapCtorString = _toSource(_Map),
  15567. promiseCtorString = _toSource(_Promise),
  15568. setCtorString = _toSource(_Set),
  15569. weakMapCtorString = _toSource(_WeakMap);
  15570. /**
  15571. * Gets the `toStringTag` of `value`.
  15572. *
  15573. * @private
  15574. * @param {*} value The value to query.
  15575. * @returns {string} Returns the `toStringTag`.
  15576. */
  15577. var getTag = _baseGetTag;
  15578. // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
  15579. if ((_DataView && getTag(new _DataView(new ArrayBuffer(1))) != dataViewTag$2) ||
  15580. (_Map && getTag(new _Map) != mapTag$2) ||
  15581. (_Promise && getTag(_Promise.resolve()) != promiseTag) ||
  15582. (_Set && getTag(new _Set) != setTag$2) ||
  15583. (_WeakMap && getTag(new _WeakMap) != weakMapTag$1)) {
  15584. getTag = function(value) {
  15585. var result = _baseGetTag(value),
  15586. Ctor = result == objectTag$2 ? value.constructor : undefined,
  15587. ctorString = Ctor ? _toSource(Ctor) : '';
  15588. if (ctorString) {
  15589. switch (ctorString) {
  15590. case dataViewCtorString: return dataViewTag$2;
  15591. case mapCtorString: return mapTag$2;
  15592. case promiseCtorString: return promiseTag;
  15593. case setCtorString: return setTag$2;
  15594. case weakMapCtorString: return weakMapTag$1;
  15595. }
  15596. }
  15597. return result;
  15598. };
  15599. }
  15600. var _getTag = getTag;
  15601. /** Used to compose bitmasks for value comparisons. */
  15602. var COMPARE_PARTIAL_FLAG$3 = 1;
  15603. /** `Object#toString` result references. */
  15604. var argsTag$2 = '[object Arguments]',
  15605. arrayTag$1 = '[object Array]',
  15606. objectTag$3 = '[object Object]';
  15607. /** Used for built-in method references. */
  15608. var objectProto$c = Object.prototype;
  15609. /** Used to check objects for own properties. */
  15610. var hasOwnProperty$9 = objectProto$c.hasOwnProperty;
  15611. /**
  15612. * A specialized version of `baseIsEqual` for arrays and objects which performs
  15613. * deep comparisons and tracks traversed objects enabling objects with circular
  15614. * references to be compared.
  15615. *
  15616. * @private
  15617. * @param {Object} object The object to compare.
  15618. * @param {Object} other The other object to compare.
  15619. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  15620. * @param {Function} customizer The function to customize comparisons.
  15621. * @param {Function} equalFunc The function to determine equivalents of values.
  15622. * @param {Object} [stack] Tracks traversed `object` and `other` objects.
  15623. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  15624. */
  15625. function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
  15626. var objIsArr = isArray_1(object),
  15627. othIsArr = isArray_1(other),
  15628. objTag = objIsArr ? arrayTag$1 : _getTag(object),
  15629. othTag = othIsArr ? arrayTag$1 : _getTag(other);
  15630. objTag = objTag == argsTag$2 ? objectTag$3 : objTag;
  15631. othTag = othTag == argsTag$2 ? objectTag$3 : othTag;
  15632. var objIsObj = objTag == objectTag$3,
  15633. othIsObj = othTag == objectTag$3,
  15634. isSameTag = objTag == othTag;
  15635. if (isSameTag && isBuffer_1(object)) {
  15636. if (!isBuffer_1(other)) {
  15637. return false;
  15638. }
  15639. objIsArr = true;
  15640. objIsObj = false;
  15641. }
  15642. if (isSameTag && !objIsObj) {
  15643. stack || (stack = new _Stack);
  15644. return (objIsArr || isTypedArray_1(object))
  15645. ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack)
  15646. : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
  15647. }
  15648. if (!(bitmask & COMPARE_PARTIAL_FLAG$3)) {
  15649. var objIsWrapped = objIsObj && hasOwnProperty$9.call(object, '__wrapped__'),
  15650. othIsWrapped = othIsObj && hasOwnProperty$9.call(other, '__wrapped__');
  15651. if (objIsWrapped || othIsWrapped) {
  15652. var objUnwrapped = objIsWrapped ? object.value() : object,
  15653. othUnwrapped = othIsWrapped ? other.value() : other;
  15654. stack || (stack = new _Stack);
  15655. return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
  15656. }
  15657. }
  15658. if (!isSameTag) {
  15659. return false;
  15660. }
  15661. stack || (stack = new _Stack);
  15662. return _equalObjects(object, other, bitmask, customizer, equalFunc, stack);
  15663. }
  15664. var _baseIsEqualDeep = baseIsEqualDeep;
  15665. /**
  15666. * The base implementation of `_.isEqual` which supports partial comparisons
  15667. * and tracks traversed objects.
  15668. *
  15669. * @private
  15670. * @param {*} value The value to compare.
  15671. * @param {*} other The other value to compare.
  15672. * @param {boolean} bitmask The bitmask flags.
  15673. * 1 - Unordered comparison
  15674. * 2 - Partial comparison
  15675. * @param {Function} [customizer] The function to customize comparisons.
  15676. * @param {Object} [stack] Tracks traversed `value` and `other` objects.
  15677. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  15678. */
  15679. function baseIsEqual(value, other, bitmask, customizer, stack) {
  15680. if (value === other) {
  15681. return true;
  15682. }
  15683. if (value == null || other == null || (!isObjectLike_1(value) && !isObjectLike_1(other))) {
  15684. return value !== value && other !== other;
  15685. }
  15686. return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
  15687. }
  15688. var _baseIsEqual = baseIsEqual;
  15689. /** Used to compose bitmasks for value comparisons. */
  15690. var COMPARE_PARTIAL_FLAG$4 = 1,
  15691. COMPARE_UNORDERED_FLAG$2 = 2;
  15692. /**
  15693. * The base implementation of `_.isMatch` without support for iteratee shorthands.
  15694. *
  15695. * @private
  15696. * @param {Object} object The object to inspect.
  15697. * @param {Object} source The object of property values to match.
  15698. * @param {Array} matchData The property names, values, and compare flags to match.
  15699. * @param {Function} [customizer] The function to customize comparisons.
  15700. * @returns {boolean} Returns `true` if `object` is a match, else `false`.
  15701. */
  15702. function baseIsMatch(object, source, matchData, customizer) {
  15703. var index = matchData.length,
  15704. length = index,
  15705. noCustomizer = !customizer;
  15706. if (object == null) {
  15707. return !length;
  15708. }
  15709. object = Object(object);
  15710. while (index--) {
  15711. var data = matchData[index];
  15712. if ((noCustomizer && data[2])
  15713. ? data[1] !== object[data[0]]
  15714. : !(data[0] in object)
  15715. ) {
  15716. return false;
  15717. }
  15718. }
  15719. while (++index < length) {
  15720. data = matchData[index];
  15721. var key = data[0],
  15722. objValue = object[key],
  15723. srcValue = data[1];
  15724. if (noCustomizer && data[2]) {
  15725. if (objValue === undefined && !(key in object)) {
  15726. return false;
  15727. }
  15728. } else {
  15729. var stack = new _Stack;
  15730. if (customizer) {
  15731. var result = customizer(objValue, srcValue, key, object, source, stack);
  15732. }
  15733. if (!(result === undefined
  15734. ? _baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$4 | COMPARE_UNORDERED_FLAG$2, customizer, stack)
  15735. : result
  15736. )) {
  15737. return false;
  15738. }
  15739. }
  15740. }
  15741. return true;
  15742. }
  15743. var _baseIsMatch = baseIsMatch;
  15744. /**
  15745. * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
  15746. *
  15747. * @private
  15748. * @param {*} value The value to check.
  15749. * @returns {boolean} Returns `true` if `value` if suitable for strict
  15750. * equality comparisons, else `false`.
  15751. */
  15752. function isStrictComparable(value) {
  15753. return value === value && !isObject_1(value);
  15754. }
  15755. var _isStrictComparable = isStrictComparable;
  15756. /**
  15757. * Gets the property names, values, and compare flags of `object`.
  15758. *
  15759. * @private
  15760. * @param {Object} object The object to query.
  15761. * @returns {Array} Returns the match data of `object`.
  15762. */
  15763. function getMatchData(object) {
  15764. var result = keys_1(object),
  15765. length = result.length;
  15766. while (length--) {
  15767. var key = result[length],
  15768. value = object[key];
  15769. result[length] = [key, value, _isStrictComparable(value)];
  15770. }
  15771. return result;
  15772. }
  15773. var _getMatchData = getMatchData;
  15774. /**
  15775. * A specialized version of `matchesProperty` for source values suitable
  15776. * for strict equality comparisons, i.e. `===`.
  15777. *
  15778. * @private
  15779. * @param {string} key The key of the property to get.
  15780. * @param {*} srcValue The value to match.
  15781. * @returns {Function} Returns the new spec function.
  15782. */
  15783. function matchesStrictComparable(key, srcValue) {
  15784. return function(object) {
  15785. if (object == null) {
  15786. return false;
  15787. }
  15788. return object[key] === srcValue &&
  15789. (srcValue !== undefined || (key in Object(object)));
  15790. };
  15791. }
  15792. var _matchesStrictComparable = matchesStrictComparable;
  15793. /**
  15794. * The base implementation of `_.matches` which doesn't clone `source`.
  15795. *
  15796. * @private
  15797. * @param {Object} source The object of property values to match.
  15798. * @returns {Function} Returns the new spec function.
  15799. */
  15800. function baseMatches(source) {
  15801. var matchData = _getMatchData(source);
  15802. if (matchData.length == 1 && matchData[0][2]) {
  15803. return _matchesStrictComparable(matchData[0][0], matchData[0][1]);
  15804. }
  15805. return function(object) {
  15806. return object === source || _baseIsMatch(object, source, matchData);
  15807. };
  15808. }
  15809. var _baseMatches = baseMatches;
  15810. /** `Object#toString` result references. */
  15811. var symbolTag$1 = '[object Symbol]';
  15812. /**
  15813. * Checks if `value` is classified as a `Symbol` primitive or object.
  15814. *
  15815. * @static
  15816. * @memberOf _
  15817. * @since 4.0.0
  15818. * @category Lang
  15819. * @param {*} value The value to check.
  15820. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
  15821. * @example
  15822. *
  15823. * _.isSymbol(Symbol.iterator);
  15824. * // => true
  15825. *
  15826. * _.isSymbol('abc');
  15827. * // => false
  15828. */
  15829. function isSymbol(value) {
  15830. return typeof value == 'symbol' ||
  15831. (isObjectLike_1(value) && _baseGetTag(value) == symbolTag$1);
  15832. }
  15833. var isSymbol_1 = isSymbol;
  15834. /** Used to match property names within property paths. */
  15835. var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
  15836. reIsPlainProp = /^\w*$/;
  15837. /**
  15838. * Checks if `value` is a property name and not a property path.
  15839. *
  15840. * @private
  15841. * @param {*} value The value to check.
  15842. * @param {Object} [object] The object to query keys on.
  15843. * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
  15844. */
  15845. function isKey(value, object) {
  15846. if (isArray_1(value)) {
  15847. return false;
  15848. }
  15849. var type = typeof value;
  15850. if (type == 'number' || type == 'symbol' || type == 'boolean' ||
  15851. value == null || isSymbol_1(value)) {
  15852. return true;
  15853. }
  15854. return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
  15855. (object != null && value in Object(object));
  15856. }
  15857. var _isKey = isKey;
  15858. /** Error message constants. */
  15859. var FUNC_ERROR_TEXT = 'Expected a function';
  15860. /**
  15861. * Creates a function that memoizes the result of `func`. If `resolver` is
  15862. * provided, it determines the cache key for storing the result based on the
  15863. * arguments provided to the memoized function. By default, the first argument
  15864. * provided to the memoized function is used as the map cache key. The `func`
  15865. * is invoked with the `this` binding of the memoized function.
  15866. *
  15867. * **Note:** The cache is exposed as the `cache` property on the memoized
  15868. * function. Its creation may be customized by replacing the `_.memoize.Cache`
  15869. * constructor with one whose instances implement the
  15870. * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
  15871. * method interface of `clear`, `delete`, `get`, `has`, and `set`.
  15872. *
  15873. * @static
  15874. * @memberOf _
  15875. * @since 0.1.0
  15876. * @category Function
  15877. * @param {Function} func The function to have its output memoized.
  15878. * @param {Function} [resolver] The function to resolve the cache key.
  15879. * @returns {Function} Returns the new memoized function.
  15880. * @example
  15881. *
  15882. * var object = { 'a': 1, 'b': 2 };
  15883. * var other = { 'c': 3, 'd': 4 };
  15884. *
  15885. * var values = _.memoize(_.values);
  15886. * values(object);
  15887. * // => [1, 2]
  15888. *
  15889. * values(other);
  15890. * // => [3, 4]
  15891. *
  15892. * object.a = 2;
  15893. * values(object);
  15894. * // => [1, 2]
  15895. *
  15896. * // Modify the result cache.
  15897. * values.cache.set(object, ['a', 'b']);
  15898. * values(object);
  15899. * // => ['a', 'b']
  15900. *
  15901. * // Replace `_.memoize.Cache`.
  15902. * _.memoize.Cache = WeakMap;
  15903. */
  15904. function memoize(func, resolver) {
  15905. if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
  15906. throw new TypeError(FUNC_ERROR_TEXT);
  15907. }
  15908. var memoized = function() {
  15909. var args = arguments,
  15910. key = resolver ? resolver.apply(this, args) : args[0],
  15911. cache = memoized.cache;
  15912. if (cache.has(key)) {
  15913. return cache.get(key);
  15914. }
  15915. var result = func.apply(this, args);
  15916. memoized.cache = cache.set(key, result) || cache;
  15917. return result;
  15918. };
  15919. memoized.cache = new (memoize.Cache || _MapCache);
  15920. return memoized;
  15921. }
  15922. // Expose `MapCache`.
  15923. memoize.Cache = _MapCache;
  15924. var memoize_1 = memoize;
  15925. /** Used as the maximum memoize cache size. */
  15926. var MAX_MEMOIZE_SIZE = 500;
  15927. /**
  15928. * A specialized version of `_.memoize` which clears the memoized function's
  15929. * cache when it exceeds `MAX_MEMOIZE_SIZE`.
  15930. *
  15931. * @private
  15932. * @param {Function} func The function to have its output memoized.
  15933. * @returns {Function} Returns the new memoized function.
  15934. */
  15935. function memoizeCapped(func) {
  15936. var result = memoize_1(func, function(key) {
  15937. if (cache.size === MAX_MEMOIZE_SIZE) {
  15938. cache.clear();
  15939. }
  15940. return key;
  15941. });
  15942. var cache = result.cache;
  15943. return result;
  15944. }
  15945. var _memoizeCapped = memoizeCapped;
  15946. /** Used to match property names within property paths. */
  15947. var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
  15948. /** Used to match backslashes in property paths. */
  15949. var reEscapeChar = /\\(\\)?/g;
  15950. /**
  15951. * Converts `string` to a property path array.
  15952. *
  15953. * @private
  15954. * @param {string} string The string to convert.
  15955. * @returns {Array} Returns the property path array.
  15956. */
  15957. var stringToPath = _memoizeCapped(function(string) {
  15958. var result = [];
  15959. if (string.charCodeAt(0) === 46 /* . */) {
  15960. result.push('');
  15961. }
  15962. string.replace(rePropName, function(match, number, quote, subString) {
  15963. result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
  15964. });
  15965. return result;
  15966. });
  15967. var _stringToPath = stringToPath;
  15968. /** Used as references for various `Number` constants. */
  15969. var INFINITY = 1 / 0;
  15970. /** Used to convert symbols to primitives and strings. */
  15971. var symbolProto$1 = _Symbol ? _Symbol.prototype : undefined,
  15972. symbolToString = symbolProto$1 ? symbolProto$1.toString : undefined;
  15973. /**
  15974. * The base implementation of `_.toString` which doesn't convert nullish
  15975. * values to empty strings.
  15976. *
  15977. * @private
  15978. * @param {*} value The value to process.
  15979. * @returns {string} Returns the string.
  15980. */
  15981. function baseToString(value) {
  15982. // Exit early for strings to avoid a performance hit in some environments.
  15983. if (typeof value == 'string') {
  15984. return value;
  15985. }
  15986. if (isArray_1(value)) {
  15987. // Recursively convert values (susceptible to call stack limits).
  15988. return _arrayMap(value, baseToString) + '';
  15989. }
  15990. if (isSymbol_1(value)) {
  15991. return symbolToString ? symbolToString.call(value) : '';
  15992. }
  15993. var result = (value + '');
  15994. return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
  15995. }
  15996. var _baseToString = baseToString;
  15997. /**
  15998. * Converts `value` to a string. An empty string is returned for `null`
  15999. * and `undefined` values. The sign of `-0` is preserved.
  16000. *
  16001. * @static
  16002. * @memberOf _
  16003. * @since 4.0.0
  16004. * @category Lang
  16005. * @param {*} value The value to convert.
  16006. * @returns {string} Returns the converted string.
  16007. * @example
  16008. *
  16009. * _.toString(null);
  16010. * // => ''
  16011. *
  16012. * _.toString(-0);
  16013. * // => '-0'
  16014. *
  16015. * _.toString([1, 2, 3]);
  16016. * // => '1,2,3'
  16017. */
  16018. function toString(value) {
  16019. return value == null ? '' : _baseToString(value);
  16020. }
  16021. var toString_1 = toString;
  16022. /**
  16023. * Casts `value` to a path array if it's not one.
  16024. *
  16025. * @private
  16026. * @param {*} value The value to inspect.
  16027. * @param {Object} [object] The object to query keys on.
  16028. * @returns {Array} Returns the cast property path array.
  16029. */
  16030. function castPath(value, object) {
  16031. if (isArray_1(value)) {
  16032. return value;
  16033. }
  16034. return _isKey(value, object) ? [value] : _stringToPath(toString_1(value));
  16035. }
  16036. var _castPath = castPath;
  16037. /** Used as references for various `Number` constants. */
  16038. var INFINITY$1 = 1 / 0;
  16039. /**
  16040. * Converts `value` to a string key if it's not a string or symbol.
  16041. *
  16042. * @private
  16043. * @param {*} value The value to inspect.
  16044. * @returns {string|symbol} Returns the key.
  16045. */
  16046. function toKey(value) {
  16047. if (typeof value == 'string' || isSymbol_1(value)) {
  16048. return value;
  16049. }
  16050. var result = (value + '');
  16051. return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result;
  16052. }
  16053. var _toKey = toKey;
  16054. /**
  16055. * The base implementation of `_.get` without support for default values.
  16056. *
  16057. * @private
  16058. * @param {Object} object The object to query.
  16059. * @param {Array|string} path The path of the property to get.
  16060. * @returns {*} Returns the resolved value.
  16061. */
  16062. function baseGet(object, path) {
  16063. path = _castPath(path, object);
  16064. var index = 0,
  16065. length = path.length;
  16066. while (object != null && index < length) {
  16067. object = object[_toKey(path[index++])];
  16068. }
  16069. return (index && index == length) ? object : undefined;
  16070. }
  16071. var _baseGet = baseGet;
  16072. /**
  16073. * Gets the value at `path` of `object`. If the resolved value is
  16074. * `undefined`, the `defaultValue` is returned in its place.
  16075. *
  16076. * @static
  16077. * @memberOf _
  16078. * @since 3.7.0
  16079. * @category Object
  16080. * @param {Object} object The object to query.
  16081. * @param {Array|string} path The path of the property to get.
  16082. * @param {*} [defaultValue] The value returned for `undefined` resolved values.
  16083. * @returns {*} Returns the resolved value.
  16084. * @example
  16085. *
  16086. * var object = { 'a': [{ 'b': { 'c': 3 } }] };
  16087. *
  16088. * _.get(object, 'a[0].b.c');
  16089. * // => 3
  16090. *
  16091. * _.get(object, ['a', '0', 'b', 'c']);
  16092. * // => 3
  16093. *
  16094. * _.get(object, 'a.b.c', 'default');
  16095. * // => 'default'
  16096. */
  16097. function get(object, path, defaultValue) {
  16098. var result = object == null ? undefined : _baseGet(object, path);
  16099. return result === undefined ? defaultValue : result;
  16100. }
  16101. var get_1 = get;
  16102. /**
  16103. * The base implementation of `_.hasIn` without support for deep paths.
  16104. *
  16105. * @private
  16106. * @param {Object} [object] The object to query.
  16107. * @param {Array|string} key The key to check.
  16108. * @returns {boolean} Returns `true` if `key` exists, else `false`.
  16109. */
  16110. function baseHasIn(object, key) {
  16111. return object != null && key in Object(object);
  16112. }
  16113. var _baseHasIn = baseHasIn;
  16114. /**
  16115. * Checks if `path` exists on `object`.
  16116. *
  16117. * @private
  16118. * @param {Object} object The object to query.
  16119. * @param {Array|string} path The path to check.
  16120. * @param {Function} hasFunc The function to check properties.
  16121. * @returns {boolean} Returns `true` if `path` exists, else `false`.
  16122. */
  16123. function hasPath(object, path, hasFunc) {
  16124. path = _castPath(path, object);
  16125. var index = -1,
  16126. length = path.length,
  16127. result = false;
  16128. while (++index < length) {
  16129. var key = _toKey(path[index]);
  16130. if (!(result = object != null && hasFunc(object, key))) {
  16131. break;
  16132. }
  16133. object = object[key];
  16134. }
  16135. if (result || ++index != length) {
  16136. return result;
  16137. }
  16138. length = object == null ? 0 : object.length;
  16139. return !!length && isLength_1(length) && _isIndex(key, length) &&
  16140. (isArray_1(object) || isArguments_1(object));
  16141. }
  16142. var _hasPath = hasPath;
  16143. /**
  16144. * Checks if `path` is a direct or inherited property of `object`.
  16145. *
  16146. * @static
  16147. * @memberOf _
  16148. * @since 4.0.0
  16149. * @category Object
  16150. * @param {Object} object The object to query.
  16151. * @param {Array|string} path The path to check.
  16152. * @returns {boolean} Returns `true` if `path` exists, else `false`.
  16153. * @example
  16154. *
  16155. * var object = _.create({ 'a': _.create({ 'b': 2 }) });
  16156. *
  16157. * _.hasIn(object, 'a');
  16158. * // => true
  16159. *
  16160. * _.hasIn(object, 'a.b');
  16161. * // => true
  16162. *
  16163. * _.hasIn(object, ['a', 'b']);
  16164. * // => true
  16165. *
  16166. * _.hasIn(object, 'b');
  16167. * // => false
  16168. */
  16169. function hasIn(object, path) {
  16170. return object != null && _hasPath(object, path, _baseHasIn);
  16171. }
  16172. var hasIn_1 = hasIn;
  16173. /** Used to compose bitmasks for value comparisons. */
  16174. var COMPARE_PARTIAL_FLAG$5 = 1,
  16175. COMPARE_UNORDERED_FLAG$3 = 2;
  16176. /**
  16177. * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
  16178. *
  16179. * @private
  16180. * @param {string} path The path of the property to get.
  16181. * @param {*} srcValue The value to match.
  16182. * @returns {Function} Returns the new spec function.
  16183. */
  16184. function baseMatchesProperty(path, srcValue) {
  16185. if (_isKey(path) && _isStrictComparable(srcValue)) {
  16186. return _matchesStrictComparable(_toKey(path), srcValue);
  16187. }
  16188. return function(object) {
  16189. var objValue = get_1(object, path);
  16190. return (objValue === undefined && objValue === srcValue)
  16191. ? hasIn_1(object, path)
  16192. : _baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$5 | COMPARE_UNORDERED_FLAG$3);
  16193. };
  16194. }
  16195. var _baseMatchesProperty = baseMatchesProperty;
  16196. /**
  16197. * This method returns the first argument it receives.
  16198. *
  16199. * @static
  16200. * @since 0.1.0
  16201. * @memberOf _
  16202. * @category Util
  16203. * @param {*} value Any value.
  16204. * @returns {*} Returns `value`.
  16205. * @example
  16206. *
  16207. * var object = { 'a': 1 };
  16208. *
  16209. * console.log(_.identity(object) === object);
  16210. * // => true
  16211. */
  16212. function identity(value) {
  16213. return value;
  16214. }
  16215. var identity_1 = identity;
  16216. /**
  16217. * The base implementation of `_.property` without support for deep paths.
  16218. *
  16219. * @private
  16220. * @param {string} key The key of the property to get.
  16221. * @returns {Function} Returns the new accessor function.
  16222. */
  16223. function baseProperty(key) {
  16224. return function(object) {
  16225. return object == null ? undefined : object[key];
  16226. };
  16227. }
  16228. var _baseProperty = baseProperty;
  16229. /**
  16230. * A specialized version of `baseProperty` which supports deep paths.
  16231. *
  16232. * @private
  16233. * @param {Array|string} path The path of the property to get.
  16234. * @returns {Function} Returns the new accessor function.
  16235. */
  16236. function basePropertyDeep(path) {
  16237. return function(object) {
  16238. return _baseGet(object, path);
  16239. };
  16240. }
  16241. var _basePropertyDeep = basePropertyDeep;
  16242. /**
  16243. * Creates a function that returns the value at `path` of a given object.
  16244. *
  16245. * @static
  16246. * @memberOf _
  16247. * @since 2.4.0
  16248. * @category Util
  16249. * @param {Array|string} path The path of the property to get.
  16250. * @returns {Function} Returns the new accessor function.
  16251. * @example
  16252. *
  16253. * var objects = [
  16254. * { 'a': { 'b': 2 } },
  16255. * { 'a': { 'b': 1 } }
  16256. * ];
  16257. *
  16258. * _.map(objects, _.property('a.b'));
  16259. * // => [2, 1]
  16260. *
  16261. * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
  16262. * // => [1, 2]
  16263. */
  16264. function property(path) {
  16265. return _isKey(path) ? _baseProperty(_toKey(path)) : _basePropertyDeep(path);
  16266. }
  16267. var property_1 = property;
  16268. /**
  16269. * The base implementation of `_.iteratee`.
  16270. *
  16271. * @private
  16272. * @param {*} [value=_.identity] The value to convert to an iteratee.
  16273. * @returns {Function} Returns the iteratee.
  16274. */
  16275. function baseIteratee(value) {
  16276. // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
  16277. // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
  16278. if (typeof value == 'function') {
  16279. return value;
  16280. }
  16281. if (value == null) {
  16282. return identity_1;
  16283. }
  16284. if (typeof value == 'object') {
  16285. return isArray_1(value)
  16286. ? _baseMatchesProperty(value[0], value[1])
  16287. : _baseMatches(value);
  16288. }
  16289. return property_1(value);
  16290. }
  16291. var _baseIteratee = baseIteratee;
  16292. /**
  16293. * Gets the last element of `array`.
  16294. *
  16295. * @static
  16296. * @memberOf _
  16297. * @since 0.1.0
  16298. * @category Array
  16299. * @param {Array} array The array to query.
  16300. * @returns {*} Returns the last element of `array`.
  16301. * @example
  16302. *
  16303. * _.last([1, 2, 3]);
  16304. * // => 3
  16305. */
  16306. function last(array) {
  16307. var length = array == null ? 0 : array.length;
  16308. return length ? array[length - 1] : undefined;
  16309. }
  16310. var last_1 = last;
  16311. /**
  16312. * The base implementation of `_.slice` without an iteratee call guard.
  16313. *
  16314. * @private
  16315. * @param {Array} array The array to slice.
  16316. * @param {number} [start=0] The start position.
  16317. * @param {number} [end=array.length] The end position.
  16318. * @returns {Array} Returns the slice of `array`.
  16319. */
  16320. function baseSlice(array, start, end) {
  16321. var index = -1,
  16322. length = array.length;
  16323. if (start < 0) {
  16324. start = -start > length ? 0 : (length + start);
  16325. }
  16326. end = end > length ? length : end;
  16327. if (end < 0) {
  16328. end += length;
  16329. }
  16330. length = start > end ? 0 : ((end - start) >>> 0);
  16331. start >>>= 0;
  16332. var result = Array(length);
  16333. while (++index < length) {
  16334. result[index] = array[index + start];
  16335. }
  16336. return result;
  16337. }
  16338. var _baseSlice = baseSlice;
  16339. /**
  16340. * Gets the parent value at `path` of `object`.
  16341. *
  16342. * @private
  16343. * @param {Object} object The object to query.
  16344. * @param {Array} path The path to get the parent value of.
  16345. * @returns {*} Returns the parent value.
  16346. */
  16347. function parent(object, path) {
  16348. return path.length < 2 ? object : _baseGet(object, _baseSlice(path, 0, -1));
  16349. }
  16350. var _parent = parent;
  16351. /**
  16352. * The base implementation of `_.unset`.
  16353. *
  16354. * @private
  16355. * @param {Object} object The object to modify.
  16356. * @param {Array|string} path The property path to unset.
  16357. * @returns {boolean} Returns `true` if the property is deleted, else `false`.
  16358. */
  16359. function baseUnset(object, path) {
  16360. path = _castPath(path, object);
  16361. object = _parent(object, path);
  16362. return object == null || delete object[_toKey(last_1(path))];
  16363. }
  16364. var _baseUnset = baseUnset;
  16365. /** Used for built-in method references. */
  16366. var arrayProto$1 = Array.prototype;
  16367. /** Built-in value references. */
  16368. var splice$1 = arrayProto$1.splice;
  16369. /**
  16370. * The base implementation of `_.pullAt` without support for individual
  16371. * indexes or capturing the removed elements.
  16372. *
  16373. * @private
  16374. * @param {Array} array The array to modify.
  16375. * @param {number[]} indexes The indexes of elements to remove.
  16376. * @returns {Array} Returns `array`.
  16377. */
  16378. function basePullAt(array, indexes) {
  16379. var length = array ? indexes.length : 0,
  16380. lastIndex = length - 1;
  16381. while (length--) {
  16382. var index = indexes[length];
  16383. if (length == lastIndex || index !== previous) {
  16384. var previous = index;
  16385. if (_isIndex(index)) {
  16386. splice$1.call(array, index, 1);
  16387. } else {
  16388. _baseUnset(array, index);
  16389. }
  16390. }
  16391. }
  16392. return array;
  16393. }
  16394. var _basePullAt = basePullAt;
  16395. /**
  16396. * Removes all elements from `array` that `predicate` returns truthy for
  16397. * and returns an array of the removed elements. The predicate is invoked
  16398. * with three arguments: (value, index, array).
  16399. *
  16400. * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
  16401. * to pull elements from an array by value.
  16402. *
  16403. * @static
  16404. * @memberOf _
  16405. * @since 2.0.0
  16406. * @category Array
  16407. * @param {Array} array The array to modify.
  16408. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  16409. * @returns {Array} Returns the new array of removed elements.
  16410. * @example
  16411. *
  16412. * var array = [1, 2, 3, 4];
  16413. * var evens = _.remove(array, function(n) {
  16414. * return n % 2 == 0;
  16415. * });
  16416. *
  16417. * console.log(array);
  16418. * // => [1, 3]
  16419. *
  16420. * console.log(evens);
  16421. * // => [2, 4]
  16422. */
  16423. function remove(array, predicate) {
  16424. var result = [];
  16425. if (!(array && array.length)) {
  16426. return result;
  16427. }
  16428. var index = -1,
  16429. indexes = [],
  16430. length = array.length;
  16431. predicate = _baseIteratee(predicate);
  16432. while (++index < length) {
  16433. var value = array[index];
  16434. if (predicate(value, index, array)) {
  16435. result.push(value);
  16436. indexes.push(index);
  16437. }
  16438. }
  16439. _basePullAt(array, indexes);
  16440. return result;
  16441. }
  16442. var remove_1 = remove;
  16443. /** `Object#toString` result references. */
  16444. var mapTag$3 = '[object Map]',
  16445. setTag$3 = '[object Set]';
  16446. /** Used for built-in method references. */
  16447. var objectProto$d = Object.prototype;
  16448. /** Used to check objects for own properties. */
  16449. var hasOwnProperty$a = objectProto$d.hasOwnProperty;
  16450. /**
  16451. * Checks if `value` is an empty object, collection, map, or set.
  16452. *
  16453. * Objects are considered empty if they have no own enumerable string keyed
  16454. * properties.
  16455. *
  16456. * Array-like values such as `arguments` objects, arrays, buffers, strings, or
  16457. * jQuery-like collections are considered empty if they have a `length` of `0`.
  16458. * Similarly, maps and sets are considered empty if they have a `size` of `0`.
  16459. *
  16460. * @static
  16461. * @memberOf _
  16462. * @since 0.1.0
  16463. * @category Lang
  16464. * @param {*} value The value to check.
  16465. * @returns {boolean} Returns `true` if `value` is empty, else `false`.
  16466. * @example
  16467. *
  16468. * _.isEmpty(null);
  16469. * // => true
  16470. *
  16471. * _.isEmpty(true);
  16472. * // => true
  16473. *
  16474. * _.isEmpty(1);
  16475. * // => true
  16476. *
  16477. * _.isEmpty([1, 2, 3]);
  16478. * // => false
  16479. *
  16480. * _.isEmpty({ 'a': 1 });
  16481. * // => false
  16482. */
  16483. function isEmpty(value) {
  16484. if (value == null) {
  16485. return true;
  16486. }
  16487. if (isArrayLike_1(value) &&
  16488. (isArray_1(value) || typeof value == 'string' || typeof value.splice == 'function' ||
  16489. isBuffer_1(value) || isTypedArray_1(value) || isArguments_1(value))) {
  16490. return !value.length;
  16491. }
  16492. var tag = _getTag(value);
  16493. if (tag == mapTag$3 || tag == setTag$3) {
  16494. return !value.size;
  16495. }
  16496. if (_isPrototype(value)) {
  16497. return !_baseKeys(value).length;
  16498. }
  16499. for (var key in value) {
  16500. if (hasOwnProperty$a.call(value, key)) {
  16501. return false;
  16502. }
  16503. }
  16504. return true;
  16505. }
  16506. var isEmpty_1 = isEmpty;
  16507. /**
  16508. * A specialized version of `_.forEach` for arrays without support for
  16509. * iteratee shorthands.
  16510. *
  16511. * @private
  16512. * @param {Array} [array] The array to iterate over.
  16513. * @param {Function} iteratee The function invoked per iteration.
  16514. * @returns {Array} Returns `array`.
  16515. */
  16516. function arrayEach(array, iteratee) {
  16517. var index = -1,
  16518. length = array == null ? 0 : array.length;
  16519. while (++index < length) {
  16520. if (iteratee(array[index], index, array) === false) {
  16521. break;
  16522. }
  16523. }
  16524. return array;
  16525. }
  16526. var _arrayEach = arrayEach;
  16527. var defineProperty = (function() {
  16528. try {
  16529. var func = _getNative(Object, 'defineProperty');
  16530. func({}, '', {});
  16531. return func;
  16532. } catch (e) {}
  16533. }());
  16534. var _defineProperty = defineProperty;
  16535. /**
  16536. * The base implementation of `assignValue` and `assignMergeValue` without
  16537. * value checks.
  16538. *
  16539. * @private
  16540. * @param {Object} object The object to modify.
  16541. * @param {string} key The key of the property to assign.
  16542. * @param {*} value The value to assign.
  16543. */
  16544. function baseAssignValue(object, key, value) {
  16545. if (key == '__proto__' && _defineProperty) {
  16546. _defineProperty(object, key, {
  16547. 'configurable': true,
  16548. 'enumerable': true,
  16549. 'value': value,
  16550. 'writable': true
  16551. });
  16552. } else {
  16553. object[key] = value;
  16554. }
  16555. }
  16556. var _baseAssignValue = baseAssignValue;
  16557. /** Used for built-in method references. */
  16558. var objectProto$e = Object.prototype;
  16559. /** Used to check objects for own properties. */
  16560. var hasOwnProperty$b = objectProto$e.hasOwnProperty;
  16561. /**
  16562. * Assigns `value` to `key` of `object` if the existing value is not equivalent
  16563. * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  16564. * for equality comparisons.
  16565. *
  16566. * @private
  16567. * @param {Object} object The object to modify.
  16568. * @param {string} key The key of the property to assign.
  16569. * @param {*} value The value to assign.
  16570. */
  16571. function assignValue(object, key, value) {
  16572. var objValue = object[key];
  16573. if (!(hasOwnProperty$b.call(object, key) && eq_1(objValue, value)) ||
  16574. (value === undefined && !(key in object))) {
  16575. _baseAssignValue(object, key, value);
  16576. }
  16577. }
  16578. var _assignValue = assignValue;
  16579. /**
  16580. * Copies properties of `source` to `object`.
  16581. *
  16582. * @private
  16583. * @param {Object} source The object to copy properties from.
  16584. * @param {Array} props The property identifiers to copy.
  16585. * @param {Object} [object={}] The object to copy properties to.
  16586. * @param {Function} [customizer] The function to customize copied values.
  16587. * @returns {Object} Returns `object`.
  16588. */
  16589. function copyObject(source, props, object, customizer) {
  16590. var isNew = !object;
  16591. object || (object = {});
  16592. var index = -1,
  16593. length = props.length;
  16594. while (++index < length) {
  16595. var key = props[index];
  16596. var newValue = customizer
  16597. ? customizer(object[key], source[key], key, object, source)
  16598. : undefined;
  16599. if (newValue === undefined) {
  16600. newValue = source[key];
  16601. }
  16602. if (isNew) {
  16603. _baseAssignValue(object, key, newValue);
  16604. } else {
  16605. _assignValue(object, key, newValue);
  16606. }
  16607. }
  16608. return object;
  16609. }
  16610. var _copyObject = copyObject;
  16611. /**
  16612. * The base implementation of `_.assign` without support for multiple sources
  16613. * or `customizer` functions.
  16614. *
  16615. * @private
  16616. * @param {Object} object The destination object.
  16617. * @param {Object} source The source object.
  16618. * @returns {Object} Returns `object`.
  16619. */
  16620. function baseAssign(object, source) {
  16621. return object && _copyObject(source, keys_1(source), object);
  16622. }
  16623. var _baseAssign = baseAssign;
  16624. /**
  16625. * This function is like
  16626. * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
  16627. * except that it includes inherited enumerable properties.
  16628. *
  16629. * @private
  16630. * @param {Object} object The object to query.
  16631. * @returns {Array} Returns the array of property names.
  16632. */
  16633. function nativeKeysIn(object) {
  16634. var result = [];
  16635. if (object != null) {
  16636. for (var key in Object(object)) {
  16637. result.push(key);
  16638. }
  16639. }
  16640. return result;
  16641. }
  16642. var _nativeKeysIn = nativeKeysIn;
  16643. /** Used for built-in method references. */
  16644. var objectProto$f = Object.prototype;
  16645. /** Used to check objects for own properties. */
  16646. var hasOwnProperty$c = objectProto$f.hasOwnProperty;
  16647. /**
  16648. * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
  16649. *
  16650. * @private
  16651. * @param {Object} object The object to query.
  16652. * @returns {Array} Returns the array of property names.
  16653. */
  16654. function baseKeysIn(object) {
  16655. if (!isObject_1(object)) {
  16656. return _nativeKeysIn(object);
  16657. }
  16658. var isProto = _isPrototype(object),
  16659. result = [];
  16660. for (var key in object) {
  16661. if (!(key == 'constructor' && (isProto || !hasOwnProperty$c.call(object, key)))) {
  16662. result.push(key);
  16663. }
  16664. }
  16665. return result;
  16666. }
  16667. var _baseKeysIn = baseKeysIn;
  16668. /**
  16669. * Creates an array of the own and inherited enumerable property names of `object`.
  16670. *
  16671. * **Note:** Non-object values are coerced to objects.
  16672. *
  16673. * @static
  16674. * @memberOf _
  16675. * @since 3.0.0
  16676. * @category Object
  16677. * @param {Object} object The object to query.
  16678. * @returns {Array} Returns the array of property names.
  16679. * @example
  16680. *
  16681. * function Foo() {
  16682. * this.a = 1;
  16683. * this.b = 2;
  16684. * }
  16685. *
  16686. * Foo.prototype.c = 3;
  16687. *
  16688. * _.keysIn(new Foo);
  16689. * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
  16690. */
  16691. function keysIn(object) {
  16692. return isArrayLike_1(object) ? _arrayLikeKeys(object, true) : _baseKeysIn(object);
  16693. }
  16694. var keysIn_1 = keysIn;
  16695. /**
  16696. * The base implementation of `_.assignIn` without support for multiple sources
  16697. * or `customizer` functions.
  16698. *
  16699. * @private
  16700. * @param {Object} object The destination object.
  16701. * @param {Object} source The source object.
  16702. * @returns {Object} Returns `object`.
  16703. */
  16704. function baseAssignIn(object, source) {
  16705. return object && _copyObject(source, keysIn_1(source), object);
  16706. }
  16707. var _baseAssignIn = baseAssignIn;
  16708. var _cloneBuffer = createCommonjsModule(function (module, exports) {
  16709. /** Detect free variable `exports`. */
  16710. var freeExports = exports && !exports.nodeType && exports;
  16711. /** Detect free variable `module`. */
  16712. var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
  16713. /** Detect the popular CommonJS extension `module.exports`. */
  16714. var moduleExports = freeModule && freeModule.exports === freeExports;
  16715. /** Built-in value references. */
  16716. var Buffer = moduleExports ? _root.Buffer : undefined,
  16717. allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;
  16718. /**
  16719. * Creates a clone of `buffer`.
  16720. *
  16721. * @private
  16722. * @param {Buffer} buffer The buffer to clone.
  16723. * @param {boolean} [isDeep] Specify a deep clone.
  16724. * @returns {Buffer} Returns the cloned buffer.
  16725. */
  16726. function cloneBuffer(buffer, isDeep) {
  16727. if (isDeep) {
  16728. return buffer.slice();
  16729. }
  16730. var length = buffer.length,
  16731. result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
  16732. buffer.copy(result);
  16733. return result;
  16734. }
  16735. module.exports = cloneBuffer;
  16736. });
  16737. /**
  16738. * Copies own symbols of `source` to `object`.
  16739. *
  16740. * @private
  16741. * @param {Object} source The object to copy symbols from.
  16742. * @param {Object} [object={}] The object to copy symbols to.
  16743. * @returns {Object} Returns `object`.
  16744. */
  16745. function copySymbols(source, object) {
  16746. return _copyObject(source, _getSymbols(source), object);
  16747. }
  16748. var _copySymbols = copySymbols;
  16749. /* Built-in method references for those with the same name as other `lodash` methods. */
  16750. var nativeGetSymbols$1 = Object.getOwnPropertySymbols;
  16751. /**
  16752. * Creates an array of the own and inherited enumerable symbols of `object`.
  16753. *
  16754. * @private
  16755. * @param {Object} object The object to query.
  16756. * @returns {Array} Returns the array of symbols.
  16757. */
  16758. var getSymbolsIn = !nativeGetSymbols$1 ? stubArray_1 : function(object) {
  16759. var result = [];
  16760. while (object) {
  16761. _arrayPush(result, _getSymbols(object));
  16762. object = _getPrototype(object);
  16763. }
  16764. return result;
  16765. };
  16766. var _getSymbolsIn = getSymbolsIn;
  16767. /**
  16768. * Copies own and inherited symbols of `source` to `object`.
  16769. *
  16770. * @private
  16771. * @param {Object} source The object to copy symbols from.
  16772. * @param {Object} [object={}] The object to copy symbols to.
  16773. * @returns {Object} Returns `object`.
  16774. */
  16775. function copySymbolsIn(source, object) {
  16776. return _copyObject(source, _getSymbolsIn(source), object);
  16777. }
  16778. var _copySymbolsIn = copySymbolsIn;
  16779. /**
  16780. * Creates an array of own and inherited enumerable property names and
  16781. * symbols of `object`.
  16782. *
  16783. * @private
  16784. * @param {Object} object The object to query.
  16785. * @returns {Array} Returns the array of property names and symbols.
  16786. */
  16787. function getAllKeysIn(object) {
  16788. return _baseGetAllKeys(object, keysIn_1, _getSymbolsIn);
  16789. }
  16790. var _getAllKeysIn = getAllKeysIn;
  16791. /** Used for built-in method references. */
  16792. var objectProto$g = Object.prototype;
  16793. /** Used to check objects for own properties. */
  16794. var hasOwnProperty$d = objectProto$g.hasOwnProperty;
  16795. /**
  16796. * Initializes an array clone.
  16797. *
  16798. * @private
  16799. * @param {Array} array The array to clone.
  16800. * @returns {Array} Returns the initialized clone.
  16801. */
  16802. function initCloneArray(array) {
  16803. var length = array.length,
  16804. result = new array.constructor(length);
  16805. // Add properties assigned by `RegExp#exec`.
  16806. if (length && typeof array[0] == 'string' && hasOwnProperty$d.call(array, 'index')) {
  16807. result.index = array.index;
  16808. result.input = array.input;
  16809. }
  16810. return result;
  16811. }
  16812. var _initCloneArray = initCloneArray;
  16813. /**
  16814. * Creates a clone of `arrayBuffer`.
  16815. *
  16816. * @private
  16817. * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
  16818. * @returns {ArrayBuffer} Returns the cloned array buffer.
  16819. */
  16820. function cloneArrayBuffer(arrayBuffer) {
  16821. var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
  16822. new _Uint8Array(result).set(new _Uint8Array(arrayBuffer));
  16823. return result;
  16824. }
  16825. var _cloneArrayBuffer = cloneArrayBuffer;
  16826. /**
  16827. * Creates a clone of `dataView`.
  16828. *
  16829. * @private
  16830. * @param {Object} dataView The data view to clone.
  16831. * @param {boolean} [isDeep] Specify a deep clone.
  16832. * @returns {Object} Returns the cloned data view.
  16833. */
  16834. function cloneDataView(dataView, isDeep) {
  16835. var buffer = isDeep ? _cloneArrayBuffer(dataView.buffer) : dataView.buffer;
  16836. return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
  16837. }
  16838. var _cloneDataView = cloneDataView;
  16839. /** Used to match `RegExp` flags from their coerced string values. */
  16840. var reFlags = /\w*$/;
  16841. /**
  16842. * Creates a clone of `regexp`.
  16843. *
  16844. * @private
  16845. * @param {Object} regexp The regexp to clone.
  16846. * @returns {Object} Returns the cloned regexp.
  16847. */
  16848. function cloneRegExp(regexp) {
  16849. var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
  16850. result.lastIndex = regexp.lastIndex;
  16851. return result;
  16852. }
  16853. var _cloneRegExp = cloneRegExp;
  16854. /** Used to convert symbols to primitives and strings. */
  16855. var symbolProto$2 = _Symbol ? _Symbol.prototype : undefined,
  16856. symbolValueOf$1 = symbolProto$2 ? symbolProto$2.valueOf : undefined;
  16857. /**
  16858. * Creates a clone of the `symbol` object.
  16859. *
  16860. * @private
  16861. * @param {Object} symbol The symbol object to clone.
  16862. * @returns {Object} Returns the cloned symbol object.
  16863. */
  16864. function cloneSymbol(symbol) {
  16865. return symbolValueOf$1 ? Object(symbolValueOf$1.call(symbol)) : {};
  16866. }
  16867. var _cloneSymbol = cloneSymbol;
  16868. /**
  16869. * Creates a clone of `typedArray`.
  16870. *
  16871. * @private
  16872. * @param {Object} typedArray The typed array to clone.
  16873. * @param {boolean} [isDeep] Specify a deep clone.
  16874. * @returns {Object} Returns the cloned typed array.
  16875. */
  16876. function cloneTypedArray(typedArray, isDeep) {
  16877. var buffer = isDeep ? _cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
  16878. return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
  16879. }
  16880. var _cloneTypedArray = cloneTypedArray;
  16881. /** `Object#toString` result references. */
  16882. var boolTag$2 = '[object Boolean]',
  16883. dateTag$2 = '[object Date]',
  16884. mapTag$4 = '[object Map]',
  16885. numberTag$2 = '[object Number]',
  16886. regexpTag$2 = '[object RegExp]',
  16887. setTag$4 = '[object Set]',
  16888. stringTag$2 = '[object String]',
  16889. symbolTag$2 = '[object Symbol]';
  16890. var arrayBufferTag$2 = '[object ArrayBuffer]',
  16891. dataViewTag$3 = '[object DataView]',
  16892. float32Tag$1 = '[object Float32Array]',
  16893. float64Tag$1 = '[object Float64Array]',
  16894. int8Tag$1 = '[object Int8Array]',
  16895. int16Tag$1 = '[object Int16Array]',
  16896. int32Tag$1 = '[object Int32Array]',
  16897. uint8Tag$1 = '[object Uint8Array]',
  16898. uint8ClampedTag$1 = '[object Uint8ClampedArray]',
  16899. uint16Tag$1 = '[object Uint16Array]',
  16900. uint32Tag$1 = '[object Uint32Array]';
  16901. /**
  16902. * Initializes an object clone based on its `toStringTag`.
  16903. *
  16904. * **Note:** This function only supports cloning values with tags of
  16905. * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
  16906. *
  16907. * @private
  16908. * @param {Object} object The object to clone.
  16909. * @param {string} tag The `toStringTag` of the object to clone.
  16910. * @param {boolean} [isDeep] Specify a deep clone.
  16911. * @returns {Object} Returns the initialized clone.
  16912. */
  16913. function initCloneByTag(object, tag, isDeep) {
  16914. var Ctor = object.constructor;
  16915. switch (tag) {
  16916. case arrayBufferTag$2:
  16917. return _cloneArrayBuffer(object);
  16918. case boolTag$2:
  16919. case dateTag$2:
  16920. return new Ctor(+object);
  16921. case dataViewTag$3:
  16922. return _cloneDataView(object, isDeep);
  16923. case float32Tag$1: case float64Tag$1:
  16924. case int8Tag$1: case int16Tag$1: case int32Tag$1:
  16925. case uint8Tag$1: case uint8ClampedTag$1: case uint16Tag$1: case uint32Tag$1:
  16926. return _cloneTypedArray(object, isDeep);
  16927. case mapTag$4:
  16928. return new Ctor;
  16929. case numberTag$2:
  16930. case stringTag$2:
  16931. return new Ctor(object);
  16932. case regexpTag$2:
  16933. return _cloneRegExp(object);
  16934. case setTag$4:
  16935. return new Ctor;
  16936. case symbolTag$2:
  16937. return _cloneSymbol(object);
  16938. }
  16939. }
  16940. var _initCloneByTag = initCloneByTag;
  16941. /** Built-in value references. */
  16942. var objectCreate = Object.create;
  16943. /**
  16944. * The base implementation of `_.create` without support for assigning
  16945. * properties to the created object.
  16946. *
  16947. * @private
  16948. * @param {Object} proto The object to inherit from.
  16949. * @returns {Object} Returns the new object.
  16950. */
  16951. var baseCreate = (function() {
  16952. function object() {}
  16953. return function(proto) {
  16954. if (!isObject_1(proto)) {
  16955. return {};
  16956. }
  16957. if (objectCreate) {
  16958. return objectCreate(proto);
  16959. }
  16960. object.prototype = proto;
  16961. var result = new object;
  16962. object.prototype = undefined;
  16963. return result;
  16964. };
  16965. }());
  16966. var _baseCreate = baseCreate;
  16967. /**
  16968. * Initializes an object clone.
  16969. *
  16970. * @private
  16971. * @param {Object} object The object to clone.
  16972. * @returns {Object} Returns the initialized clone.
  16973. */
  16974. function initCloneObject(object) {
  16975. return (typeof object.constructor == 'function' && !_isPrototype(object))
  16976. ? _baseCreate(_getPrototype(object))
  16977. : {};
  16978. }
  16979. var _initCloneObject = initCloneObject;
  16980. /** `Object#toString` result references. */
  16981. var mapTag$5 = '[object Map]';
  16982. /**
  16983. * The base implementation of `_.isMap` without Node.js optimizations.
  16984. *
  16985. * @private
  16986. * @param {*} value The value to check.
  16987. * @returns {boolean} Returns `true` if `value` is a map, else `false`.
  16988. */
  16989. function baseIsMap(value) {
  16990. return isObjectLike_1(value) && _getTag(value) == mapTag$5;
  16991. }
  16992. var _baseIsMap = baseIsMap;
  16993. /* Node.js helper references. */
  16994. var nodeIsMap = _nodeUtil && _nodeUtil.isMap;
  16995. /**
  16996. * Checks if `value` is classified as a `Map` object.
  16997. *
  16998. * @static
  16999. * @memberOf _
  17000. * @since 4.3.0
  17001. * @category Lang
  17002. * @param {*} value The value to check.
  17003. * @returns {boolean} Returns `true` if `value` is a map, else `false`.
  17004. * @example
  17005. *
  17006. * _.isMap(new Map);
  17007. * // => true
  17008. *
  17009. * _.isMap(new WeakMap);
  17010. * // => false
  17011. */
  17012. var isMap = nodeIsMap ? _baseUnary(nodeIsMap) : _baseIsMap;
  17013. var isMap_1 = isMap;
  17014. /** `Object#toString` result references. */
  17015. var setTag$5 = '[object Set]';
  17016. /**
  17017. * The base implementation of `_.isSet` without Node.js optimizations.
  17018. *
  17019. * @private
  17020. * @param {*} value The value to check.
  17021. * @returns {boolean} Returns `true` if `value` is a set, else `false`.
  17022. */
  17023. function baseIsSet(value) {
  17024. return isObjectLike_1(value) && _getTag(value) == setTag$5;
  17025. }
  17026. var _baseIsSet = baseIsSet;
  17027. /* Node.js helper references. */
  17028. var nodeIsSet = _nodeUtil && _nodeUtil.isSet;
  17029. /**
  17030. * Checks if `value` is classified as a `Set` object.
  17031. *
  17032. * @static
  17033. * @memberOf _
  17034. * @since 4.3.0
  17035. * @category Lang
  17036. * @param {*} value The value to check.
  17037. * @returns {boolean} Returns `true` if `value` is a set, else `false`.
  17038. * @example
  17039. *
  17040. * _.isSet(new Set);
  17041. * // => true
  17042. *
  17043. * _.isSet(new WeakSet);
  17044. * // => false
  17045. */
  17046. var isSet = nodeIsSet ? _baseUnary(nodeIsSet) : _baseIsSet;
  17047. var isSet_1 = isSet;
  17048. /** Used to compose bitmasks for cloning. */
  17049. var CLONE_DEEP_FLAG = 1,
  17050. CLONE_FLAT_FLAG = 2,
  17051. CLONE_SYMBOLS_FLAG = 4;
  17052. /** `Object#toString` result references. */
  17053. var argsTag$3 = '[object Arguments]',
  17054. arrayTag$2 = '[object Array]',
  17055. boolTag$3 = '[object Boolean]',
  17056. dateTag$3 = '[object Date]',
  17057. errorTag$2 = '[object Error]',
  17058. funcTag$2 = '[object Function]',
  17059. genTag$1 = '[object GeneratorFunction]',
  17060. mapTag$6 = '[object Map]',
  17061. numberTag$3 = '[object Number]',
  17062. objectTag$4 = '[object Object]',
  17063. regexpTag$3 = '[object RegExp]',
  17064. setTag$6 = '[object Set]',
  17065. stringTag$3 = '[object String]',
  17066. symbolTag$3 = '[object Symbol]',
  17067. weakMapTag$2 = '[object WeakMap]';
  17068. var arrayBufferTag$3 = '[object ArrayBuffer]',
  17069. dataViewTag$4 = '[object DataView]',
  17070. float32Tag$2 = '[object Float32Array]',
  17071. float64Tag$2 = '[object Float64Array]',
  17072. int8Tag$2 = '[object Int8Array]',
  17073. int16Tag$2 = '[object Int16Array]',
  17074. int32Tag$2 = '[object Int32Array]',
  17075. uint8Tag$2 = '[object Uint8Array]',
  17076. uint8ClampedTag$2 = '[object Uint8ClampedArray]',
  17077. uint16Tag$2 = '[object Uint16Array]',
  17078. uint32Tag$2 = '[object Uint32Array]';
  17079. /** Used to identify `toStringTag` values supported by `_.clone`. */
  17080. var cloneableTags = {};
  17081. cloneableTags[argsTag$3] = cloneableTags[arrayTag$2] =
  17082. cloneableTags[arrayBufferTag$3] = cloneableTags[dataViewTag$4] =
  17083. cloneableTags[boolTag$3] = cloneableTags[dateTag$3] =
  17084. cloneableTags[float32Tag$2] = cloneableTags[float64Tag$2] =
  17085. cloneableTags[int8Tag$2] = cloneableTags[int16Tag$2] =
  17086. cloneableTags[int32Tag$2] = cloneableTags[mapTag$6] =
  17087. cloneableTags[numberTag$3] = cloneableTags[objectTag$4] =
  17088. cloneableTags[regexpTag$3] = cloneableTags[setTag$6] =
  17089. cloneableTags[stringTag$3] = cloneableTags[symbolTag$3] =
  17090. cloneableTags[uint8Tag$2] = cloneableTags[uint8ClampedTag$2] =
  17091. cloneableTags[uint16Tag$2] = cloneableTags[uint32Tag$2] = true;
  17092. cloneableTags[errorTag$2] = cloneableTags[funcTag$2] =
  17093. cloneableTags[weakMapTag$2] = false;
  17094. /**
  17095. * The base implementation of `_.clone` and `_.cloneDeep` which tracks
  17096. * traversed objects.
  17097. *
  17098. * @private
  17099. * @param {*} value The value to clone.
  17100. * @param {boolean} bitmask The bitmask flags.
  17101. * 1 - Deep clone
  17102. * 2 - Flatten inherited properties
  17103. * 4 - Clone symbols
  17104. * @param {Function} [customizer] The function to customize cloning.
  17105. * @param {string} [key] The key of `value`.
  17106. * @param {Object} [object] The parent object of `value`.
  17107. * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
  17108. * @returns {*} Returns the cloned value.
  17109. */
  17110. function baseClone(value, bitmask, customizer, key, object, stack) {
  17111. var result,
  17112. isDeep = bitmask & CLONE_DEEP_FLAG,
  17113. isFlat = bitmask & CLONE_FLAT_FLAG,
  17114. isFull = bitmask & CLONE_SYMBOLS_FLAG;
  17115. if (customizer) {
  17116. result = object ? customizer(value, key, object, stack) : customizer(value);
  17117. }
  17118. if (result !== undefined) {
  17119. return result;
  17120. }
  17121. if (!isObject_1(value)) {
  17122. return value;
  17123. }
  17124. var isArr = isArray_1(value);
  17125. if (isArr) {
  17126. result = _initCloneArray(value);
  17127. if (!isDeep) {
  17128. return _copyArray(value, result);
  17129. }
  17130. } else {
  17131. var tag = _getTag(value),
  17132. isFunc = tag == funcTag$2 || tag == genTag$1;
  17133. if (isBuffer_1(value)) {
  17134. return _cloneBuffer(value, isDeep);
  17135. }
  17136. if (tag == objectTag$4 || tag == argsTag$3 || (isFunc && !object)) {
  17137. result = (isFlat || isFunc) ? {} : _initCloneObject(value);
  17138. if (!isDeep) {
  17139. return isFlat
  17140. ? _copySymbolsIn(value, _baseAssignIn(result, value))
  17141. : _copySymbols(value, _baseAssign(result, value));
  17142. }
  17143. } else {
  17144. if (!cloneableTags[tag]) {
  17145. return object ? value : {};
  17146. }
  17147. result = _initCloneByTag(value, tag, isDeep);
  17148. }
  17149. }
  17150. // Check for circular references and return its corresponding clone.
  17151. stack || (stack = new _Stack);
  17152. var stacked = stack.get(value);
  17153. if (stacked) {
  17154. return stacked;
  17155. }
  17156. stack.set(value, result);
  17157. if (isSet_1(value)) {
  17158. value.forEach(function(subValue) {
  17159. result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
  17160. });
  17161. } else if (isMap_1(value)) {
  17162. value.forEach(function(subValue, key) {
  17163. result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
  17164. });
  17165. }
  17166. var keysFunc = isFull
  17167. ? (isFlat ? _getAllKeysIn : _getAllKeys)
  17168. : (isFlat ? keysIn_1 : keys_1);
  17169. var props = isArr ? undefined : keysFunc(value);
  17170. _arrayEach(props || value, function(subValue, key) {
  17171. if (props) {
  17172. key = subValue;
  17173. subValue = value[key];
  17174. }
  17175. // Recursively populate clone (susceptible to call stack limits).
  17176. _assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
  17177. });
  17178. return result;
  17179. }
  17180. var _baseClone = baseClone;
  17181. /** Used to compose bitmasks for cloning. */
  17182. var CLONE_DEEP_FLAG$1 = 1,
  17183. CLONE_SYMBOLS_FLAG$1 = 4;
  17184. /**
  17185. * This method is like `_.clone` except that it recursively clones `value`.
  17186. *
  17187. * @static
  17188. * @memberOf _
  17189. * @since 1.0.0
  17190. * @category Lang
  17191. * @param {*} value The value to recursively clone.
  17192. * @returns {*} Returns the deep cloned value.
  17193. * @see _.clone
  17194. * @example
  17195. *
  17196. * var objects = [{ 'a': 1 }, { 'b': 2 }];
  17197. *
  17198. * var deep = _.cloneDeep(objects);
  17199. * console.log(deep[0] === objects[0]);
  17200. * // => false
  17201. */
  17202. function cloneDeep(value) {
  17203. return _baseClone(value, CLONE_DEEP_FLAG$1 | CLONE_SYMBOLS_FLAG$1);
  17204. }
  17205. var cloneDeep_1 = cloneDeep;
  17206. /**
  17207. * Creates a `_.find` or `_.findLast` function.
  17208. *
  17209. * @private
  17210. * @param {Function} findIndexFunc The function to find the collection index.
  17211. * @returns {Function} Returns the new find function.
  17212. */
  17213. function createFind(findIndexFunc) {
  17214. return function(collection, predicate, fromIndex) {
  17215. var iterable = Object(collection);
  17216. if (!isArrayLike_1(collection)) {
  17217. var iteratee = _baseIteratee(predicate);
  17218. collection = keys_1(collection);
  17219. predicate = function(key) { return iteratee(iterable[key], key, iterable); };
  17220. }
  17221. var index = findIndexFunc(collection, predicate, fromIndex);
  17222. return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
  17223. };
  17224. }
  17225. var _createFind = createFind;
  17226. /**
  17227. * The base implementation of `_.findIndex` and `_.findLastIndex` without
  17228. * support for iteratee shorthands.
  17229. *
  17230. * @private
  17231. * @param {Array} array The array to inspect.
  17232. * @param {Function} predicate The function invoked per iteration.
  17233. * @param {number} fromIndex The index to search from.
  17234. * @param {boolean} [fromRight] Specify iterating from right to left.
  17235. * @returns {number} Returns the index of the matched value, else `-1`.
  17236. */
  17237. function baseFindIndex(array, predicate, fromIndex, fromRight) {
  17238. var length = array.length,
  17239. index = fromIndex + (fromRight ? 1 : -1);
  17240. while ((fromRight ? index-- : ++index < length)) {
  17241. if (predicate(array[index], index, array)) {
  17242. return index;
  17243. }
  17244. }
  17245. return -1;
  17246. }
  17247. var _baseFindIndex = baseFindIndex;
  17248. /** Used to match a single whitespace character. */
  17249. var reWhitespace = /\s/;
  17250. /**
  17251. * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
  17252. * character of `string`.
  17253. *
  17254. * @private
  17255. * @param {string} string The string to inspect.
  17256. * @returns {number} Returns the index of the last non-whitespace character.
  17257. */
  17258. function trimmedEndIndex(string) {
  17259. var index = string.length;
  17260. while (index-- && reWhitespace.test(string.charAt(index))) {}
  17261. return index;
  17262. }
  17263. var _trimmedEndIndex = trimmedEndIndex;
  17264. /** Used to match leading whitespace. */
  17265. var reTrimStart = /^\s+/;
  17266. /**
  17267. * The base implementation of `_.trim`.
  17268. *
  17269. * @private
  17270. * @param {string} string The string to trim.
  17271. * @returns {string} Returns the trimmed string.
  17272. */
  17273. function baseTrim(string) {
  17274. return string
  17275. ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '')
  17276. : string;
  17277. }
  17278. var _baseTrim = baseTrim;
  17279. /** Used as references for various `Number` constants. */
  17280. var NAN = 0 / 0;
  17281. /** Used to detect bad signed hexadecimal string values. */
  17282. var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
  17283. /** Used to detect binary string values. */
  17284. var reIsBinary = /^0b[01]+$/i;
  17285. /** Used to detect octal string values. */
  17286. var reIsOctal = /^0o[0-7]+$/i;
  17287. /** Built-in method references without a dependency on `root`. */
  17288. var freeParseInt = parseInt;
  17289. /**
  17290. * Converts `value` to a number.
  17291. *
  17292. * @static
  17293. * @memberOf _
  17294. * @since 4.0.0
  17295. * @category Lang
  17296. * @param {*} value The value to process.
  17297. * @returns {number} Returns the number.
  17298. * @example
  17299. *
  17300. * _.toNumber(3.2);
  17301. * // => 3.2
  17302. *
  17303. * _.toNumber(Number.MIN_VALUE);
  17304. * // => 5e-324
  17305. *
  17306. * _.toNumber(Infinity);
  17307. * // => Infinity
  17308. *
  17309. * _.toNumber('3.2');
  17310. * // => 3.2
  17311. */
  17312. function toNumber(value) {
  17313. if (typeof value == 'number') {
  17314. return value;
  17315. }
  17316. if (isSymbol_1(value)) {
  17317. return NAN;
  17318. }
  17319. if (isObject_1(value)) {
  17320. var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
  17321. value = isObject_1(other) ? (other + '') : other;
  17322. }
  17323. if (typeof value != 'string') {
  17324. return value === 0 ? value : +value;
  17325. }
  17326. value = _baseTrim(value);
  17327. var isBinary = reIsBinary.test(value);
  17328. return (isBinary || reIsOctal.test(value))
  17329. ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
  17330. : (reIsBadHex.test(value) ? NAN : +value);
  17331. }
  17332. var toNumber_1 = toNumber;
  17333. /** Used as references for various `Number` constants. */
  17334. var INFINITY$2 = 1 / 0,
  17335. MAX_INTEGER = 1.7976931348623157e+308;
  17336. /**
  17337. * Converts `value` to a finite number.
  17338. *
  17339. * @static
  17340. * @memberOf _
  17341. * @since 4.12.0
  17342. * @category Lang
  17343. * @param {*} value The value to convert.
  17344. * @returns {number} Returns the converted number.
  17345. * @example
  17346. *
  17347. * _.toFinite(3.2);
  17348. * // => 3.2
  17349. *
  17350. * _.toFinite(Number.MIN_VALUE);
  17351. * // => 5e-324
  17352. *
  17353. * _.toFinite(Infinity);
  17354. * // => 1.7976931348623157e+308
  17355. *
  17356. * _.toFinite('3.2');
  17357. * // => 3.2
  17358. */
  17359. function toFinite(value) {
  17360. if (!value) {
  17361. return value === 0 ? value : 0;
  17362. }
  17363. value = toNumber_1(value);
  17364. if (value === INFINITY$2 || value === -INFINITY$2) {
  17365. var sign = (value < 0 ? -1 : 1);
  17366. return sign * MAX_INTEGER;
  17367. }
  17368. return value === value ? value : 0;
  17369. }
  17370. var toFinite_1 = toFinite;
  17371. /**
  17372. * Converts `value` to an integer.
  17373. *
  17374. * **Note:** This method is loosely based on
  17375. * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
  17376. *
  17377. * @static
  17378. * @memberOf _
  17379. * @since 4.0.0
  17380. * @category Lang
  17381. * @param {*} value The value to convert.
  17382. * @returns {number} Returns the converted integer.
  17383. * @example
  17384. *
  17385. * _.toInteger(3.2);
  17386. * // => 3
  17387. *
  17388. * _.toInteger(Number.MIN_VALUE);
  17389. * // => 0
  17390. *
  17391. * _.toInteger(Infinity);
  17392. * // => 1.7976931348623157e+308
  17393. *
  17394. * _.toInteger('3.2');
  17395. * // => 3
  17396. */
  17397. function toInteger(value) {
  17398. var result = toFinite_1(value),
  17399. remainder = result % 1;
  17400. return result === result ? (remainder ? result - remainder : result) : 0;
  17401. }
  17402. var toInteger_1 = toInteger;
  17403. /* Built-in method references for those with the same name as other `lodash` methods. */
  17404. var nativeMax = Math.max;
  17405. /**
  17406. * This method is like `_.find` except that it returns the index of the first
  17407. * element `predicate` returns truthy for instead of the element itself.
  17408. *
  17409. * @static
  17410. * @memberOf _
  17411. * @since 1.1.0
  17412. * @category Array
  17413. * @param {Array} array The array to inspect.
  17414. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  17415. * @param {number} [fromIndex=0] The index to search from.
  17416. * @returns {number} Returns the index of the found element, else `-1`.
  17417. * @example
  17418. *
  17419. * var users = [
  17420. * { 'user': 'barney', 'active': false },
  17421. * { 'user': 'fred', 'active': false },
  17422. * { 'user': 'pebbles', 'active': true }
  17423. * ];
  17424. *
  17425. * _.findIndex(users, function(o) { return o.user == 'barney'; });
  17426. * // => 0
  17427. *
  17428. * // The `_.matches` iteratee shorthand.
  17429. * _.findIndex(users, { 'user': 'fred', 'active': false });
  17430. * // => 1
  17431. *
  17432. * // The `_.matchesProperty` iteratee shorthand.
  17433. * _.findIndex(users, ['active', false]);
  17434. * // => 0
  17435. *
  17436. * // The `_.property` iteratee shorthand.
  17437. * _.findIndex(users, 'active');
  17438. * // => 2
  17439. */
  17440. function findIndex(array, predicate, fromIndex) {
  17441. var length = array == null ? 0 : array.length;
  17442. if (!length) {
  17443. return -1;
  17444. }
  17445. var index = fromIndex == null ? 0 : toInteger_1(fromIndex);
  17446. if (index < 0) {
  17447. index = nativeMax(length + index, 0);
  17448. }
  17449. return _baseFindIndex(array, _baseIteratee(predicate), index);
  17450. }
  17451. var findIndex_1 = findIndex;
  17452. /**
  17453. * Iterates over elements of `collection`, returning the first element
  17454. * `predicate` returns truthy for. The predicate is invoked with three
  17455. * arguments: (value, index|key, collection).
  17456. *
  17457. * @static
  17458. * @memberOf _
  17459. * @since 0.1.0
  17460. * @category Collection
  17461. * @param {Array|Object} collection The collection to inspect.
  17462. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  17463. * @param {number} [fromIndex=0] The index to search from.
  17464. * @returns {*} Returns the matched element, else `undefined`.
  17465. * @example
  17466. *
  17467. * var users = [
  17468. * { 'user': 'barney', 'age': 36, 'active': true },
  17469. * { 'user': 'fred', 'age': 40, 'active': false },
  17470. * { 'user': 'pebbles', 'age': 1, 'active': true }
  17471. * ];
  17472. *
  17473. * _.find(users, function(o) { return o.age < 40; });
  17474. * // => object for 'barney'
  17475. *
  17476. * // The `_.matches` iteratee shorthand.
  17477. * _.find(users, { 'age': 1, 'active': true });
  17478. * // => object for 'pebbles'
  17479. *
  17480. * // The `_.matchesProperty` iteratee shorthand.
  17481. * _.find(users, ['active', false]);
  17482. * // => object for 'fred'
  17483. *
  17484. * // The `_.property` iteratee shorthand.
  17485. * _.find(users, 'active');
  17486. * // => object for 'barney'
  17487. */
  17488. var find = _createFind(findIndex_1);
  17489. var find_1 = find;
  17490. // IMClient
  17491. const UNREAD_MESSAGES_COUNT_UPDATE = 'unreadmessagescountupdate';
  17492. const CLOSE = 'close';
  17493. const CONFLICT = 'conflict';
  17494. const CONVERSATION_INFO_UPDATED = 'conversationinfoupdated';
  17495. const UNHANDLED_MESSAGE = 'unhandledmessage'; // shared
  17496. const INVITED = 'invited';
  17497. const KICKED = 'kicked';
  17498. const MEMBERS_JOINED = 'membersjoined';
  17499. const MEMBERS_LEFT = 'membersleft';
  17500. const MEMBER_INFO_UPDATED = 'memberinfoupdated';
  17501. const BLOCKED = 'blocked';
  17502. const UNBLOCKED = 'unblocked';
  17503. const MEMBERS_BLOCKED = 'membersblocked';
  17504. const MEMBERS_UNBLOCKED = 'membersunblocked';
  17505. const MUTED = 'muted';
  17506. const UNMUTED = 'unmuted';
  17507. const MEMBERS_MUTED = 'membersmuted';
  17508. const MEMBERS_UNMUTED = 'membersunmuted';
  17509. const MESSAGE$1 = 'message';
  17510. const MESSAGE_RECALL = 'messagerecall';
  17511. const MESSAGE_UPDATE = 'messageupdate'; // Conversation
  17512. const LAST_DELIVERED_AT_UPDATE = 'lastdeliveredatupdate';
  17513. const LAST_READ_AT_UPDATE = 'lastreadatupdate';
  17514. const INFO_UPDATED = 'infoupdated';
  17515. var IMEvent = /*#__PURE__*/Object.freeze({
  17516. __proto__: null,
  17517. UNREAD_MESSAGES_COUNT_UPDATE: UNREAD_MESSAGES_COUNT_UPDATE,
  17518. CLOSE: CLOSE,
  17519. CONFLICT: CONFLICT,
  17520. CONVERSATION_INFO_UPDATED: CONVERSATION_INFO_UPDATED,
  17521. UNHANDLED_MESSAGE: UNHANDLED_MESSAGE,
  17522. INVITED: INVITED,
  17523. KICKED: KICKED,
  17524. MEMBERS_JOINED: MEMBERS_JOINED,
  17525. MEMBERS_LEFT: MEMBERS_LEFT,
  17526. MEMBER_INFO_UPDATED: MEMBER_INFO_UPDATED,
  17527. BLOCKED: BLOCKED,
  17528. UNBLOCKED: UNBLOCKED,
  17529. MEMBERS_BLOCKED: MEMBERS_BLOCKED,
  17530. MEMBERS_UNBLOCKED: MEMBERS_UNBLOCKED,
  17531. MUTED: MUTED,
  17532. UNMUTED: UNMUTED,
  17533. MEMBERS_MUTED: MEMBERS_MUTED,
  17534. MEMBERS_UNMUTED: MEMBERS_UNMUTED,
  17535. MESSAGE: MESSAGE$1,
  17536. MESSAGE_RECALL: MESSAGE_RECALL,
  17537. MESSAGE_UPDATE: MESSAGE_UPDATE,
  17538. LAST_DELIVERED_AT_UPDATE: LAST_DELIVERED_AT_UPDATE,
  17539. LAST_READ_AT_UPDATE: LAST_READ_AT_UPDATE,
  17540. INFO_UPDATED: INFO_UPDATED
  17541. });
  17542. /**
  17543. * 消息状态枚举
  17544. * @enum {Symbol}
  17545. * @since 3.2.0
  17546. * @memberof module:leancloud-realtime
  17547. */
  17548. const MessageStatus = {
  17549. /** 初始状态、未知状态 */
  17550. NONE: Symbol('none'),
  17551. /** 正在发送 */
  17552. SENDING: Symbol('sending'),
  17553. /** 已发送 */
  17554. SENT: Symbol('sent'),
  17555. /** 已送达 */
  17556. DELIVERED: Symbol('delivered'),
  17557. /** 发送失败 */
  17558. FAILED: Symbol('failed')
  17559. };
  17560. Object.freeze(MessageStatus);
  17561. const rMessageStatus = {
  17562. [MessageStatus.NONE]: true,
  17563. [MessageStatus.SENDING]: true,
  17564. [MessageStatus.SENT]: true,
  17565. [MessageStatus.DELIVERED]: true,
  17566. [MessageStatus.READ]: true,
  17567. [MessageStatus.FAILED]: true
  17568. };
  17569. class Message {
  17570. /**
  17571. * @implements AVMessage
  17572. * @param {Object|String|ArrayBuffer} content 消息内容
  17573. */
  17574. constructor(content) {
  17575. Object.assign(this, {
  17576. content
  17577. }, {
  17578. /**
  17579. * @type {String}
  17580. * @memberof Message#
  17581. */
  17582. id: v4_1(),
  17583. /**
  17584. * 消息所在的 conversation id
  17585. * @memberof Message#
  17586. * @type {String?}
  17587. */
  17588. cid: null,
  17589. /**
  17590. * 消息发送时间
  17591. * @memberof Message#
  17592. * @type {Date}
  17593. */
  17594. timestamp: new Date(),
  17595. /**
  17596. * 消息发送者
  17597. * @memberof Message#
  17598. * @type {String}
  17599. */
  17600. from: undefined,
  17601. /**
  17602. * 消息提及的用户
  17603. * @since 4.0.0
  17604. * @memberof Message#
  17605. * @type {String[]}
  17606. */
  17607. mentionList: [],
  17608. /**
  17609. * 消息是否提及了所有人
  17610. * @since 4.0.0
  17611. * @memberof Message#
  17612. * @type {Boolean}
  17613. */
  17614. mentionedAll: false,
  17615. _mentioned: false
  17616. });
  17617. this._setStatus(MessageStatus.NONE);
  17618. }
  17619. /**
  17620. * 将当前消息的内容序列化为 JSON 对象
  17621. * @private
  17622. * @return {Object}
  17623. */
  17624. getPayload() {
  17625. return this.content;
  17626. }
  17627. _toJSON() {
  17628. const {
  17629. id,
  17630. cid,
  17631. from,
  17632. timestamp,
  17633. deliveredAt,
  17634. updatedAt,
  17635. mentionList,
  17636. mentionedAll,
  17637. mentioned
  17638. } = this;
  17639. return {
  17640. id,
  17641. cid,
  17642. from,
  17643. timestamp,
  17644. deliveredAt,
  17645. updatedAt,
  17646. mentionList,
  17647. mentionedAll,
  17648. mentioned
  17649. };
  17650. }
  17651. /**
  17652. * 返回 JSON 格式的消息
  17653. * @return {Object} 返回值是一个 plain Object
  17654. */
  17655. toJSON() {
  17656. return { ...this._toJSON(),
  17657. data: this.content
  17658. };
  17659. }
  17660. /**
  17661. * 返回 JSON 格式的消息,与 toJSON 不同的是,该对象包含了完整的信息,可以通过 {@link IMClient#parseMessage} 反序列化。
  17662. * @return {Object} 返回值是一个 plain Object
  17663. * @since 4.0.0
  17664. */
  17665. toFullJSON() {
  17666. const {
  17667. content,
  17668. id,
  17669. cid,
  17670. from,
  17671. timestamp,
  17672. deliveredAt,
  17673. _updatedAt,
  17674. mentionList,
  17675. mentionedAll
  17676. } = this;
  17677. return {
  17678. data: content,
  17679. id,
  17680. cid,
  17681. from,
  17682. timestamp: getTime(timestamp),
  17683. deliveredAt: getTime(deliveredAt),
  17684. updatedAt: getTime(_updatedAt),
  17685. mentionList,
  17686. mentionedAll
  17687. };
  17688. }
  17689. /**
  17690. * 消息状态,值为 {@link module:leancloud-realtime.MessageStatus} 之一
  17691. * @type {Symbol}
  17692. * @readonly
  17693. * @since 3.2.0
  17694. */
  17695. get status() {
  17696. return this._status;
  17697. }
  17698. _setStatus(status) {
  17699. if (!rMessageStatus[status]) {
  17700. throw new Error('Invalid message status');
  17701. }
  17702. this._status = status;
  17703. }
  17704. get timestamp() {
  17705. return this._timestamp;
  17706. }
  17707. set timestamp(value) {
  17708. this._timestamp = decodeDate(value);
  17709. }
  17710. /**
  17711. * 消息送达时间
  17712. * @type {?Date}
  17713. */
  17714. get deliveredAt() {
  17715. return this._deliveredAt;
  17716. }
  17717. set deliveredAt(value) {
  17718. this._deliveredAt = decodeDate(value);
  17719. }
  17720. /**
  17721. * 消息修改或撤回时间,可以通过比较其与消息的 timestamp 是否相等判断消息是否被修改过或撤回过。
  17722. * @type {Date}
  17723. * @since 3.5.0
  17724. */
  17725. get updatedAt() {
  17726. return this._updatedAt || this.timestamp;
  17727. }
  17728. set updatedAt(value) {
  17729. this._updatedAt = decodeDate(value);
  17730. }
  17731. /**
  17732. * 当前用户是否在该消息中被提及
  17733. * @type {Boolean}
  17734. * @readonly
  17735. * @since 4.0.0
  17736. */
  17737. get mentioned() {
  17738. return this._mentioned;
  17739. }
  17740. _updateMentioned(client) {
  17741. this._mentioned = this.from !== client && (this.mentionedAll || this.mentionList.indexOf(client) > -1);
  17742. }
  17743. /**
  17744. * 获取提及用户列表
  17745. * @since 4.0.0
  17746. * @return {String[]} 提及用户的 id 列表
  17747. */
  17748. getMentionList() {
  17749. return this.mentionList;
  17750. }
  17751. /**
  17752. * 设置提及用户列表
  17753. * @since 4.0.0
  17754. * @param {String[]} clients 提及用户的 id 列表
  17755. * @return {this} self
  17756. */
  17757. setMentionList(clients) {
  17758. this.mentionList = ensureArray(clients);
  17759. return this;
  17760. }
  17761. /**
  17762. * 设置是否提及所有人
  17763. * @since 4.0.0
  17764. * @param {Boolean} [value=true]
  17765. * @return {this} self
  17766. */
  17767. mentionAll(value = true) {
  17768. this.mentionedAll = Boolean(value);
  17769. return this;
  17770. }
  17771. /**
  17772. * 判断给定的内容是否是有效的 Message,
  17773. * 该方法始终返回 true
  17774. * @private
  17775. * @returns {Boolean}
  17776. * @implements AVMessage.validate
  17777. */
  17778. static validate() {
  17779. return true;
  17780. }
  17781. /**
  17782. * 解析处理消息内容
  17783. * <pre>
  17784. * 如果子类提供了 message,返回该 message
  17785. * 如果没有提供,将 json 作为 content 实例化一个 Message
  17786. * @private
  17787. * @param {Object} json json 格式的消息内容
  17788. * @param {Message} message 子类提供的 message
  17789. * @return {Message}
  17790. * @implements AVMessage.parse
  17791. */
  17792. static parse(json, message) {
  17793. return message || new this(json);
  17794. }
  17795. }
  17796. /* eslint-disable no-param-reassign */
  17797. const messageType = type => {
  17798. if (typeof type !== 'number') {
  17799. throw new TypeError(`${type} is not a Number`);
  17800. }
  17801. return target => {
  17802. target.TYPE = type;
  17803. target.validate = json => json._lctype === type;
  17804. target.prototype._getType = () => ({
  17805. _lctype: type
  17806. });
  17807. };
  17808. }; // documented in ../plugin-im.js
  17809. const messageField = fields => {
  17810. if (typeof fields !== 'string') {
  17811. if (!Array.isArray(fields)) {
  17812. throw new TypeError(`${fields} is not an Array`);
  17813. } else if (fields.some(value => typeof value !== 'string')) {
  17814. throw new TypeError('fields contains non-string typed member');
  17815. }
  17816. }
  17817. return target => {
  17818. // IE10 Hack:
  17819. // static properties in IE10 will not be inherited from super
  17820. // search for parse method and assign it manually
  17821. let originalCustomFields = isIE10 ? getStaticProperty(target, '_customFields') : target._customFields;
  17822. originalCustomFields = Array.isArray(originalCustomFields) ? originalCustomFields : [];
  17823. target._customFields = originalCustomFields.concat(fields);
  17824. };
  17825. }; // IE10 Hack:
  17826. // static properties in IE10 will not be inherited from super
  17827. // search for parse method and assign it manually
  17828. const IE10Compatible = target => {
  17829. if (isIE10) {
  17830. target.parse = getStaticProperty(target, 'parse');
  17831. }
  17832. };
  17833. var _dec, _class$1;
  17834. let // jsdoc-ignore-end
  17835. /**
  17836. * 所有内置的富媒体消息均继承自本类
  17837. * @extends Message
  17838. */
  17839. TypedMessage = (_dec = messageField(['_lctext', '_lcattrs']), _dec(_class$1 = class TypedMessage extends Message {
  17840. /**
  17841. * @type {Number}
  17842. * @readonly
  17843. */
  17844. get type() {
  17845. return this.constructor.TYPE;
  17846. }
  17847. /** @type {String} */
  17848. set text(text) {
  17849. return this.setText(text);
  17850. }
  17851. get text() {
  17852. return this.getText();
  17853. }
  17854. /** @type {Object} */
  17855. set attributes(attributes) {
  17856. return this.setAttributes(attributes);
  17857. }
  17858. get attributes() {
  17859. return this.getAttributes();
  17860. }
  17861. /**
  17862. * 在客户端需要以文本形式展示该消息时显示的文案,
  17863. * 如 <code>[红包] 新春快乐</code>。
  17864. * 默认值为消息的 text。
  17865. * @type {String}
  17866. * @readonly
  17867. */
  17868. get summary() {
  17869. return this.text;
  17870. }
  17871. /**
  17872. * @param {String} text
  17873. * @return {this} self
  17874. */
  17875. setText(text) {
  17876. this._lctext = text;
  17877. return this;
  17878. }
  17879. /**
  17880. * @return {String}
  17881. */
  17882. getText() {
  17883. return this._lctext;
  17884. }
  17885. /**
  17886. * @param {Object} attributes
  17887. * @return {this} self
  17888. */
  17889. setAttributes(attributes) {
  17890. this._lcattrs = attributes;
  17891. return this;
  17892. }
  17893. /**
  17894. * @return {Object}
  17895. */
  17896. getAttributes() {
  17897. return this._lcattrs;
  17898. }
  17899. _getCustomFields() {
  17900. const fields = Array.isArray(this.constructor._customFields) ? this.constructor._customFields : [];
  17901. return fields.reduce((result, field) => {
  17902. if (typeof field !== 'string') return result;
  17903. result[field] = this[field]; // eslint-disable-line no-param-reassign
  17904. return result;
  17905. }, {});
  17906. }
  17907. /* eslint-disable class-methods-use-this */
  17908. _getType() {
  17909. throw new Error('not implemented');
  17910. }
  17911. /* eslint-enable class-methods-use-this */
  17912. getPayload() {
  17913. return compact({
  17914. _lctext: this.getText(),
  17915. _lcattrs: this.getAttributes(),
  17916. ...this._getCustomFields(),
  17917. ...this._getType()
  17918. });
  17919. }
  17920. toJSON() {
  17921. const {
  17922. type,
  17923. text,
  17924. attributes,
  17925. summary
  17926. } = this;
  17927. return { ...super._toJSON(),
  17928. type,
  17929. text,
  17930. attributes,
  17931. summary
  17932. };
  17933. }
  17934. toFullJSON() {
  17935. return { ...super.toFullJSON(),
  17936. data: this.getPayload()
  17937. };
  17938. }
  17939. /**
  17940. * 解析处理消息内容
  17941. * <pre>
  17942. * 为给定的 message 设置 text 与 attributes 属性,返回该 message
  17943. * 如果子类没有提供 message,new this()
  17944. * @protected
  17945. * @param {Object} json json 格式的消息内容
  17946. * @param {TypedMessage} message 子类提供的 message
  17947. * @return {TypedMessage}
  17948. * @implements AVMessage.parse
  17949. */
  17950. static parse(json, message = new this()) {
  17951. message.content = json; // eslint-disable-line no-param-reassign
  17952. const customFields = isIE10 ? getStaticProperty(message.constructor, '_customFields') : message.constructor._customFields;
  17953. let fields = Array.isArray(customFields) ? customFields : [];
  17954. fields = fields.reduce((result, field) => {
  17955. if (typeof field !== 'string') return result;
  17956. result[field] = json[field]; // eslint-disable-line no-param-reassign
  17957. return result;
  17958. }, {});
  17959. Object.assign(message, fields);
  17960. return super.parse(json, message);
  17961. }
  17962. }) || _class$1);
  17963. var _dec$1, _class$2;
  17964. let // jsdoc-ignore-end
  17965. /**
  17966. * 已撤回类型消息,当消息被撤回时,SDK 会使用该类型的消息替代原始消息
  17967. * @extends TypedMessage
  17968. */
  17969. RecalledMessage = (_dec$1 = messageType(-127), _dec$1(_class$2 = IE10Compatible(_class$2 = class RecalledMessage extends TypedMessage {
  17970. /**
  17971. * 在客户端需要以文本形式展示该消息时显示的文案,值为 <code>[该消息已撤回]</code>
  17972. * @type {String}
  17973. * @readonly
  17974. */
  17975. // eslint-disable-next-line class-methods-use-this
  17976. get summary() {
  17977. return '[该消息已撤回]';
  17978. }
  17979. }) || _class$2) || _class$2);
  17980. /* eslint class-methods-use-this: ["error", { "exceptMethods": ["_addMembers", "_removeMembers"] }] */
  17981. const debug$7 = browser('LC:Conversation');
  17982. const serializeMessage = message => {
  17983. const content = message.getPayload();
  17984. let msg;
  17985. let binaryMsg;
  17986. if (content instanceof ArrayBuffer) {
  17987. binaryMsg = content;
  17988. } else if (typeof content !== 'string') {
  17989. msg = JSON.stringify(content);
  17990. } else {
  17991. msg = content;
  17992. }
  17993. return {
  17994. msg,
  17995. binaryMsg
  17996. };
  17997. };
  17998. const {
  17999. NEW,
  18000. OLD
  18001. } = LogsCommand.QueryDirection;
  18002. /**
  18003. * 历史消息查询方向枚举
  18004. * @enum {Number}
  18005. * @since 4.0.0
  18006. * @memberof module:leancloud-realtime
  18007. */
  18008. const MessageQueryDirection = {
  18009. /** 从后向前 */
  18010. NEW_TO_OLD: OLD,
  18011. /** 从前向后 */
  18012. OLD_TO_NEW: NEW
  18013. };
  18014. Object.freeze(MessageQueryDirection);
  18015. class ConversationBase extends eventemitter3 {
  18016. /**
  18017. * @extends EventEmitter
  18018. * @private
  18019. * @abstract
  18020. */
  18021. constructor({
  18022. id,
  18023. lastMessageAt,
  18024. lastMessage,
  18025. lastDeliveredAt,
  18026. lastReadAt,
  18027. unreadMessagesCount = 0,
  18028. members = [],
  18029. mentioned = false,
  18030. ...properties
  18031. }, client) {
  18032. super();
  18033. Object.assign(this, {
  18034. /**
  18035. * 对话 id,对应 _Conversation 表中的 objectId
  18036. * @memberof ConversationBase#
  18037. * @type {String}
  18038. */
  18039. id,
  18040. /**
  18041. * 最后一条消息时间
  18042. * @memberof ConversationBase#
  18043. * @type {?Date}
  18044. */
  18045. lastMessageAt,
  18046. /**
  18047. * 最后一条消息
  18048. * @memberof ConversationBase#
  18049. * @type {?Message}
  18050. */
  18051. lastMessage,
  18052. /**
  18053. * 参与该对话的用户列表
  18054. * @memberof ConversationBase#
  18055. * @type {String[]}
  18056. */
  18057. members,
  18058. // other properties provided by subclasses
  18059. ...properties
  18060. });
  18061. this.members = Array.from(new Set(this.members));
  18062. Object.assign(internal(this), {
  18063. messagesWaitingForReceipt: {},
  18064. lastDeliveredAt,
  18065. lastReadAt,
  18066. unreadMessagesCount,
  18067. mentioned
  18068. });
  18069. this._client = client;
  18070. if (debug$7.enabled) {
  18071. values_1(IMEvent).forEach(event => this.on(event, (...payload) => this._debug(`${event} event emitted. %o`, payload)));
  18072. } // onConversationCreate hook
  18073. applyDecorators(this._client._plugins.onConversationCreate, this);
  18074. }
  18075. /**
  18076. * 当前用户是否在该对话的未读消息中被提及
  18077. * @type {Boolean}
  18078. * @since 4.0.0
  18079. */
  18080. get unreadMessagesMentioned() {
  18081. return internal(this).unreadMessagesMentioned;
  18082. }
  18083. _setUnreadMessagesMentioned(value) {
  18084. internal(this).unreadMessagesMentioned = Boolean(value);
  18085. }
  18086. set unreadMessagesCount(value) {
  18087. if (value !== this.unreadMessagesCount) {
  18088. internal(this).unreadMessagesCount = value;
  18089. this._client.emit(UNREAD_MESSAGES_COUNT_UPDATE, [this]);
  18090. }
  18091. }
  18092. /**
  18093. * 当前用户在该对话的未读消息数
  18094. * @type {Number}
  18095. */
  18096. get unreadMessagesCount() {
  18097. return internal(this).unreadMessagesCount;
  18098. }
  18099. set lastMessageAt(value) {
  18100. const time = decodeDate(value);
  18101. if (time <= this._lastMessageAt) return;
  18102. this._lastMessageAt = time;
  18103. }
  18104. get lastMessageAt() {
  18105. return this._lastMessageAt;
  18106. }
  18107. /**
  18108. * 最后消息送达时间,常用来实现消息的「已送达」标记,可通过 {@link Conversation#fetchReceiptTimestamps} 获取或更新该属性
  18109. * @type {?Date}
  18110. * @since 3.4.0
  18111. */
  18112. get lastDeliveredAt() {
  18113. if (this.members.length !== 2) return null;
  18114. return internal(this).lastDeliveredAt;
  18115. }
  18116. _setLastDeliveredAt(value) {
  18117. const date = decodeDate(value);
  18118. if (!(date < internal(this).lastDeliveredAt)) {
  18119. internal(this).lastDeliveredAt = date;
  18120. /**
  18121. * 最后消息送达时间更新
  18122. * @event ConversationBase#LAST_DELIVERED_AT_UPDATE
  18123. * @since 3.4.0
  18124. */
  18125. this.emit(LAST_DELIVERED_AT_UPDATE);
  18126. }
  18127. }
  18128. /**
  18129. * 最后消息被阅读时间,常用来实现发送消息的「已读」标记,可通过 {@link Conversation#fetchReceiptTimestamps} 获取或更新该属性
  18130. * @type {?Date}
  18131. * @since 3.4.0
  18132. */
  18133. get lastReadAt() {
  18134. if (this.members.length !== 2) return null;
  18135. return internal(this).lastReadAt;
  18136. }
  18137. _setLastReadAt(value) {
  18138. const date = decodeDate(value);
  18139. if (!(date < internal(this).lastReadAt)) {
  18140. internal(this).lastReadAt = date;
  18141. /**
  18142. * 最后消息被阅读时间更新
  18143. * @event ConversationBase#LAST_READ_AT_UPDATE
  18144. * @since 3.4.0
  18145. */
  18146. this.emit(LAST_READ_AT_UPDATE);
  18147. }
  18148. }
  18149. /**
  18150. * 返回 JSON 格式的对话,与 toJSON 不同的是,该对象包含了完整的信息,可以通过 {@link IMClient#parseConversation} 反序列化。
  18151. * @return {Object} 返回值是一个 plain Object
  18152. * @since 4.0.0
  18153. */
  18154. toFullJSON() {
  18155. const {
  18156. id,
  18157. members,
  18158. lastMessageAt,
  18159. lastDeliveredAt,
  18160. lastReadAt,
  18161. lastMessage,
  18162. unreadMessagesCount
  18163. } = this;
  18164. return {
  18165. id,
  18166. members,
  18167. lastMessageAt: getTime(lastMessageAt),
  18168. lastDeliveredAt: getTime(lastDeliveredAt),
  18169. lastReadAt: getTime(lastReadAt),
  18170. lastMessage: lastMessage ? lastMessage.toFullJSON() : undefined,
  18171. unreadMessagesCount
  18172. };
  18173. }
  18174. /**
  18175. * 返回 JSON 格式的对话
  18176. * @return {Object} 返回值是一个 plain Object
  18177. * @since 4.0.0
  18178. */
  18179. toJSON() {
  18180. const {
  18181. id,
  18182. members,
  18183. lastMessageAt,
  18184. lastDeliveredAt,
  18185. lastReadAt,
  18186. lastMessage,
  18187. unreadMessagesCount,
  18188. unreadMessagesMentioned
  18189. } = this;
  18190. return {
  18191. id,
  18192. members,
  18193. lastMessageAt,
  18194. lastDeliveredAt,
  18195. lastReadAt,
  18196. lastMessage: lastMessage ? lastMessage.toJSON() : undefined,
  18197. unreadMessagesCount,
  18198. unreadMessagesMentioned
  18199. };
  18200. }
  18201. _debug(...params) {
  18202. debug$7(...params, `[${this.id}]`);
  18203. }
  18204. _send(command, ...args) {
  18205. /* eslint-disable no-param-reassign */
  18206. if (command.cmd === null) {
  18207. command.cmd = 'conv';
  18208. }
  18209. if (command.cmd === 'conv' && command.convMessage === null) {
  18210. command.convMessage = new ConvCommand();
  18211. }
  18212. if (command.convMessage && command.convMessage.cid === null) {
  18213. command.convMessage.cid = this.id;
  18214. }
  18215. /* eslint-enable no-param-reassign */
  18216. return this._client._send(command, ...args);
  18217. }
  18218. /**
  18219. * 发送消息
  18220. * @param {Message} message 消息,Message 及其子类的实例
  18221. * @param {Object} [options] since v3.3.0,发送选项
  18222. * @param {Boolean} [options.transient] since v3.3.1,是否作为暂态消息发送
  18223. * @param {Boolean} [options.receipt] 是否需要回执,仅在普通对话中有效
  18224. * @param {Boolean} [options.will] since v3.4.0,是否指定该消息作为「掉线消息」发送,
  18225. * 「掉线消息」会延迟到当前用户掉线后发送,常用来实现「下线通知」功能
  18226. * @param {MessagePriority} [options.priority] 消息优先级,仅在暂态对话中有效,
  18227. * see: {@link module:leancloud-realtime.MessagePriority MessagePriority}
  18228. * @param {Object} [options.pushData] 消息对应的离线推送内容,如果消息接收方不在线,会推送指定的内容。其结构说明参见: {@link https://url.leanapp.cn/pushData 推送消息内容}
  18229. * @return {Promise.<Message>} 发送的消息
  18230. */
  18231. async send(message, options) {
  18232. this._debug(message, 'send');
  18233. if (!(message instanceof Message)) {
  18234. throw new TypeError(`${message} is not a Message`);
  18235. }
  18236. const {
  18237. transient,
  18238. receipt,
  18239. priority,
  18240. pushData,
  18241. will
  18242. } = { // support Message static property: sendOptions
  18243. ...message.constructor.sendOptions,
  18244. // support Message static property: getSendOptions
  18245. ...(typeof message.constructor.getSendOptions === 'function' ? message.constructor.getSendOptions(message) : {}),
  18246. ...options
  18247. };
  18248. if (receipt) {
  18249. if (this.transient) {
  18250. console.warn('receipt option is ignored as the conversation is transient.');
  18251. } else if (transient) {
  18252. console.warn('receipt option is ignored as the message is sent transiently.');
  18253. } else if (this.members.length > 2) {
  18254. console.warn('receipt option is recommended to be used in one-on-one conversation.'); // eslint-disable-line max-len
  18255. }
  18256. }
  18257. if (priority && !this.transient) {
  18258. console.warn('priority option is ignored as the conversation is not transient.');
  18259. }
  18260. Object.assign(message, {
  18261. cid: this.id,
  18262. from: this._client.id
  18263. });
  18264. message._setStatus(MessageStatus.SENDING);
  18265. const {
  18266. msg,
  18267. binaryMsg
  18268. } = serializeMessage(message);
  18269. const command = new GenericCommand({
  18270. cmd: 'direct',
  18271. directMessage: new DirectCommand({
  18272. msg,
  18273. binaryMsg,
  18274. cid: this.id,
  18275. r: receipt,
  18276. transient,
  18277. dt: message.id,
  18278. pushData: JSON.stringify(pushData),
  18279. will,
  18280. mentionPids: message.mentionList,
  18281. mentionAll: message.mentionedAll
  18282. }),
  18283. priority
  18284. });
  18285. try {
  18286. const resCommand = await this._send(command);
  18287. const {
  18288. ackMessage: {
  18289. uid,
  18290. t,
  18291. code,
  18292. reason,
  18293. appCode
  18294. }
  18295. } = resCommand;
  18296. if (code !== null) {
  18297. throw createError({
  18298. code,
  18299. reason,
  18300. appCode
  18301. });
  18302. }
  18303. Object.assign(message, {
  18304. id: uid,
  18305. timestamp: t
  18306. });
  18307. if (!transient) {
  18308. this.lastMessage = message;
  18309. this.lastMessageAt = message.timestamp;
  18310. }
  18311. message._setStatus(MessageStatus.SENT);
  18312. if (receipt) {
  18313. internal(this).messagesWaitingForReceipt[message.id] = message;
  18314. }
  18315. return message;
  18316. } catch (error) {
  18317. message._setStatus(MessageStatus.FAILED);
  18318. throw error;
  18319. }
  18320. }
  18321. async _update(message, newMessage, recall) {
  18322. this._debug('patch %O %O %O', message, newMessage, recall);
  18323. if (message instanceof Message) {
  18324. if (message.from !== this._client.id) {
  18325. throw new Error('Updating message from others is not allowed');
  18326. }
  18327. if (message.status !== MessageStatus.SENT && message.status !== MessageStatus.DELIVERED) {
  18328. throw new Error('Message is not sent');
  18329. }
  18330. } else if (!(message.id && message.timestamp)) {
  18331. throw new TypeError(`${message} is not a Message`);
  18332. }
  18333. let msg;
  18334. let binaryMsg;
  18335. if (!recall) {
  18336. const content = serializeMessage(newMessage);
  18337. ({
  18338. msg,
  18339. binaryMsg
  18340. } = content);
  18341. }
  18342. await this._send(new GenericCommand({
  18343. cmd: CommandType.patch,
  18344. op: OpType.modify,
  18345. patchMessage: new PatchCommand({
  18346. patches: [new PatchItem({
  18347. cid: this.id,
  18348. mid: message.id,
  18349. timestamp: Number(message.timestamp),
  18350. recall,
  18351. data: msg,
  18352. binaryMsg,
  18353. mentionPids: newMessage.mentionList,
  18354. mentionAll: newMessage.mentionedAll
  18355. })],
  18356. lastPatchTime: this._client._lastPatchTime
  18357. })
  18358. }));
  18359. const {
  18360. id,
  18361. cid,
  18362. timestamp,
  18363. from,
  18364. _status
  18365. } = message;
  18366. Object.assign(newMessage, {
  18367. id,
  18368. cid,
  18369. timestamp,
  18370. from,
  18371. _status
  18372. });
  18373. if (this.lastMessage && this.lastMessage.id === newMessage.id) {
  18374. this.lastMessage = newMessage;
  18375. }
  18376. return newMessage;
  18377. }
  18378. /**
  18379. * 获取对话人数,或暂态对话的在线人数
  18380. * @return {Promise.<Number>}
  18381. */
  18382. async count() {
  18383. this._debug('count');
  18384. const resCommand = await this._send(new GenericCommand({
  18385. op: 'count'
  18386. }));
  18387. return resCommand.convMessage.count;
  18388. }
  18389. /**
  18390. * 应用增加成员的操作,产生副作用
  18391. * @param {string[]} members
  18392. * @abstract
  18393. * @private
  18394. */
  18395. _addMembers() {}
  18396. /**
  18397. * 应用减少成员的操作,产生副作用
  18398. * @param {string[]} members
  18399. * @abstract
  18400. * @private
  18401. */
  18402. _removeMembers() {}
  18403. /**
  18404. * 修改已发送的消息
  18405. * @param {AVMessage} message 要修改的消息,该消息必须是由当前用户发送的。也可以提供一个包含消息 {id, timestamp} 的对象
  18406. * @param {AVMessage} newMessage 新的消息
  18407. * @return {Promise.<AVMessage>} 更新后的消息
  18408. */
  18409. async update(message, newMessage) {
  18410. if (!(newMessage instanceof Message)) {
  18411. throw new TypeError(`${newMessage} is not a Message`);
  18412. }
  18413. return this._update(message, newMessage, false);
  18414. }
  18415. /**
  18416. * 撤回已发送的消息
  18417. * @param {AVMessage} message 要撤回的消息,该消息必须是由当前用户发送的。也可以提供一个包含消息 {id, timestamp} 的对象
  18418. * @return {Promise.<RecalledMessage>} 一条已撤回的消息
  18419. */
  18420. async recall(message) {
  18421. return this._update(message, new RecalledMessage(), true);
  18422. }
  18423. /**
  18424. * 查询消息记录
  18425. * 如果仅需实现消息向前记录翻页查询需求,建议使用 {@link Conversation#createMessagesIterator}。
  18426. * 不论何种方向,获得的消息都是按照时间升序排列的。
  18427. * startClosed 与 endClosed 用于指定查询区间的开闭。
  18428. *
  18429. * @param {Object} [options]
  18430. * @param {Number} [options.limit] 限制查询结果的数量,目前服务端默认为 20
  18431. * @param {Number} [options.type] 指定查询的富媒体消息类型,不指定则查询所有消息。
  18432. * @param {MessageQueryDirection} [options.direction] 查询的方向。
  18433. * 在不指定的情况下如果 startTime 大于 endTime,则为从新到旧查询,可以实现加载聊天记录等场景。
  18434. * 如果 startTime 小于 endTime,则为从旧到新查询,可以实现弹幕等场景。
  18435. * @param {Date} [options.startTime] 从该时间开始查询,不传则从当前时间开始查询
  18436. * @param {String} [options.startMessageId] 从该消息之前开始查询,需要与 startTime 同时使用,为防止某时刻有重复消息
  18437. * @param {Boolean}[options.startClosed] 指定查询范围是否包括开始的时间点,默认不包括
  18438. * @param {Date} [options.endTime] 查询到该时间为止,不传则查询最早消息为止
  18439. * @param {String} [options.endMessageId] 查询到该消息为止,需要与 endTime 同时使用,为防止某时刻有重复消息
  18440. * @param {Boolean}[options.endClosed] 指定查询范围是否包括结束的时间点,默认不包括
  18441. *
  18442. * @param {Date} [options.beforeTime] DEPRECATED: 使用 startTime 代替。限制查询结果为小于该时间之前的消息,不传则为当前时间
  18443. * @param {String} [options.beforeMessageId] DEPRECATED: 使用 startMessageId 代替。
  18444. * 限制查询结果为该消息之前的消息,需要与 beforeTime 同时使用,为防止某时刻有重复消息
  18445. * @param {Date} [options.afterTime] DEPRECATED: 使用 endTime 代替。限制查询结果为大于该时间之前的消息
  18446. * @param {String} [options.afterMessageId] DEPRECATED: 使用 endMessageId 代替。
  18447. * 限制查询结果为该消息之后的消息,需要与 afterTime 同时使用,为防止某时刻有重复消息
  18448. * @return {Promise.<Message[]>} 消息列表
  18449. */
  18450. async queryMessages(options = {}) {
  18451. this._debug('query messages %O', options);
  18452. const {
  18453. beforeTime,
  18454. beforeMessageId,
  18455. afterTime,
  18456. afterMessageId,
  18457. limit,
  18458. direction,
  18459. type,
  18460. startTime,
  18461. startMessageId,
  18462. startClosed,
  18463. endTime,
  18464. endMessageId,
  18465. endClosed
  18466. } = options;
  18467. if (beforeMessageId || beforeTime || afterMessageId || afterTime) {
  18468. console.warn('DEPRECATION: queryMessages options beforeTime, beforeMessageId, afterTime and afterMessageId are deprecated in favor of startTime, startMessageId, endTime and endMessageId.');
  18469. return this.queryMessages({
  18470. startTime: beforeTime,
  18471. startMessageId: beforeMessageId,
  18472. endTime: afterTime,
  18473. endMessageId: afterMessageId,
  18474. limit
  18475. });
  18476. }
  18477. if (startMessageId && !startTime) {
  18478. throw new Error('query option startMessageId must be used with option startTime');
  18479. }
  18480. if (endMessageId && !endTime) {
  18481. throw new Error('query option endMessageId must be used with option endTime');
  18482. }
  18483. const conditions = {
  18484. t: startTime,
  18485. mid: startMessageId,
  18486. tIncluded: startClosed,
  18487. tt: endTime,
  18488. tmid: endMessageId,
  18489. ttIncluded: endClosed,
  18490. l: limit,
  18491. lctype: type
  18492. };
  18493. if (conditions.t instanceof Date) {
  18494. conditions.t = conditions.t.getTime();
  18495. }
  18496. if (conditions.tt instanceof Date) {
  18497. conditions.tt = conditions.tt.getTime();
  18498. }
  18499. if (direction !== undefined) {
  18500. conditions.direction = direction;
  18501. } else if (conditions.tt > conditions.t) {
  18502. conditions.direction = MessageQueryDirection.OLD_TO_NEW;
  18503. }
  18504. const resCommand = await this._send(new GenericCommand({
  18505. cmd: 'logs',
  18506. logsMessage: new LogsCommand(Object.assign(conditions, {
  18507. cid: this.id
  18508. }))
  18509. }));
  18510. return Promise.all(resCommand.logsMessage.logs.map(async ({
  18511. msgId,
  18512. timestamp,
  18513. patchTimestamp,
  18514. from,
  18515. ackAt,
  18516. readAt,
  18517. data,
  18518. mentionAll,
  18519. mentionPids,
  18520. bin
  18521. }) => {
  18522. const messageData = {
  18523. data,
  18524. bin,
  18525. id: msgId,
  18526. cid: this.id,
  18527. timestamp,
  18528. from,
  18529. deliveredAt: ackAt,
  18530. updatedAt: patchTimestamp,
  18531. mentionList: mentionPids,
  18532. mentionedAll: mentionAll
  18533. };
  18534. const message = await this._client.parseMessage(messageData);
  18535. let status = MessageStatus.SENT;
  18536. if (this.members.length === 2) {
  18537. if (ackAt) status = MessageStatus.DELIVERED;
  18538. if (ackAt) this._setLastDeliveredAt(ackAt);
  18539. if (readAt) this._setLastReadAt(readAt);
  18540. }
  18541. message._setStatus(status);
  18542. return message;
  18543. }));
  18544. }
  18545. /**
  18546. * 获取消息翻页迭代器
  18547. * @param {Object} [options]
  18548. * @param {Date} [options.beforeTime] 限制起始查询结果为小于该时间之前的消息,不传则为当前时间
  18549. * @param {String} [options.beforeMessageId] 限制起始查询结果为该消息之前的消息,需要与 beforeTime 同时使用,为防止某时刻有重复消息
  18550. * @param {Number} [options.limit] 限制每页查询结果的数量,目前服务端默认为 20
  18551. * @return {AsyncIterater.<Promise.<IteratorResult<Message[]>>>} [AsyncIterator]{@link https://github.com/tc39/proposal-async-iteration},调用其 next 方法返回获取下一页消息的 Promise
  18552. * @example
  18553. * var messageIterator = conversation.createMessagesIterator({ limit: 10 });
  18554. * messageIterator.next().then(function(result) {
  18555. * // result: {
  18556. * // value: [message1, ..., message10],
  18557. * // done: false,
  18558. * // }
  18559. * });
  18560. * messageIterator.next().then(function(result) {
  18561. * // result: {
  18562. * // value: [message11, ..., message20],
  18563. * // done: false,
  18564. * // }
  18565. * });
  18566. * messageIterator.next().then(function(result) {
  18567. * // No more messages
  18568. * // result: { value: [], done: true }
  18569. * });
  18570. */
  18571. createMessagesIterator({
  18572. beforeTime,
  18573. beforeMessageId,
  18574. limit
  18575. } = {}) {
  18576. let promise;
  18577. return {
  18578. next: () => {
  18579. if (promise === undefined) {
  18580. // first call
  18581. promise = this.queryMessages({
  18582. limit,
  18583. startTime: beforeTime,
  18584. startMessageId: beforeMessageId
  18585. });
  18586. } else {
  18587. promise = promise.then(prevMessages => {
  18588. if (prevMessages.length === 0 || prevMessages.length < limit) {
  18589. // no more messages
  18590. return [];
  18591. }
  18592. return this.queryMessages({
  18593. startTime: prevMessages[0].timestamp,
  18594. startMessageId: prevMessages[0].id,
  18595. limit
  18596. });
  18597. });
  18598. }
  18599. return promise.then(value => ({
  18600. value: Array.from(value),
  18601. done: value.length === 0 || value.length < limit
  18602. }));
  18603. }
  18604. };
  18605. }
  18606. /**
  18607. * 将该会话标记为已读
  18608. * @return {Promise.<this>} self
  18609. */
  18610. async read() {
  18611. this.unreadMessagesCount = 0;
  18612. this._setUnreadMessagesMentioned(false); // 跳过暂态会话
  18613. if (this.transient) return this;
  18614. const client = this._client;
  18615. if (!internal(client).readConversationsBuffer) {
  18616. internal(client).readConversationsBuffer = new Set();
  18617. }
  18618. internal(client).readConversationsBuffer.add(this);
  18619. client._doSendRead();
  18620. return this;
  18621. }
  18622. _handleReceipt({
  18623. messageId,
  18624. timestamp,
  18625. read
  18626. }) {
  18627. if (read) {
  18628. this._setLastReadAt(timestamp);
  18629. } else {
  18630. this._setLastDeliveredAt(timestamp);
  18631. }
  18632. const {
  18633. messagesWaitingForReceipt
  18634. } = internal(this);
  18635. const message = messagesWaitingForReceipt[messageId];
  18636. if (!message) return;
  18637. message._setStatus(MessageStatus.DELIVERED);
  18638. message.deliveredAt = timestamp;
  18639. delete messagesWaitingForReceipt[messageId];
  18640. }
  18641. /**
  18642. * 更新对话的最新回执时间戳(lastDeliveredAt、lastReadAt)
  18643. * @since 3.4.0
  18644. * @return {Promise.<this>} this
  18645. */
  18646. async fetchReceiptTimestamps() {
  18647. // 暂态/系统会话不支持回执
  18648. if (this.transient || this.system) return this;
  18649. const {
  18650. convMessage: {
  18651. maxReadTimestamp,
  18652. maxAckTimestamp
  18653. }
  18654. } = await this._send(new GenericCommand({
  18655. op: 'max_read'
  18656. }));
  18657. this._setLastDeliveredAt(maxAckTimestamp);
  18658. this._setLastReadAt(maxReadTimestamp);
  18659. return this;
  18660. }
  18661. _fetchAllReceiptTimestamps() {
  18662. // 暂态/系统会话不支持回执
  18663. if (this.transient || this.system) return this;
  18664. const convMessage = new ConvCommand({
  18665. queryAllMembers: true
  18666. });
  18667. return this._send(new GenericCommand({
  18668. op: 'max_read',
  18669. convMessage
  18670. })).then(({
  18671. convMessage: {
  18672. maxReadTuples
  18673. }
  18674. }) => maxReadTuples.filter(maxReadTuple => maxReadTuple.maxAckTimestamp || maxReadTuple.maxReadTimestamp).map(({
  18675. pid,
  18676. maxAckTimestamp,
  18677. maxReadTimestamp
  18678. }) => ({
  18679. pid,
  18680. lastDeliveredAt: decodeDate(maxAckTimestamp),
  18681. lastReadAt: decodeDate(maxReadTimestamp)
  18682. })));
  18683. }
  18684. }
  18685. const debug$8 = browser('LC:SignatureFactoryRunner');
  18686. function _validateSignature(signatureResult = {}) {
  18687. const {
  18688. signature,
  18689. timestamp,
  18690. nonce
  18691. } = signatureResult;
  18692. if (typeof signature !== 'string' || typeof timestamp !== 'number' || typeof nonce !== 'string') {
  18693. throw new Error('malformed signature');
  18694. }
  18695. return {
  18696. signature,
  18697. timestamp,
  18698. nonce
  18699. };
  18700. }
  18701. var runSignatureFactory = ((signatureFactory, params) => Promise.resolve().then(() => {
  18702. debug$8('call signatureFactory with %O', params);
  18703. return signatureFactory(...params);
  18704. }).then(tap(signatureResult => debug$8('sign result %O', signatureResult)), error => {
  18705. // eslint-disable-next-line no-param-reassign
  18706. error.message = `sign error: ${error.message}`;
  18707. debug$8(error);
  18708. throw error;
  18709. }).then(_validateSignature));
  18710. /**
  18711. * 部分失败异常
  18712. * @typedef OperationFailureError
  18713. * @type {Error}
  18714. * @property {string} message 异常信息
  18715. * @property {string[]} clientIds 因为该原因失败的 client id 列表
  18716. * @property {number} [code] 错误码
  18717. * @property {string} [detail] 详细信息
  18718. */
  18719. /**
  18720. * 部分成功的结果
  18721. * @typedef PartiallySuccess
  18722. * @type {Object}
  18723. * @property {string[]} successfulClientIds 成功的 client id 列表
  18724. * @property {OperationFailureError[]} failures 失败的异常列表
  18725. */
  18726. /**
  18727. * 分页查询结果
  18728. * @typedef PagedResults
  18729. * @type {Object}
  18730. * @property {T[]} results 查询结果
  18731. * @property {string} [next] 存在表示还有更多结果,在下次查询中带上可实现翻页。
  18732. */
  18733. const createPartiallySuccess = ({
  18734. allowedPids,
  18735. failedPids
  18736. }) => ({
  18737. successfulClientIds: allowedPids,
  18738. failures: failedPids.map(({
  18739. pids,
  18740. ...error
  18741. }) => Object.assign(createError(error), {
  18742. clientIds: pids
  18743. }))
  18744. });
  18745. /**
  18746. * @extends ConversationBase
  18747. * @private
  18748. * @abstract
  18749. */
  18750. class PersistentConversation extends ConversationBase {
  18751. constructor(data, {
  18752. creator,
  18753. createdAt,
  18754. updatedAt,
  18755. transient = false,
  18756. system = false,
  18757. muted = false,
  18758. mutedMembers = [],
  18759. ...attributes
  18760. }, client) {
  18761. super({ ...data,
  18762. /**
  18763. * 对话创建者
  18764. * @memberof PersistentConversation#
  18765. * @type {String}
  18766. */
  18767. creator,
  18768. /**
  18769. * 对话创建时间
  18770. * @memberof PersistentConversation#
  18771. * @type {Date}
  18772. */
  18773. createdAt,
  18774. /**
  18775. * 对话更新时间
  18776. * @memberof PersistentConversation#
  18777. * @type {Date}
  18778. */
  18779. updatedAt,
  18780. /**
  18781. * 对该对话设置了静音的用户列表
  18782. * @memberof PersistentConversation#
  18783. * @type {?String[]}
  18784. */
  18785. mutedMembers,
  18786. /**
  18787. * 暂态对话标记
  18788. * @memberof PersistentConversation#
  18789. * @type {Boolean}
  18790. */
  18791. transient,
  18792. /**
  18793. * 系统对话标记
  18794. * @memberof PersistentConversation#
  18795. * @type {Boolean}
  18796. * @since 3.3.0
  18797. */
  18798. system,
  18799. /**
  18800. * 当前用户静音该对话标记
  18801. * @memberof PersistentConversation#
  18802. * @type {Boolean}
  18803. */
  18804. muted,
  18805. _attributes: attributes
  18806. }, client);
  18807. this._reset();
  18808. }
  18809. set createdAt(value) {
  18810. this._createdAt = decodeDate(value);
  18811. }
  18812. get createdAt() {
  18813. return this._createdAt;
  18814. }
  18815. set updatedAt(value) {
  18816. this._updatedAt = decodeDate(value);
  18817. }
  18818. get updatedAt() {
  18819. return this._updatedAt;
  18820. }
  18821. /**
  18822. * 对话名字,对应 _Conversation 表中的 name
  18823. * @type {String}
  18824. */
  18825. get name() {
  18826. return this.get('name');
  18827. }
  18828. set name(value) {
  18829. this.set('name', value);
  18830. }
  18831. /**
  18832. * 获取对话的自定义属性
  18833. * @since 3.2.0
  18834. * @param {String} key key 属性的键名,'x' 对应 Conversation 表中的 x 列
  18835. * @return {Any} 属性的值
  18836. */
  18837. get(key) {
  18838. return get_1(internal(this).currentAttributes, key);
  18839. }
  18840. /**
  18841. * 设置对话的自定义属性
  18842. * @since 3.2.0
  18843. * @param {String} key 属性的键名,'x' 对应 Conversation 表中的 x 列,支持使用 'x.y.z' 来修改对象的部分字段。
  18844. * @param {Any} value 属性的值
  18845. * @return {this} self
  18846. * @example
  18847. *
  18848. * // 设置对话的 color 属性
  18849. * conversation.set('color', {
  18850. * text: '#000',
  18851. * background: '#DDD',
  18852. * });
  18853. * // 设置对话的 color.text 属性
  18854. * conversation.set('color.text', '#333');
  18855. */
  18856. set(key, value) {
  18857. this._debug(`set [${key}]: ${value}`);
  18858. const {
  18859. pendingAttributes
  18860. } = internal(this);
  18861. const pendingKeys = Object.keys(pendingAttributes); // suppose pendingAttributes = { 'a.b': {} }
  18862. // set 'a' or 'a.b': delete 'a.b'
  18863. const re = new RegExp(`^${key}`);
  18864. const childKeys = pendingKeys.filter(re.test.bind(re));
  18865. childKeys.forEach(k => {
  18866. delete pendingAttributes[k];
  18867. });
  18868. if (childKeys.length) {
  18869. pendingAttributes[key] = value;
  18870. } else {
  18871. // set 'a.c': nothing to do
  18872. // set 'a.b.c.d': assign c: { d: {} } to 'a.b'
  18873. const parentKey = find_1(pendingKeys, k => key.indexOf(k) === 0); // 'a.b'
  18874. if (parentKey) {
  18875. setValue(pendingAttributes[parentKey], key.slice(parentKey.length + 1), value);
  18876. } else {
  18877. pendingAttributes[key] = value;
  18878. }
  18879. }
  18880. this._buildCurrentAttributes();
  18881. return this;
  18882. }
  18883. _buildCurrentAttributes() {
  18884. const {
  18885. pendingAttributes
  18886. } = internal(this);
  18887. internal(this).currentAttributes = Object.keys(pendingAttributes).reduce((target, k) => setValue(target, k, pendingAttributes[k]), cloneDeep_1(this._attributes));
  18888. }
  18889. _updateServerAttributes(attributes) {
  18890. Object.keys(attributes).forEach(key => setValue(this._attributes, key, attributes[key]));
  18891. this._buildCurrentAttributes();
  18892. }
  18893. _reset() {
  18894. Object.assign(internal(this), {
  18895. pendingAttributes: {},
  18896. currentAttributes: this._attributes
  18897. });
  18898. }
  18899. /**
  18900. * 保存当前对话的属性至服务器
  18901. * @return {Promise.<this>} self
  18902. */
  18903. async save() {
  18904. this._debug('save');
  18905. const attr = internal(this).pendingAttributes;
  18906. if (isEmpty_1(attr)) {
  18907. this._debug('nothing touched, resolve with self');
  18908. return this;
  18909. }
  18910. this._debug('attr: %O', attr);
  18911. const convMessage = new ConvCommand({
  18912. attr: new JsonObjectMessage({
  18913. data: JSON.stringify(encode(attr))
  18914. })
  18915. });
  18916. const resCommand = await this._send(new GenericCommand({
  18917. op: 'update',
  18918. convMessage
  18919. }));
  18920. this.updatedAt = resCommand.convMessage.udate;
  18921. this._attributes = internal(this).currentAttributes;
  18922. internal(this).pendingAttributes = {};
  18923. return this;
  18924. }
  18925. /**
  18926. * 从服务器更新对话的属性
  18927. * @return {Promise.<this>} self
  18928. */
  18929. async fetch() {
  18930. const query = this._client.getQuery().equalTo('objectId', this.id);
  18931. await query.find();
  18932. return this;
  18933. }
  18934. /**
  18935. * 静音,客户端拒绝收到服务器端的离线推送通知
  18936. * @return {Promise.<this>} self
  18937. */
  18938. async mute() {
  18939. this._debug('mute');
  18940. await this._send(new GenericCommand({
  18941. op: 'mute'
  18942. }));
  18943. if (!this.transient) {
  18944. this.muted = true;
  18945. this.mutedMembers = union(this.mutedMembers, [this._client.id]);
  18946. }
  18947. return this;
  18948. }
  18949. /**
  18950. * 取消静音
  18951. * @return {Promise.<this>} self
  18952. */
  18953. async unmute() {
  18954. this._debug('unmute');
  18955. await this._send(new GenericCommand({
  18956. op: 'unmute'
  18957. }));
  18958. if (!this.transient) {
  18959. this.muted = false;
  18960. this.mutedMembers = difference(this.mutedMembers, [this._client.id]);
  18961. }
  18962. return this;
  18963. }
  18964. async _appendConversationSignature(command, action, clientIds) {
  18965. if (this._client.options.conversationSignatureFactory) {
  18966. const params = [this.id, this._client.id, clientIds.sort(), action];
  18967. const signatureResult = await runSignatureFactory(this._client.options.conversationSignatureFactory, params);
  18968. Object.assign(command.convMessage, keyRemap({
  18969. signature: 's',
  18970. timestamp: 't',
  18971. nonce: 'n'
  18972. }, signatureResult));
  18973. }
  18974. }
  18975. async _appendBlacklistSignature(command, action, clientIds) {
  18976. if (this._client.options.blacklistSignatureFactory) {
  18977. const params = [this.id, this._client.id, clientIds.sort(), action];
  18978. const signatureResult = await runSignatureFactory(this._client.options.blacklistSignatureFactory, params);
  18979. Object.assign(command.blacklistMessage, keyRemap({
  18980. signature: 's',
  18981. timestamp: 't',
  18982. nonce: 'n'
  18983. }, signatureResult));
  18984. }
  18985. }
  18986. /**
  18987. * 增加成员
  18988. * @param {String|String[]} clientIds 新增成员 client id
  18989. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  18990. */
  18991. async add(clientIds) {
  18992. this._debug('add', clientIds);
  18993. if (typeof clientIds === 'string') {
  18994. clientIds = [clientIds]; // eslint-disable-line no-param-reassign
  18995. }
  18996. const command = new GenericCommand({
  18997. op: 'add',
  18998. convMessage: new ConvCommand({
  18999. m: clientIds
  19000. })
  19001. });
  19002. await this._appendConversationSignature(command, 'invite', clientIds);
  19003. const {
  19004. convMessage,
  19005. convMessage: {
  19006. allowedPids
  19007. }
  19008. } = await this._send(command);
  19009. this._addMembers(allowedPids);
  19010. return createPartiallySuccess(convMessage);
  19011. }
  19012. /**
  19013. * 剔除成员
  19014. * @param {String|String[]} clientIds 成员 client id
  19015. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  19016. */
  19017. async remove(clientIds) {
  19018. this._debug('remove', clientIds);
  19019. if (typeof clientIds === 'string') {
  19020. clientIds = [clientIds]; // eslint-disable-line no-param-reassign
  19021. }
  19022. const command = new GenericCommand({
  19023. op: 'remove',
  19024. convMessage: new ConvCommand({
  19025. m: clientIds
  19026. })
  19027. });
  19028. await this._appendConversationSignature(command, 'kick', clientIds);
  19029. const {
  19030. convMessage,
  19031. convMessage: {
  19032. allowedPids
  19033. }
  19034. } = await this._send(command);
  19035. this._removeMembers(allowedPids);
  19036. return createPartiallySuccess(convMessage);
  19037. }
  19038. /**
  19039. * (当前用户)加入该对话
  19040. * @return {Promise.<this>} self
  19041. */
  19042. async join() {
  19043. this._debug('join');
  19044. return this.add(this._client.id).then(({
  19045. failures
  19046. }) => {
  19047. if (failures[0]) throw failures[0];
  19048. return this;
  19049. });
  19050. }
  19051. /**
  19052. * (当前用户)退出该对话
  19053. * @return {Promise.<this>} self
  19054. */
  19055. async quit() {
  19056. this._debug('quit');
  19057. return this.remove(this._client.id).then(({
  19058. failures
  19059. }) => {
  19060. if (failures[0]) throw failures[0];
  19061. return this;
  19062. });
  19063. }
  19064. /**
  19065. * 在该对话中禁言成员
  19066. * @param {String|String[]} clientIds 成员 client id
  19067. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  19068. */
  19069. async muteMembers(clientIds) {
  19070. this._debug('mute', clientIds);
  19071. clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
  19072. const command = new GenericCommand({
  19073. op: OpType.add_shutup,
  19074. convMessage: new ConvCommand({
  19075. m: clientIds
  19076. })
  19077. });
  19078. const {
  19079. convMessage
  19080. } = await this._send(command);
  19081. return createPartiallySuccess(convMessage);
  19082. }
  19083. /**
  19084. * 在该对话中解除成员禁言
  19085. * @param {String|String[]} clientIds 成员 client id
  19086. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  19087. */
  19088. async unmuteMembers(clientIds) {
  19089. this._debug('unmute', clientIds);
  19090. clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
  19091. const command = new GenericCommand({
  19092. op: OpType.remove_shutup,
  19093. convMessage: new ConvCommand({
  19094. m: clientIds
  19095. })
  19096. });
  19097. const {
  19098. convMessage
  19099. } = await this._send(command);
  19100. return createPartiallySuccess(convMessage);
  19101. }
  19102. /**
  19103. * 查询该对话禁言成员列表
  19104. * @param {Object} [options]
  19105. * @param {Number} [options.limit] 返回的成员数量,服务器默认值 10
  19106. * @param {String} [options.next] 从指定 next 开始查询,与 limit 一起使用可以完成翻页。
  19107. * @return {PagedResults.<string>} 查询结果。其中的 cureser 存在表示还有更多结果。
  19108. */
  19109. async queryMutedMembers({
  19110. limit,
  19111. next
  19112. } = {}) {
  19113. this._debug('query muted: limit %O, next: %O', limit, next);
  19114. const command = new GenericCommand({
  19115. op: OpType.query_shutup,
  19116. convMessage: new ConvCommand({
  19117. limit,
  19118. next
  19119. })
  19120. });
  19121. const {
  19122. convMessage: {
  19123. m,
  19124. next: newNext
  19125. }
  19126. } = await this._send(command);
  19127. return {
  19128. results: m,
  19129. next: newNext
  19130. };
  19131. }
  19132. /**
  19133. * 将用户加入该对话黑名单
  19134. * @param {String|String[]} clientIds 成员 client id
  19135. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  19136. */
  19137. async blockMembers(clientIds) {
  19138. this._debug('block', clientIds);
  19139. clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
  19140. const command = new GenericCommand({
  19141. cmd: 'blacklist',
  19142. op: OpType.block,
  19143. blacklistMessage: new BlacklistCommand({
  19144. srcCid: this.id,
  19145. toPids: clientIds
  19146. })
  19147. });
  19148. await this._appendBlacklistSignature(command, 'conversation-block-clients', clientIds);
  19149. const {
  19150. blacklistMessage
  19151. } = await this._send(command);
  19152. return createPartiallySuccess(blacklistMessage);
  19153. }
  19154. /**
  19155. * 将用户移出该对话黑名单
  19156. * @param {String|String[]} clientIds 成员 client id
  19157. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  19158. */
  19159. async unblockMembers(clientIds) {
  19160. this._debug('unblock', clientIds);
  19161. clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
  19162. const command = new GenericCommand({
  19163. cmd: 'blacklist',
  19164. op: OpType.unblock,
  19165. blacklistMessage: new BlacklistCommand({
  19166. srcCid: this.id,
  19167. toPids: clientIds
  19168. })
  19169. });
  19170. await this._appendBlacklistSignature(command, 'conversation-unblock-clients', clientIds);
  19171. const {
  19172. blacklistMessage
  19173. } = await this._send(command);
  19174. return createPartiallySuccess(blacklistMessage);
  19175. }
  19176. /**
  19177. * 查询该对话黑名单
  19178. * @param {Object} [options]
  19179. * @param {Number} [options.limit] 返回的成员数量,服务器默认值 10
  19180. * @param {String} [options.next] 从指定 next 开始查询,与 limit 一起使用可以完成翻页
  19181. * @return {PagedResults.<string>} 查询结果。其中的 cureser 存在表示还有更多结果。
  19182. */
  19183. async queryBlockedMembers({
  19184. limit,
  19185. next
  19186. } = {}) {
  19187. this._debug('query blocked: limit %O, next: %O', limit, next);
  19188. const command = new GenericCommand({
  19189. cmd: 'blacklist',
  19190. op: OpType.query,
  19191. blacklistMessage: new BlacklistCommand({
  19192. srcCid: this.id,
  19193. limit,
  19194. next
  19195. })
  19196. });
  19197. const {
  19198. blacklistMessage: {
  19199. blockedPids,
  19200. next: newNext
  19201. }
  19202. } = await this._send(command);
  19203. return {
  19204. results: blockedPids,
  19205. next: newNext
  19206. };
  19207. }
  19208. toFullJSON() {
  19209. const {
  19210. creator,
  19211. system,
  19212. transient,
  19213. createdAt,
  19214. updatedAt,
  19215. _attributes
  19216. } = this;
  19217. return { ...super.toFullJSON(),
  19218. creator,
  19219. system,
  19220. transient,
  19221. createdAt: getTime(createdAt),
  19222. updatedAt: getTime(updatedAt),
  19223. ..._attributes
  19224. };
  19225. }
  19226. toJSON() {
  19227. const {
  19228. creator,
  19229. system,
  19230. transient,
  19231. muted,
  19232. mutedMembers,
  19233. createdAt,
  19234. updatedAt,
  19235. _attributes
  19236. } = this;
  19237. return { ...super.toJSON(),
  19238. creator,
  19239. system,
  19240. transient,
  19241. muted,
  19242. mutedMembers,
  19243. createdAt,
  19244. updatedAt,
  19245. ..._attributes
  19246. };
  19247. }
  19248. }
  19249. /**
  19250. * 对话成员角色枚举
  19251. * @enum {String}
  19252. * @since 4.0.0
  19253. * @memberof module:leancloud-realtime
  19254. */
  19255. const ConversationMemberRole = {
  19256. /** 所有者 */
  19257. OWNER: 'Owner',
  19258. /** 管理员 */
  19259. MANAGER: 'Manager',
  19260. /** 成员 */
  19261. MEMBER: 'Member'
  19262. };
  19263. Object.freeze(ConversationMemberRole);
  19264. class ConversationMemberInfo {
  19265. /**
  19266. * 对话成员属性,保存了成员与某个对话相关的属性,对应 _ConversationMemberInfo 表
  19267. * @since 4.0.0
  19268. */
  19269. constructor({
  19270. conversation,
  19271. memberId,
  19272. role
  19273. }) {
  19274. if (!conversation) throw new Error('conversation requried');
  19275. if (!memberId) throw new Error('memberId requried');
  19276. Object.assign(internal(this), {
  19277. conversation,
  19278. memberId,
  19279. role
  19280. });
  19281. }
  19282. /**
  19283. * 对话 Id
  19284. * @type {String}
  19285. * @readonly
  19286. */
  19287. get conversationId() {
  19288. return internal(this).conversation.id;
  19289. }
  19290. /**
  19291. * 成员 Id
  19292. * @type {String}
  19293. * @readonly
  19294. */
  19295. get memberId() {
  19296. return internal(this).memberId;
  19297. }
  19298. /**
  19299. * 角色
  19300. * @type {module:leancloud-realtime.ConversationMemberRole | String}
  19301. * @readonly
  19302. */
  19303. get role() {
  19304. if (this.isOwner) return ConversationMemberRole.OWNER;
  19305. return internal(this).role;
  19306. }
  19307. /**
  19308. * 是否是管理员
  19309. * @type {Boolean}
  19310. * @readonly
  19311. */
  19312. get isOwner() {
  19313. return this.memberId === internal(this).conversation.creator;
  19314. }
  19315. toJSON() {
  19316. const {
  19317. conversationId,
  19318. memberId,
  19319. role,
  19320. isOwner
  19321. } = this;
  19322. return {
  19323. conversationId,
  19324. memberId,
  19325. role,
  19326. isOwner
  19327. };
  19328. }
  19329. }
  19330. /**
  19331. * 普通对话
  19332. *
  19333. * 无法直接实例化,请使用 {@link IMClient#createConversation} 创建新的普通对话。
  19334. * @extends PersistentConversation
  19335. * @public
  19336. */
  19337. class Conversation extends PersistentConversation {
  19338. _addMembers(members) {
  19339. super._addMembers(members);
  19340. this.members = union(this.members, members);
  19341. const {
  19342. memberInfoMap
  19343. } = internal(this);
  19344. if (!memberInfoMap) return;
  19345. members.forEach(memberId => {
  19346. memberInfoMap[memberId] = memberInfoMap[memberId] || new ConversationMemberInfo({
  19347. conversation: this,
  19348. memberId,
  19349. role: ConversationMemberRole.MEMBER
  19350. });
  19351. });
  19352. }
  19353. _removeMembers(members) {
  19354. super._removeMembers(members);
  19355. this.members = difference(this.members, members);
  19356. const {
  19357. memberInfoMap
  19358. } = internal(this);
  19359. if (!memberInfoMap) return;
  19360. members.forEach(memberId => {
  19361. delete memberInfoMap[memberId];
  19362. });
  19363. }
  19364. async _fetchAllMemberInfo() {
  19365. const response = await this._client._requestWithSessionToken({
  19366. method: 'GET',
  19367. path: '/classes/_ConversationMemberInfo',
  19368. query: {
  19369. where: {
  19370. cid: this.id
  19371. }
  19372. }
  19373. });
  19374. const memberInfos = response.results.map(info => new ConversationMemberInfo({
  19375. conversation: this,
  19376. memberId: info.clientId,
  19377. role: info.role
  19378. }));
  19379. const memberInfoMap = {};
  19380. memberInfos.forEach(memberInfo => {
  19381. memberInfoMap[memberInfo.memberId] = memberInfo;
  19382. });
  19383. this.members.forEach(memberId => {
  19384. memberInfoMap[memberId] = memberInfoMap[memberId] || new ConversationMemberInfo({
  19385. conversation: this,
  19386. memberId,
  19387. role: ConversationMemberRole.MEMBER
  19388. });
  19389. });
  19390. internal(this).memberInfoMap = memberInfoMap;
  19391. return memberInfoMap;
  19392. }
  19393. /**
  19394. * 获取所有成员的对话属性
  19395. * @since 4.0.0
  19396. * @return {Promise.<ConversationMemberInfo[]>} 所有成员的对话属性列表
  19397. */
  19398. async getAllMemberInfo({
  19399. noCache = false
  19400. } = {}) {
  19401. let {
  19402. memberInfoMap
  19403. } = internal(this);
  19404. if (!memberInfoMap || noCache) {
  19405. memberInfoMap = await this._fetchAllMemberInfo();
  19406. }
  19407. return this.members.map(memberId => memberInfoMap[memberId]);
  19408. }
  19409. /**
  19410. * 获取指定成员的对话属性
  19411. * @since 4.0.0
  19412. * @param {String} memberId 成员 Id
  19413. * @return {Promise.<ConversationMemberInfo>} 指定成员的对话属性
  19414. */
  19415. async getMemberInfo(memberId) {
  19416. if (this.members.indexOf(memberId) === -1) throw new Error(`${memberId} is not the mumber of conversation[${this.id}]`);
  19417. const {
  19418. memberInfoMap
  19419. } = internal(this);
  19420. if (!(memberInfoMap && memberInfoMap[memberId])) await this.getAllMemberInfo();
  19421. return internal(this).memberInfoMap[memberId];
  19422. }
  19423. /**
  19424. * 更新指定用户的角色
  19425. * @since 4.0.0
  19426. * @param {String} memberId 成员 Id
  19427. * @param {module:leancloud-realtime.ConversationMemberRole | String} role 角色
  19428. * @return {Promise.<this>} self
  19429. */
  19430. async updateMemberRole(memberId, role) {
  19431. this._debug('update member role');
  19432. if (role === ConversationMemberRole.OWNER) throw createError({
  19433. code: ErrorCode.OWNER_PROMOTION_NOT_ALLOWED
  19434. });
  19435. await this._send(new GenericCommand({
  19436. op: OpType.member_info_update,
  19437. convMessage: new ConvCommand({
  19438. targetClientId: memberId,
  19439. info: new ConvMemberInfo({
  19440. pid: memberId,
  19441. role
  19442. })
  19443. })
  19444. }));
  19445. const {
  19446. memberInfos
  19447. } = internal(this);
  19448. if (memberInfos && memberInfos[memberId]) {
  19449. internal(memberInfos[memberId]).role = role;
  19450. }
  19451. return this;
  19452. }
  19453. }
  19454. /**
  19455. * 聊天室。
  19456. *
  19457. * 无法直接实例化,请使用 {@link IMClient#createChatRoom} 创建新的聊天室。
  19458. * @since 4.0.0
  19459. * @extends PersistentConversation
  19460. * @public
  19461. */
  19462. class ChatRoom extends PersistentConversation {}
  19463. /**
  19464. * 服务号。
  19465. *
  19466. * 服务号不支持在客户端创建。
  19467. * @since 4.0.0
  19468. * @extends PersistentConversation
  19469. * @public
  19470. */
  19471. class ServiceConversation extends PersistentConversation {
  19472. /**
  19473. * 订阅该服务号
  19474. * @return {Promise.<this>} self
  19475. */
  19476. async subscribe() {
  19477. return this.join();
  19478. }
  19479. /**
  19480. * 退订该服务号
  19481. * @return {Promise.<this>} self
  19482. */
  19483. async unsubscribe() {
  19484. return this.quit();
  19485. }
  19486. }
  19487. const transformNotFoundError = error => error.code === ErrorCode.CONVERSATION_NOT_FOUND ? createError({
  19488. code: ErrorCode.TEMPORARY_CONVERSATION_EXPIRED
  19489. }) : error;
  19490. /**
  19491. * 临时对话
  19492. * @since 4.0.0
  19493. * @extends ConversationBase
  19494. * @public
  19495. */
  19496. class TemporaryConversation extends ConversationBase {
  19497. /**
  19498. * 无法直接实例化,请使用 {@link IMClient#createTemporaryConversation} 创建新的临时对话。
  19499. */
  19500. constructor(data, {
  19501. expiredAt
  19502. }, client) {
  19503. super({ ...data,
  19504. expiredAt
  19505. }, client);
  19506. }
  19507. /**
  19508. * 对话失效时间
  19509. * @type {Date}
  19510. */
  19511. set expiredAt(value) {
  19512. this._expiredAt = decodeDate(value);
  19513. }
  19514. get expiredAt() {
  19515. return this._expiredAt;
  19516. }
  19517. /**
  19518. * 对话是否已失效
  19519. * @type {Boolean}
  19520. */
  19521. get expired() {
  19522. return this.expiredAt < new Date();
  19523. }
  19524. async _send(...args) {
  19525. if (this.expired) throw createError({
  19526. code: ErrorCode.TEMPORARY_CONVERSATION_EXPIRED
  19527. });
  19528. try {
  19529. return await super._send(...args);
  19530. } catch (error) {
  19531. throw transformNotFoundError(error);
  19532. }
  19533. }
  19534. async send(...args) {
  19535. try {
  19536. return await super.send(...args);
  19537. } catch (error) {
  19538. throw transformNotFoundError(error);
  19539. }
  19540. }
  19541. toFullJSON() {
  19542. const {
  19543. expiredAt
  19544. } = this;
  19545. return { ...super.toFullJSON(),
  19546. expiredAt: getTime(expiredAt)
  19547. };
  19548. }
  19549. toJSON() {
  19550. const {
  19551. expiredAt,
  19552. expired
  19553. } = this;
  19554. return { ...super.toJSON(),
  19555. expiredAt,
  19556. expired
  19557. };
  19558. }
  19559. }
  19560. const debug$9 = browser('LC:ConversationQuery');
  19561. class ConversationQuery {
  19562. static _encode(value) {
  19563. if (value instanceof Date) {
  19564. return {
  19565. __type: 'Date',
  19566. iso: value.toJSON()
  19567. };
  19568. }
  19569. if (value instanceof RegExp) {
  19570. return value.source;
  19571. }
  19572. return value;
  19573. }
  19574. static _quote(s) {
  19575. return `\\Q${s.replace('\\E', '\\E\\\\E\\Q')}\\E`;
  19576. }
  19577. static _calculateFlag(options) {
  19578. return ['withLastMessagesRefreshed', 'compact'].reduce( // eslint-disable-next-line no-bitwise
  19579. (prev, key) => (prev << 1) + Boolean(options[key]), 0);
  19580. }
  19581. /**
  19582. * 构造一个用 AND 连接所有查询的 ConversationQuery
  19583. * @param {...ConversationQuery} queries
  19584. * @return {ConversationQuery}
  19585. */
  19586. static and(...queries) {
  19587. if (queries.length < 2) {
  19588. throw new Error('The queries must contain at least two elements');
  19589. }
  19590. if (!queries.every(q => q instanceof ConversationQuery)) {
  19591. throw new Error('The element of queries must be an instance of ConversationQuery');
  19592. }
  19593. const combined = new ConversationQuery(queries[0]._client);
  19594. combined._where.$and = queries.map(q => q._where);
  19595. return combined;
  19596. }
  19597. /**
  19598. * 构造一个用 OR 连接所有查询的 ConversationQuery
  19599. * @param {...ConversationQuery} queries
  19600. * @return {ConversationQuery}
  19601. */
  19602. static or(...queries) {
  19603. const combined = ConversationQuery.and(...queries);
  19604. combined._where.$or = combined._where.$and;
  19605. delete combined._where.$and;
  19606. return combined;
  19607. }
  19608. /**
  19609. * Create a ConversationQuery
  19610. * @param {IMClient} client
  19611. */
  19612. constructor(client) {
  19613. this._client = client;
  19614. this._where = {};
  19615. this._extraOptions = {};
  19616. }
  19617. _addCondition(key, condition, value) {
  19618. // Check if we already have a condition
  19619. if (!this._where[key]) {
  19620. this._where[key] = {};
  19621. }
  19622. this._where[key][condition] = this.constructor._encode(value);
  19623. return this;
  19624. }
  19625. toJSON() {
  19626. const json = {
  19627. where: this._where,
  19628. flag: this.constructor._calculateFlag(this._extraOptions)
  19629. };
  19630. if (typeof this._skip !== 'undefined') json.skip = this._skip;
  19631. if (typeof this._limit !== 'undefined') json.limit = this._limit;
  19632. if (typeof this._order !== 'undefined') json.sort = this._order;
  19633. debug$9(json);
  19634. return json;
  19635. }
  19636. /**
  19637. * 增加查询条件,指定聊天室的组员包含某些成员即可返回
  19638. * @param {string[]} peerIds - 成员 ID 列表
  19639. * @return {ConversationQuery} self
  19640. */
  19641. containsMembers(peerIds) {
  19642. return this.containsAll('m', peerIds);
  19643. }
  19644. /**
  19645. * 增加查询条件,指定聊天室的组员条件满足条件的才返回
  19646. *
  19647. * @param {string[]} - 成员 ID 列表
  19648. * @param {Boolean} includeSelf - 是否包含自己
  19649. * @return {ConversationQuery} self
  19650. */
  19651. withMembers(peerIds, includeSelf) {
  19652. const peerIdsSet = new Set(peerIds);
  19653. if (includeSelf) {
  19654. peerIdsSet.add(this._client.id);
  19655. }
  19656. this.sizeEqualTo('m', peerIdsSet.size);
  19657. return this.containsMembers(Array.from(peerIdsSet));
  19658. }
  19659. /**
  19660. * 增加查询条件,当 conversation 的属性中对应的字段满足等于条件时即可返回
  19661. *
  19662. * @param {string} key
  19663. * @param value
  19664. * @return {ConversationQuery} self
  19665. */
  19666. equalTo(key, value) {
  19667. this._where[key] = this.constructor._encode(value);
  19668. return this;
  19669. }
  19670. /**
  19671. * 增加查询条件,当 conversation 的属性中对应的字段满足小于条件时即可返回
  19672. * @param {string} key
  19673. * @param value
  19674. * @return {ConversationQuery} self
  19675. */
  19676. lessThan(key, value) {
  19677. return this._addCondition(key, '$lt', value);
  19678. }
  19679. /**
  19680. * 增加查询条件,当 conversation 的属性中对应的字段满足小于等于条件时即可返回
  19681. * @param {string} key
  19682. * @param value
  19683. * @return {ConversationQuery} self
  19684. */
  19685. lessThanOrEqualTo(key, value) {
  19686. return this._addCondition(key, '$lte', value);
  19687. }
  19688. /**
  19689. * 增加查询条件,当 conversation 的属性中对应的字段满足大于条件时即可返回
  19690. *
  19691. * @param {string} key
  19692. * @param value
  19693. * @return {ConversationQuery} self
  19694. */
  19695. greaterThan(key, value) {
  19696. return this._addCondition(key, '$gt', value);
  19697. }
  19698. /**
  19699. * 增加查询条件,当 conversation 的属性中对应的字段满足大于等于条件时即可返回
  19700. *
  19701. * @param {string} key
  19702. * @param value
  19703. * @return {ConversationQuery} self
  19704. */
  19705. greaterThanOrEqualTo(key, value) {
  19706. return this._addCondition(key, '$gte', value);
  19707. }
  19708. /**
  19709. * 增加查询条件,当 conversation 的属性中对应的字段满足不等于条件时即可返回
  19710. *
  19711. * @param {string} key
  19712. * @param value
  19713. * @return {ConversationQuery} self
  19714. */
  19715. notEqualTo(key, value) {
  19716. return this._addCondition(key, '$ne', value);
  19717. }
  19718. /**
  19719. * 增加查询条件,当 conversation 存在指定的字段时即可返回
  19720. *
  19721. * @since 3.5.0
  19722. * @param {string} key
  19723. * @return {ConversationQuery} self
  19724. */
  19725. exists(key) {
  19726. return this._addCondition(key, '$exists', true);
  19727. }
  19728. /**
  19729. * 增加查询条件,当 conversation 不存在指定的字段时即可返回
  19730. *
  19731. * @since 3.5.0
  19732. * @param {string} key
  19733. * @return {ConversationQuery} self
  19734. */
  19735. doesNotExist(key) {
  19736. return this._addCondition(key, '$exists', false);
  19737. }
  19738. /**
  19739. * 增加查询条件,当 conversation 的属性中对应的字段对应的值包含在指定值中时即可返回
  19740. *
  19741. * @param {string} key
  19742. * @param values
  19743. * @return {ConversationQuery} self
  19744. */
  19745. containedIn(key, values) {
  19746. return this._addCondition(key, '$in', values);
  19747. }
  19748. /**
  19749. * 增加查询条件,当 conversation 的属性中对应的字段对应的值不包含在指定值中时即可返回
  19750. *
  19751. * @param {string} key
  19752. * @param values
  19753. * @return {ConversationQuery} self
  19754. */
  19755. notContainsIn(key, values) {
  19756. return this._addCondition(key, '$nin', values);
  19757. }
  19758. /**
  19759. * 增加查询条件,当conversation的属性中对应的字段中的元素包含所有的值才可返回
  19760. *
  19761. * @param {string} key
  19762. * @param values
  19763. * @return {ConversationQuery} self
  19764. */
  19765. containsAll(key, values) {
  19766. return this._addCondition(key, '$all', values);
  19767. }
  19768. /**
  19769. * 增加查询条件,当 conversation 的属性中对应的字段对应的值包含此字符串即可返回
  19770. *
  19771. * @param {string} key
  19772. * @param {string} subString
  19773. * @return {ConversationQuery} self
  19774. */
  19775. contains(key, subString) {
  19776. return this._addCondition(key, '$regex', ConversationQuery._quote(subString));
  19777. }
  19778. /**
  19779. * 增加查询条件,当 conversation 的属性中对应的字段对应的值以此字符串起始即可返回
  19780. *
  19781. * @param {string} key
  19782. * @param {string} prefix
  19783. * @return {ConversationQuery} self
  19784. */
  19785. startsWith(key, prefix) {
  19786. return this._addCondition(key, '$regex', `^${ConversationQuery._quote(prefix)}`);
  19787. }
  19788. /**
  19789. * 增加查询条件,当 conversation 的属性中对应的字段对应的值以此字符串结束即可返回
  19790. *
  19791. * @param {string} key
  19792. * @param {string} suffix
  19793. * @return {ConversationQuery} self
  19794. */
  19795. endsWith(key, suffix) {
  19796. return this._addCondition(key, '$regex', `${ConversationQuery._quote(suffix)}$`);
  19797. }
  19798. /**
  19799. * 增加查询条件,当 conversation 的属性中对应的字段对应的值满足提供的正则表达式即可返回
  19800. *
  19801. * @param {string} key
  19802. * @param {RegExp} regex
  19803. * @return {ConversationQuery} self
  19804. */
  19805. matches(key, regex) {
  19806. this._addCondition(key, '$regex', regex); // Javascript regex options support mig as inline options but store them
  19807. // as properties of the object. We support mi & should migrate them to
  19808. // modifiers
  19809. let _modifiers = '';
  19810. if (regex.ignoreCase) {
  19811. _modifiers += 'i';
  19812. }
  19813. if (regex.multiline) {
  19814. _modifiers += 'm';
  19815. }
  19816. if (_modifiers && _modifiers.length) {
  19817. this._addCondition(key, '$options', _modifiers);
  19818. }
  19819. return this;
  19820. }
  19821. /**
  19822. * 添加查询约束条件,查找 key 类型是数组,该数组的长度匹配提供的数值
  19823. *
  19824. * @param {string} key
  19825. * @param {Number} length
  19826. * @return {ConversationQuery} self
  19827. */
  19828. sizeEqualTo(key, length) {
  19829. return this._addCondition(key, '$size', length);
  19830. }
  19831. /**
  19832. * 设置返回集合的大小上限
  19833. *
  19834. * @param {Number} limit - 上限
  19835. * @return {ConversationQuery} self
  19836. */
  19837. limit(limit) {
  19838. this._limit = limit;
  19839. return this;
  19840. }
  19841. /**
  19842. * 设置返回集合的起始位置,一般用于分页
  19843. *
  19844. * @param {Number} skip - 起始位置跳过几个对象
  19845. * @return {ConversationQuery} self
  19846. */
  19847. skip(skip) {
  19848. this._skip = skip;
  19849. return this;
  19850. }
  19851. /**
  19852. * 设置返回集合按照指定key进行增序排列
  19853. *
  19854. * @param {string} key
  19855. * @return {ConversationQuery} self
  19856. */
  19857. ascending(key) {
  19858. this._order = key;
  19859. return this;
  19860. }
  19861. /**
  19862. * 设置返回集合按照指定key进行增序排列,如果已设置其他排序,原排序的优先级较高
  19863. *
  19864. * @param {string} key
  19865. * @return {ConversationQuery} self
  19866. */
  19867. addAscending(key) {
  19868. if (this._order) {
  19869. this._order += `,${key}`;
  19870. } else {
  19871. this._order = key;
  19872. }
  19873. return this;
  19874. }
  19875. /**
  19876. * 设置返回集合按照指定 key 进行降序排列
  19877. *
  19878. * @param {string} key
  19879. * @return {ConversationQuery} self
  19880. */
  19881. descending(key) {
  19882. this._order = `-${key}`;
  19883. return this;
  19884. }
  19885. /**
  19886. * 设置返回集合按照指定 key 进行降序排列,如果已设置其他排序,原排序的优先级较高
  19887. *
  19888. * @param {string} key
  19889. * @return {ConversationQuery} self
  19890. */
  19891. addDescending(key) {
  19892. if (this._order) {
  19893. this._order += `,-${key}`;
  19894. } else {
  19895. this._order = `-${key}`;
  19896. }
  19897. return this;
  19898. }
  19899. /**
  19900. * 设置返回的 conversations 刷新最后一条消息
  19901. * @param {Boolean} [enabled=true]
  19902. * @return {ConversationQuery} self
  19903. */
  19904. withLastMessagesRefreshed(enabled = true) {
  19905. this._extraOptions.withLastMessagesRefreshed = enabled;
  19906. return this;
  19907. }
  19908. /**
  19909. * 设置返回的 conversations 为精简模式,即不含成员列表
  19910. * @param {Boolean} [enabled=true]
  19911. * @return {ConversationQuery} self
  19912. */
  19913. compact(enabled = true) {
  19914. this._extraOptions.compact = enabled;
  19915. return this;
  19916. }
  19917. /**
  19918. * 执行查询
  19919. * @return {Promise.<ConversationBase[]>}
  19920. */
  19921. async find() {
  19922. return this._client._executeQuery(this);
  19923. }
  19924. /**
  19925. * 返回符合条件的第一个结果
  19926. * @return {Promise.<ConversationBase>}
  19927. */
  19928. async first() {
  19929. return (await this.limit(1).find())[0];
  19930. }
  19931. }
  19932. const debug$a = browser('LC:SessionManager');
  19933. class SessionManager {
  19934. constructor({
  19935. refresh,
  19936. onBeforeGetSessionToken
  19937. } = {}) {
  19938. this.refresh = refresh;
  19939. this._onBeforeGetSessionToken = onBeforeGetSessionToken;
  19940. this.setSessionToken(null, 0);
  19941. }
  19942. setSessionToken(token, ttl) {
  19943. debug$a('set session token', token, ttl);
  19944. const sessionToken = new Expirable(token, ttl * 1000);
  19945. this._sessionToken = sessionToken;
  19946. delete this._pendingSessionTokenPromise;
  19947. return sessionToken;
  19948. }
  19949. async setSessionTokenAsync(promise) {
  19950. const currentSessionToken = this._sessionToken;
  19951. this._pendingSessionTokenPromise = promise.catch(error => {
  19952. // revert, otherwise the following getSessionToken calls
  19953. // will all be rejected
  19954. this._sessionToken = currentSessionToken;
  19955. throw error;
  19956. });
  19957. return this.setSessionToken(...(await this._pendingSessionTokenPromise));
  19958. }
  19959. async getSessionToken({
  19960. autoRefresh = true
  19961. } = {}) {
  19962. debug$a('get session token');
  19963. if (this._onBeforeGetSessionToken) {
  19964. this._onBeforeGetSessionToken(this);
  19965. }
  19966. const {
  19967. value,
  19968. originalValue
  19969. } = this._sessionToken || (await this._pendingSessionTokenPromise);
  19970. if (value === Expirable.EXPIRED && autoRefresh && this.refresh) {
  19971. debug$a('refresh expired session token');
  19972. const {
  19973. value: newValue
  19974. } = await this.setSessionTokenAsync(this.refresh(this, originalValue));
  19975. debug$a('session token', newValue);
  19976. return newValue;
  19977. }
  19978. debug$a('session token', value);
  19979. return value;
  19980. }
  19981. revoke() {
  19982. if (this._sessionToken) this._sessionToken.expiredAt = -1;
  19983. }
  19984. }
  19985. var _dec$2, _dec2, _class$3;
  19986. const debug$b = browser('LC:IMClient');
  19987. const {
  19988. INVITED: INVITED$1,
  19989. KICKED: KICKED$1,
  19990. MEMBERS_JOINED: MEMBERS_JOINED$1,
  19991. MEMBERS_LEFT: MEMBERS_LEFT$1,
  19992. MEMBER_INFO_UPDATED: MEMBER_INFO_UPDATED$1,
  19993. BLOCKED: BLOCKED$1,
  19994. UNBLOCKED: UNBLOCKED$1,
  19995. MEMBERS_BLOCKED: MEMBERS_BLOCKED$1,
  19996. MEMBERS_UNBLOCKED: MEMBERS_UNBLOCKED$1,
  19997. MUTED: MUTED$1,
  19998. UNMUTED: UNMUTED$1,
  19999. MEMBERS_MUTED: MEMBERS_MUTED$1,
  20000. MEMBERS_UNMUTED: MEMBERS_UNMUTED$1,
  20001. MESSAGE: MESSAGE$2,
  20002. UNREAD_MESSAGES_COUNT_UPDATE: UNREAD_MESSAGES_COUNT_UPDATE$1,
  20003. CLOSE: CLOSE$1,
  20004. CONFLICT: CONFLICT$1,
  20005. UNHANDLED_MESSAGE: UNHANDLED_MESSAGE$1,
  20006. CONVERSATION_INFO_UPDATED: CONVERSATION_INFO_UPDATED$1,
  20007. MESSAGE_RECALL: MESSAGE_RECALL$1,
  20008. MESSAGE_UPDATE: MESSAGE_UPDATE$1,
  20009. INFO_UPDATED: INFO_UPDATED$1
  20010. } = IMEvent;
  20011. const isTemporaryConversatrionId = id => /^_tmp:/.test(id);
  20012. /**
  20013. * 1 patch-msg
  20014. * 1 temp-conv-msg
  20015. * 0 auto-bind-deviceid-and-installation
  20016. * 1 transient-msg-ack
  20017. * 1 keep-notification
  20018. * 1 partial-failed-msg
  20019. * 0 group-chat-rcp
  20020. * 1 omit-peer-id
  20021. * @ignore
  20022. */
  20023. const configBitmap = 0b10111011;
  20024. let IMClient = (_dec$2 = throttle(1000), _dec2 = throttle(1000), (_class$3 = class IMClient extends eventemitter3 {
  20025. /**
  20026. * 无法直接实例化,请使用 {@link Realtime#createIMClient} 创建新的 IMClient。
  20027. *
  20028. * @extends EventEmitter
  20029. */
  20030. constructor(id, options = {}, props) {
  20031. if (!(id === undefined || typeof id === 'string')) {
  20032. throw new TypeError(`Client id [${id}] is not a String`);
  20033. }
  20034. super();
  20035. Object.assign(this, {
  20036. /**
  20037. * @var id {String} 客户端 id
  20038. * @memberof IMClient#
  20039. */
  20040. id,
  20041. options
  20042. }, props);
  20043. if (!this._messageParser) {
  20044. throw new Error('IMClient must be initialized with a MessageParser');
  20045. }
  20046. this._conversationCache = new Cache(`client:${this.id}`);
  20047. this._ackMessageBuffer = {};
  20048. internal(this).lastPatchTime = Date.now();
  20049. internal(this).lastNotificationTime = undefined;
  20050. internal(this)._eventemitter = new eventemitter3();
  20051. if (debug$b.enabled) {
  20052. values_1(IMEvent).forEach(event => this.on(event, (...payload) => this._debug(`${event} event emitted. %o`, payload)));
  20053. } // onIMClientCreate hook
  20054. applyDecorators(this._plugins.onIMClientCreate, this);
  20055. }
  20056. _debug(...params) {
  20057. debug$b(...params, `[${this.id}]`);
  20058. }
  20059. /**
  20060. * @override
  20061. * @private
  20062. */
  20063. async _dispatchCommand(command) {
  20064. this._debug(trim(command), 'received');
  20065. if (command.serverTs && command.notificationType === 1) {
  20066. internal(this).lastNotificationTime = getTime(decodeDate(command.serverTs));
  20067. }
  20068. switch (command.cmd) {
  20069. case CommandType.conv:
  20070. return this._dispatchConvMessage(command);
  20071. case CommandType.direct:
  20072. return this._dispatchDirectMessage(command);
  20073. case CommandType.session:
  20074. return this._dispatchSessionMessage(command);
  20075. case CommandType.unread:
  20076. return this._dispatchUnreadMessage(command);
  20077. case CommandType.rcp:
  20078. return this._dispatchRcpMessage(command);
  20079. case CommandType.patch:
  20080. return this._dispatchPatchMessage(command);
  20081. default:
  20082. return this.emit(UNHANDLED_MESSAGE$1, command);
  20083. }
  20084. }
  20085. async _dispatchSessionMessage(message) {
  20086. const {
  20087. sessionMessage: {
  20088. code,
  20089. reason
  20090. }
  20091. } = message;
  20092. switch (message.op) {
  20093. case OpType.closed:
  20094. {
  20095. internal(this)._eventemitter.emit('close');
  20096. if (code === ErrorCode.SESSION_CONFLICT) {
  20097. /**
  20098. * 用户在其他客户端登录,当前客户端被服务端强行下线。详见文档「单点登录」章节。
  20099. * @event IMClient#CONFLICT
  20100. * @param {Object} payload
  20101. * @param {string} payload.reason 原因
  20102. */
  20103. return this.emit(CONFLICT$1, {
  20104. reason
  20105. });
  20106. }
  20107. /**
  20108. * 当前客户端被服务端强行下线
  20109. * @event IMClient#CLOSE
  20110. * @param {Object} payload
  20111. * @param {Number} payload.code 错误码
  20112. * @param {String} payload.reason 原因
  20113. */
  20114. return this.emit(CLOSE$1, {
  20115. code,
  20116. reason
  20117. });
  20118. }
  20119. default:
  20120. this.emit(UNHANDLED_MESSAGE$1, message);
  20121. throw new Error('Unrecognized session command');
  20122. }
  20123. }
  20124. _dispatchUnreadMessage({
  20125. unreadMessage: {
  20126. convs,
  20127. notifTime
  20128. }
  20129. }) {
  20130. internal(this).lastUnreadNotifTime = notifTime; // ensure all converstions are cached
  20131. return this.getConversations(convs.map(conv => conv.cid)).then(() => // update conversations data
  20132. Promise.all(convs.map(({
  20133. cid,
  20134. unread,
  20135. mid,
  20136. timestamp: ts,
  20137. from,
  20138. data,
  20139. binaryMsg,
  20140. patchTimestamp,
  20141. mentioned
  20142. }) => {
  20143. const conversation = this._conversationCache.get(cid); // deleted conversation
  20144. if (!conversation) return null;
  20145. let timestamp;
  20146. if (ts) {
  20147. timestamp = decodeDate(ts);
  20148. conversation.lastMessageAt = timestamp; // eslint-disable-line no-param-reassign
  20149. }
  20150. return (mid ? this._messageParser.parse(binaryMsg || data).then(message => {
  20151. const messageProps = {
  20152. id: mid,
  20153. cid,
  20154. timestamp,
  20155. updatedAt: patchTimestamp,
  20156. from
  20157. };
  20158. Object.assign(message, messageProps);
  20159. conversation.lastMessage = message; // eslint-disable-line no-param-reassign
  20160. }) : Promise.resolve()).then(() => {
  20161. conversation._setUnreadMessagesMentioned(mentioned);
  20162. const countNotUpdated = unread === internal(conversation).unreadMessagesCount;
  20163. if (countNotUpdated) return null; // to be filtered
  20164. // manipulate internal property directly to skip unreadmessagescountupdate event
  20165. internal(conversation).unreadMessagesCount = unread;
  20166. return conversation;
  20167. }); // filter conversations without unread count update
  20168. })).then(conversations => conversations.filter(conversation => conversation))).then(conversations => {
  20169. if (conversations.length) {
  20170. /**
  20171. * 未读消息数目更新
  20172. * @event IMClient#UNREAD_MESSAGES_COUNT_UPDATE
  20173. * @since 3.4.0
  20174. * @param {Conversation[]} conversations 未读消息数目有更新的对话列表
  20175. */
  20176. this.emit(UNREAD_MESSAGES_COUNT_UPDATE$1, conversations);
  20177. }
  20178. });
  20179. }
  20180. async _dispatchRcpMessage(message) {
  20181. const {
  20182. rcpMessage,
  20183. rcpMessage: {
  20184. read
  20185. }
  20186. } = message;
  20187. const conversationId = rcpMessage.cid;
  20188. const messageId = rcpMessage.id;
  20189. const timestamp = decodeDate(rcpMessage.t);
  20190. const conversation = this._conversationCache.get(conversationId); // conversation not cached means the client does not send the message
  20191. // during this session
  20192. if (!conversation) return;
  20193. conversation._handleReceipt({
  20194. messageId,
  20195. timestamp,
  20196. read
  20197. });
  20198. }
  20199. _dispatchPatchMessage({
  20200. patchMessage: {
  20201. patches
  20202. }
  20203. }) {
  20204. // ensure all converstions are cached
  20205. return this.getConversations(patches.map(patch => patch.cid)).then(() => Promise.all(patches.map(({
  20206. cid,
  20207. mid,
  20208. timestamp,
  20209. recall,
  20210. data,
  20211. patchTimestamp,
  20212. from,
  20213. binaryMsg,
  20214. mentionAll,
  20215. mentionPids,
  20216. patchCode,
  20217. patchReason
  20218. }) => {
  20219. const conversation = this._conversationCache.get(cid); // deleted conversation
  20220. if (!conversation) return null;
  20221. return this._messageParser.parse(binaryMsg || data).then(message => {
  20222. const patchTime = getTime(decodeDate(patchTimestamp));
  20223. const messageProps = {
  20224. id: mid,
  20225. cid,
  20226. timestamp,
  20227. updatedAt: patchTime,
  20228. from,
  20229. mentionList: mentionPids,
  20230. mentionedAll: mentionAll
  20231. };
  20232. Object.assign(message, messageProps);
  20233. message._setStatus(MessageStatus.SENT);
  20234. message._updateMentioned(this.id);
  20235. if (internal(this).lastPatchTime < patchTime) {
  20236. internal(this).lastPatchTime = patchTime;
  20237. } // update conversation lastMessage
  20238. if (conversation.lastMessage && conversation.lastMessage.id === mid) {
  20239. conversation.lastMessage = message; // eslint-disable-line no-param-reassign
  20240. }
  20241. let reason;
  20242. if (patchCode) {
  20243. reason = {
  20244. code: patchCode.toNumber(),
  20245. detail: patchReason
  20246. };
  20247. }
  20248. if (recall) {
  20249. /**
  20250. * 消息被撤回
  20251. * @event IMClient#MESSAGE_RECALL
  20252. * @param {AVMessage} message 被撤回的消息
  20253. * @param {ConversationBase} conversation 消息所在的会话
  20254. * @param {PatchReason} [reason] 撤回的原因,不存在代表是发送者主动撤回
  20255. */
  20256. this.emit(MESSAGE_RECALL$1, message, conversation, reason);
  20257. /**
  20258. * 消息被撤回
  20259. * @event ConversationBase#MESSAGE_RECALL
  20260. * @param {AVMessage} message 被撤回的消息
  20261. * @param {PatchReason} [reason] 撤回的原因,不存在代表是发送者主动撤回
  20262. */
  20263. conversation.emit(MESSAGE_RECALL$1, message, reason);
  20264. } else {
  20265. /**
  20266. * 消息被修改
  20267. * @event IMClient#MESSAGE_UPDATE
  20268. * @param {AVMessage} message 被修改的消息
  20269. * @param {ConversationBase} conversation 消息所在的会话
  20270. * @param {PatchReason} [reason] 修改的原因,不存在代表是发送者主动修改
  20271. */
  20272. this.emit(MESSAGE_UPDATE$1, message, conversation, reason);
  20273. /**
  20274. * 消息被修改
  20275. * @event ConversationBase#MESSAGE_UPDATE
  20276. * @param {AVMessage} message 被修改的消息
  20277. * @param {PatchReason} [reason] 修改的原因,不存在代表是发送者主动修改
  20278. */
  20279. conversation.emit(MESSAGE_UPDATE$1, message, reason);
  20280. }
  20281. });
  20282. })));
  20283. }
  20284. async _dispatchConvMessage(message) {
  20285. const {
  20286. convMessage,
  20287. convMessage: {
  20288. initBy,
  20289. m,
  20290. info,
  20291. attr
  20292. }
  20293. } = message;
  20294. const conversation = await this.getConversation(convMessage.cid);
  20295. switch (message.op) {
  20296. case OpType.joined:
  20297. {
  20298. conversation._addMembers([this.id]);
  20299. const payload = {
  20300. invitedBy: initBy
  20301. };
  20302. /**
  20303. * 当前用户被添加至某个对话
  20304. * @event IMClient#INVITED
  20305. * @param {Object} payload
  20306. * @param {String} payload.invitedBy 邀请者 id
  20307. * @param {ConversationBase} conversation
  20308. */
  20309. this.emit(INVITED$1, payload, conversation);
  20310. /**
  20311. * 当前用户被添加至当前对话
  20312. * @event ConversationBase#INVITED
  20313. * @param {Object} payload
  20314. * @param {String} payload.invitedBy 该移除操作的发起者 id
  20315. */
  20316. conversation.emit(INVITED$1, payload);
  20317. return;
  20318. }
  20319. case OpType.left:
  20320. {
  20321. conversation._removeMembers([this.id]);
  20322. const payload = {
  20323. kickedBy: initBy
  20324. };
  20325. /**
  20326. * 当前用户被从某个对话中移除
  20327. * @event IMClient#KICKED
  20328. * @param {Object} payload
  20329. * @param {String} payload.kickedBy 该移除操作的发起者 id
  20330. * @param {ConversationBase} conversation
  20331. */
  20332. this.emit(KICKED$1, payload, conversation);
  20333. /**
  20334. * 当前用户被从当前对话中移除
  20335. * @event ConversationBase#KICKED
  20336. * @param {Object} payload
  20337. * @param {String} payload.kickedBy 该移除操作的发起者 id
  20338. */
  20339. conversation.emit(KICKED$1, payload);
  20340. return;
  20341. }
  20342. case OpType.members_joined:
  20343. {
  20344. conversation._addMembers(m);
  20345. const payload = {
  20346. invitedBy: initBy,
  20347. members: m
  20348. };
  20349. /**
  20350. * 有用户被添加至某个对话
  20351. * @event IMClient#MEMBERS_JOINED
  20352. * @param {Object} payload
  20353. * @param {String[]} payload.members 被添加的用户 id 列表
  20354. * @param {String} payload.invitedBy 邀请者 id
  20355. * @param {ConversationBase} conversation
  20356. */
  20357. this.emit(MEMBERS_JOINED$1, payload, conversation);
  20358. /**
  20359. * 有成员被添加至当前对话
  20360. * @event ConversationBase#MEMBERS_JOINED
  20361. * @param {Object} payload
  20362. * @param {String[]} payload.members 被添加的成员 id 列表
  20363. * @param {String} payload.invitedBy 邀请者 id
  20364. */
  20365. conversation.emit(MEMBERS_JOINED$1, payload);
  20366. return;
  20367. }
  20368. case OpType.members_left:
  20369. {
  20370. conversation._removeMembers(m);
  20371. const payload = {
  20372. kickedBy: initBy,
  20373. members: m
  20374. };
  20375. /**
  20376. * 有成员被从某个对话中移除
  20377. * @event IMClient#MEMBERS_LEFT
  20378. * @param {Object} payload
  20379. * @param {String[]} payload.members 被移除的成员 id 列表
  20380. * @param {String} payload.kickedBy 该移除操作的发起者 id
  20381. * @param {ConversationBase} conversation
  20382. */
  20383. this.emit(MEMBERS_LEFT$1, payload, conversation);
  20384. /**
  20385. * 有成员被从当前对话中移除
  20386. * @event ConversationBase#MEMBERS_LEFT
  20387. * @param {Object} payload
  20388. * @param {String[]} payload.members 被移除的成员 id 列表
  20389. * @param {String} payload.kickedBy 该移除操作的发起者 id
  20390. */
  20391. conversation.emit(MEMBERS_LEFT$1, payload);
  20392. return;
  20393. }
  20394. case OpType.members_blocked:
  20395. {
  20396. const payload = {
  20397. blockedBy: initBy,
  20398. members: m
  20399. };
  20400. /**
  20401. * 有成员被加入某个对话的黑名单
  20402. * @event IMClient#MEMBERS_BLOCKED
  20403. * @param {Object} payload
  20404. * @param {String[]} payload.members 成员 id 列表
  20405. * @param {String} payload.blockedBy 该操作的发起者 id
  20406. * @param {ConversationBase} conversation
  20407. */
  20408. this.emit(MEMBERS_BLOCKED$1, payload, conversation);
  20409. /**
  20410. * 有成员被加入当前对话的黑名单
  20411. * @event ConversationBase#MEMBERS_BLOCKED
  20412. * @param {Object} payload
  20413. * @param {String[]} payload.members 成员 id 列表
  20414. * @param {String} payload.blockedBy 该操作的发起者 id
  20415. */
  20416. conversation.emit(MEMBERS_BLOCKED$1, payload);
  20417. return;
  20418. }
  20419. case OpType.members_unblocked:
  20420. {
  20421. const payload = {
  20422. unblockedBy: initBy,
  20423. members: m
  20424. };
  20425. /**
  20426. * 有成员被移出某个对话的黑名单
  20427. * @event IMClient#MEMBERS_UNBLOCKED
  20428. * @param {Object} payload
  20429. * @param {String[]} payload.members 成员 id 列表
  20430. * @param {String} payload.unblockedBy 该操作的发起者 id
  20431. * @param {ConversationBase} conversation
  20432. */
  20433. this.emit(MEMBERS_UNBLOCKED$1, payload, conversation);
  20434. /**
  20435. * 有成员被移出当前对话的黑名单
  20436. * @event ConversationBase#MEMBERS_UNBLOCKED
  20437. * @param {Object} payload
  20438. * @param {String[]} payload.members 成员 id 列表
  20439. * @param {String} payload.unblockedBy 该操作的发起者 id
  20440. */
  20441. conversation.emit(MEMBERS_UNBLOCKED$1, payload);
  20442. return;
  20443. }
  20444. case OpType.blocked:
  20445. {
  20446. const payload = {
  20447. blockedBy: initBy
  20448. };
  20449. /**
  20450. * 当前用户被加入某个对话的黑名单
  20451. * @event IMClient#BLOCKED
  20452. * @param {Object} payload
  20453. * @param {String} payload.blockedBy 该操作的发起者 id
  20454. * @param {ConversationBase} conversation
  20455. */
  20456. this.emit(BLOCKED$1, payload, conversation);
  20457. /**
  20458. * 当前用户被加入当前对话的黑名单
  20459. * @event ConversationBase#BLOCKED
  20460. * @param {Object} payload
  20461. * @param {String} payload.blockedBy 该操作的发起者 id
  20462. */
  20463. conversation.emit(BLOCKED$1, payload);
  20464. return;
  20465. }
  20466. case OpType.unblocked:
  20467. {
  20468. const payload = {
  20469. unblockedBy: initBy
  20470. };
  20471. /**
  20472. * 当前用户被移出某个对话的黑名单
  20473. * @event IMClient#UNBLOCKED
  20474. * @param {Object} payload
  20475. * @param {String} payload.unblockedBy 该操作的发起者 id
  20476. * @param {ConversationBase} conversation
  20477. */
  20478. this.emit(UNBLOCKED$1, payload, conversation);
  20479. /**
  20480. * 当前用户被移出当前对话的黑名单
  20481. * @event ConversationBase#UNBLOCKED
  20482. * @param {Object} payload
  20483. * @param {String} payload.unblockedBy 该操作的发起者 id
  20484. */
  20485. conversation.emit(UNBLOCKED$1, payload);
  20486. return;
  20487. }
  20488. case OpType.members_shutuped:
  20489. {
  20490. const payload = {
  20491. mutedBy: initBy,
  20492. members: m
  20493. };
  20494. /**
  20495. * 有成员在某个对话中被禁言
  20496. * @event IMClient#MEMBERS_MUTED
  20497. * @param {Object} payload
  20498. * @param {String[]} payload.members 成员 id 列表
  20499. * @param {String} payload.mutedBy 该操作的发起者 id
  20500. * @param {ConversationBase} conversation
  20501. */
  20502. this.emit(MEMBERS_MUTED$1, payload, conversation);
  20503. /**
  20504. * 有成员在当前对话中被禁言
  20505. * @event ConversationBase#MEMBERS_MUTED
  20506. * @param {Object} payload
  20507. * @param {String[]} payload.members 成员 id 列表
  20508. * @param {String} payload.mutedBy 该操作的发起者 id
  20509. */
  20510. conversation.emit(MEMBERS_MUTED$1, payload);
  20511. return;
  20512. }
  20513. case OpType.members_unshutuped:
  20514. {
  20515. const payload = {
  20516. unmutedBy: initBy,
  20517. members: m
  20518. };
  20519. /**
  20520. * 有成员在某个对话中被解除禁言
  20521. * @event IMClient#MEMBERS_UNMUTED
  20522. * @param {Object} payload
  20523. * @param {String[]} payload.members 成员 id 列表
  20524. * @param {String} payload.unmutedBy 该操作的发起者 id
  20525. * @param {ConversationBase} conversation
  20526. */
  20527. this.emit(MEMBERS_UNMUTED$1, payload, conversation);
  20528. /**
  20529. * 有成员在当前对话中被解除禁言
  20530. * @event ConversationBase#MEMBERS_UNMUTED
  20531. * @param {Object} payload
  20532. * @param {String[]} payload.members 成员 id 列表
  20533. * @param {String} payload.unmutedBy 该操作的发起者 id
  20534. */
  20535. conversation.emit(MEMBERS_UNMUTED$1, payload);
  20536. return;
  20537. }
  20538. case OpType.shutuped:
  20539. {
  20540. const payload = {
  20541. mutedBy: initBy
  20542. };
  20543. /**
  20544. * 有成员在某个对话中被禁言
  20545. * @event IMClient#MUTED
  20546. * @param {Object} payload
  20547. * @param {String} payload.mutedBy 该操作的发起者 id
  20548. * @param {ConversationBase} conversation
  20549. */
  20550. this.emit(MUTED$1, payload, conversation);
  20551. /**
  20552. * 有成员在当前对话中被禁言
  20553. * @event ConversationBase#MUTED
  20554. * @param {Object} payload
  20555. * @param {String} payload.mutedBy 该操作的发起者 id
  20556. */
  20557. conversation.emit(MUTED$1, payload);
  20558. return;
  20559. }
  20560. case OpType.unshutuped:
  20561. {
  20562. const payload = {
  20563. unmutedBy: initBy
  20564. };
  20565. /**
  20566. * 有成员在某个对话中被解除禁言
  20567. * @event IMClient#UNMUTED
  20568. * @param {Object} payload
  20569. * @param {String} payload.unmutedBy 该操作的发起者 id
  20570. * @param {ConversationBase} conversation
  20571. */
  20572. this.emit(UNMUTED$1, payload, conversation);
  20573. /**
  20574. * 有成员在当前对话中被解除禁言
  20575. * @event ConversationBase#UNMUTED
  20576. * @param {Object} payload
  20577. * @param {String} payload.unmutedBy 该操作的发起者 id
  20578. */
  20579. conversation.emit(UNMUTED$1, payload);
  20580. return;
  20581. }
  20582. case OpType.member_info_changed:
  20583. {
  20584. const {
  20585. pid,
  20586. role
  20587. } = info;
  20588. const {
  20589. memberInfoMap
  20590. } = internal(conversation); // 如果不存在缓存,且不是 role 的更新,则不通知
  20591. if (!memberInfoMap && !role) return;
  20592. const memberInfo = await conversation.getMemberInfo(pid);
  20593. internal(memberInfo).role = role;
  20594. const payload = {
  20595. member: pid,
  20596. memberInfo,
  20597. updatedBy: initBy
  20598. };
  20599. /**
  20600. * 有成员的对话信息被更新
  20601. * @event IMClient#MEMBER_INFO_UPDATED
  20602. * @param {Object} payload
  20603. * @param {String} payload.member 被更新对话信息的成员 id
  20604. * @param {ConversationMumberInfo} payload.memberInfo 被更新的成员对话信息
  20605. * @param {String} payload.updatedBy 该操作的发起者 id
  20606. * @param {ConversationBase} conversation
  20607. */
  20608. this.emit(MEMBER_INFO_UPDATED$1, payload, conversation);
  20609. /**
  20610. * 有成员的对话信息被更新
  20611. * @event ConversationBase#MEMBER_INFO_UPDATED
  20612. * @param {Object} payload
  20613. * @param {String} payload.member 被更新对话信息的成员 id
  20614. * @param {ConversationMumberInfo} payload.memberInfo 被更新的成员对话信息
  20615. * @param {String} payload.updatedBy 该操作的发起者 id
  20616. */
  20617. conversation.emit(MEMBER_INFO_UPDATED$1, payload);
  20618. return;
  20619. }
  20620. case OpType.updated:
  20621. {
  20622. const attributes = decode(JSON.parse(attr.data));
  20623. conversation._updateServerAttributes(attributes);
  20624. const payload = {
  20625. attributes,
  20626. updatedBy: initBy
  20627. };
  20628. /**
  20629. * 该对话信息被更新
  20630. * @event IMClient#CONVERSATION_INFO_UPDATED
  20631. * @param {Object} payload
  20632. * @param {Object} payload.attributes 被更新的属性
  20633. * @param {String} payload.updatedBy 该操作的发起者 id
  20634. * @param {ConversationBase} conversation
  20635. */
  20636. this.emit(CONVERSATION_INFO_UPDATED$1, payload, conversation);
  20637. /**
  20638. * 有对话信息被更新
  20639. * @event ConversationBase#INFO_UPDATED
  20640. * @param {Object} payload
  20641. * @param {Object} payload.attributes 被更新的属性
  20642. * @param {String} payload.updatedBy 该操作的发起者 id
  20643. */
  20644. conversation.emit(INFO_UPDATED$1, payload);
  20645. return;
  20646. }
  20647. default:
  20648. this.emit(UNHANDLED_MESSAGE$1, message);
  20649. throw new Error('Unrecognized conversation command');
  20650. }
  20651. }
  20652. _dispatchDirectMessage(originalMessage) {
  20653. const {
  20654. directMessage,
  20655. directMessage: {
  20656. id,
  20657. cid,
  20658. fromPeerId,
  20659. timestamp,
  20660. transient,
  20661. patchTimestamp,
  20662. mentionPids,
  20663. mentionAll,
  20664. binaryMsg,
  20665. msg
  20666. }
  20667. } = originalMessage;
  20668. const content = binaryMsg ? binaryMsg.toArrayBuffer() : msg;
  20669. return Promise.all([this.getConversation(directMessage.cid), this._messageParser.parse(content)]).then(([conversation, message]) => {
  20670. // deleted conversation
  20671. if (!conversation) return undefined;
  20672. const messageProps = {
  20673. id,
  20674. cid,
  20675. timestamp,
  20676. updatedAt: patchTimestamp,
  20677. from: fromPeerId,
  20678. mentionList: mentionPids,
  20679. mentionedAll: mentionAll
  20680. };
  20681. Object.assign(message, messageProps);
  20682. message._updateMentioned(this.id);
  20683. message._setStatus(MessageStatus.SENT); // filter outgoing message sent from another device
  20684. if (message.from !== this.id) {
  20685. if (!(transient || conversation.transient)) {
  20686. this._sendAck(message);
  20687. }
  20688. }
  20689. return this._dispatchParsedMessage(message, conversation);
  20690. });
  20691. }
  20692. _dispatchParsedMessage(message, conversation) {
  20693. // beforeMessageDispatch hook
  20694. return applyDispatcher(this._plugins.beforeMessageDispatch, [message, conversation]).then(shouldDispatch => {
  20695. if (shouldDispatch === false) return;
  20696. conversation.lastMessage = message; // eslint-disable-line no-param-reassign
  20697. conversation.lastMessageAt = message.timestamp; // eslint-disable-line no-param-reassign
  20698. // filter outgoing message sent from another device
  20699. if (message.from !== this.id) {
  20700. conversation.unreadMessagesCount += 1; // eslint-disable-line no-param-reassign
  20701. if (message.mentioned) conversation._setUnreadMessagesMentioned(true);
  20702. }
  20703. /**
  20704. * 当前用户收到消息
  20705. * @event IMClient#MESSAGE
  20706. * @param {Message} message
  20707. * @param {ConversationBase} conversation 收到消息的对话
  20708. */
  20709. this.emit(MESSAGE$2, message, conversation);
  20710. /**
  20711. * 当前对话收到消息
  20712. * @event ConversationBase#MESSAGE
  20713. * @param {Message} message
  20714. */
  20715. conversation.emit(MESSAGE$2, message);
  20716. });
  20717. }
  20718. _sendAck(message) {
  20719. this._debug('send ack for %O', message);
  20720. const {
  20721. cid
  20722. } = message;
  20723. if (!cid) {
  20724. throw new Error('missing cid');
  20725. }
  20726. if (!this._ackMessageBuffer[cid]) {
  20727. this._ackMessageBuffer[cid] = [];
  20728. }
  20729. this._ackMessageBuffer[cid].push(message);
  20730. return this._doSendAck();
  20731. } // jsdoc-ignore-start
  20732. // jsdoc-ignore-end
  20733. _doSendAck() {
  20734. // if not connected, just skip everything
  20735. if (!this._connection.is('connected')) return;
  20736. this._debug('do send ack %O', this._ackMessageBuffer);
  20737. Promise.all(Object.keys(this._ackMessageBuffer).map(cid => {
  20738. const convAckMessages = this._ackMessageBuffer[cid];
  20739. const timestamps = convAckMessages.map(message => message.timestamp);
  20740. const command = new GenericCommand({
  20741. cmd: 'ack',
  20742. ackMessage: new AckCommand({
  20743. cid,
  20744. fromts: Math.min.apply(null, timestamps),
  20745. tots: Math.max.apply(null, timestamps)
  20746. })
  20747. });
  20748. delete this._ackMessageBuffer[cid];
  20749. return this._send(command, false).catch(error => {
  20750. this._debug('send ack failed: %O', error);
  20751. this._ackMessageBuffer[cid] = convAckMessages;
  20752. });
  20753. }));
  20754. }
  20755. _omitPeerId(value) {
  20756. internal(this).peerIdOmittable = value;
  20757. }
  20758. _send(cmd, ...args) {
  20759. const command = cmd;
  20760. if (!internal(this).peerIdOmittable && this.id) {
  20761. command.peerId = this.id;
  20762. }
  20763. return this._connection.send(command, ...args);
  20764. }
  20765. async _open(appId, tag, deviceId, isReconnect = false) {
  20766. this._debug('open session');
  20767. const {
  20768. lastUnreadNotifTime,
  20769. lastPatchTime,
  20770. lastNotificationTime
  20771. } = internal(this);
  20772. const command = new GenericCommand({
  20773. cmd: 'session',
  20774. op: 'open',
  20775. appId,
  20776. peerId: this.id,
  20777. sessionMessage: new SessionCommand({
  20778. ua: `js/${version}`,
  20779. r: isReconnect,
  20780. lastUnreadNotifTime,
  20781. lastPatchTime,
  20782. configBitmap
  20783. })
  20784. });
  20785. if (!isReconnect) {
  20786. Object.assign(command.sessionMessage, trim({
  20787. tag,
  20788. deviceId
  20789. }));
  20790. if (this.options.signatureFactory) {
  20791. const signatureResult = await runSignatureFactory(this.options.signatureFactory, [this._identity]);
  20792. Object.assign(command.sessionMessage, keyRemap({
  20793. signature: 's',
  20794. timestamp: 't',
  20795. nonce: 'n'
  20796. }, signatureResult));
  20797. }
  20798. } else {
  20799. const sessionToken = await this._sessionManager.getSessionToken({
  20800. autoRefresh: false
  20801. });
  20802. if (sessionToken && sessionToken !== Expirable.EXPIRED) {
  20803. Object.assign(command.sessionMessage, {
  20804. st: sessionToken
  20805. });
  20806. }
  20807. }
  20808. let resCommand;
  20809. try {
  20810. resCommand = await this._send(command);
  20811. } catch (error) {
  20812. if (error.code === ErrorCode.SESSION_TOKEN_EXPIRED) {
  20813. if (!this._sessionManager) {
  20814. // let it fail if sessoinToken not cached but command rejected as token expired
  20815. // to prevent session openning flood
  20816. throw new Error('Unexpected session expiration');
  20817. }
  20818. debug$b('Session token expired, reopening');
  20819. this._sessionManager.revoke();
  20820. return this._open(appId, tag, deviceId, isReconnect);
  20821. }
  20822. throw error;
  20823. }
  20824. const {
  20825. peerId,
  20826. sessionMessage,
  20827. sessionMessage: {
  20828. st: token,
  20829. stTtl: tokenTTL,
  20830. code
  20831. },
  20832. serverTs
  20833. } = resCommand;
  20834. if (code) {
  20835. throw createError(sessionMessage);
  20836. }
  20837. if (peerId) {
  20838. this.id = peerId;
  20839. if (!this._identity) this._identity = peerId;
  20840. if (token) {
  20841. this._sessionManager = this._sessionManager || this._createSessionManager();
  20842. this._sessionManager.setSessionToken(token, tokenTTL);
  20843. }
  20844. const serverTime = getTime(decodeDate(serverTs));
  20845. if (serverTs) {
  20846. internal(this).lastPatchTime = serverTime;
  20847. }
  20848. if (lastNotificationTime) {
  20849. // Do not await for it as this is failable
  20850. this._syncNotifications(lastNotificationTime).catch(error => console.warn('Syncing notifications failed:', error));
  20851. } else {
  20852. // Set timestamp to now for next reconnection
  20853. internal(this).lastNotificationTime = serverTime;
  20854. }
  20855. } else {
  20856. console.warn('Unexpected session opened without peerId.');
  20857. }
  20858. return undefined;
  20859. }
  20860. async _syncNotifications(timestamp) {
  20861. const {
  20862. hasMore,
  20863. notifications
  20864. } = await this._fetchNotifications(timestamp);
  20865. notifications.forEach(notification => {
  20866. const {
  20867. cmd,
  20868. op,
  20869. serverTs,
  20870. notificationType,
  20871. ...payload
  20872. } = notification;
  20873. this._dispatchCommand({
  20874. cmd: CommandType[cmd],
  20875. op: OpType[op],
  20876. serverTs,
  20877. notificationType,
  20878. [`${cmd}Message`]: payload
  20879. });
  20880. });
  20881. if (hasMore) {
  20882. return this._syncNotifications(internal(this).lastNotificationTime);
  20883. }
  20884. return undefined;
  20885. }
  20886. async _fetchNotifications(timestamp) {
  20887. return this._requestWithSessionToken({
  20888. method: 'GET',
  20889. path: '/rtm/notifications',
  20890. query: {
  20891. start_ts: timestamp,
  20892. notification_type: 'permanent'
  20893. }
  20894. });
  20895. }
  20896. _createSessionManager() {
  20897. debug$b('create SessionManager');
  20898. return new SessionManager({
  20899. onBeforeGetSessionToken: this._connection.checkConnectionAvailability.bind(this._connection),
  20900. refresh: (manager, expiredSessionToken) => manager.setSessionTokenAsync(Promise.resolve(new GenericCommand({
  20901. cmd: 'session',
  20902. op: 'refresh',
  20903. sessionMessage: new SessionCommand({
  20904. ua: `js/${version}`,
  20905. st: expiredSessionToken
  20906. })
  20907. })).then(async command => {
  20908. if (this.options.signatureFactory) {
  20909. const signatureResult = await runSignatureFactory(this.options.signatureFactory, [this._identity]);
  20910. Object.assign(command.sessionMessage, keyRemap({
  20911. signature: 's',
  20912. timestamp: 't',
  20913. nonce: 'n'
  20914. }, signatureResult));
  20915. }
  20916. return command;
  20917. }).then(this._send.bind(this)).then(({
  20918. sessionMessage: {
  20919. st: token,
  20920. stTtl: ttl
  20921. }
  20922. }) => [token, ttl]))
  20923. });
  20924. }
  20925. async _requestWithSessionToken({
  20926. headers,
  20927. query,
  20928. ...params
  20929. }) {
  20930. const sessionToken = await this._sessionManager.getSessionToken();
  20931. return this._request({
  20932. headers: {
  20933. 'X-LC-IM-Session-Token': sessionToken,
  20934. ...headers
  20935. },
  20936. query: {
  20937. client_id: this.id,
  20938. ...query
  20939. },
  20940. ...params
  20941. });
  20942. }
  20943. /**
  20944. * 关闭客户端
  20945. * @return {Promise}
  20946. */
  20947. async close() {
  20948. this._debug('close session');
  20949. const _ee = internal(this)._eventemitter;
  20950. _ee.emit('beforeclose');
  20951. if (this._connection.is('connected')) {
  20952. const command = new GenericCommand({
  20953. cmd: 'session',
  20954. op: 'close'
  20955. });
  20956. await this._send(command);
  20957. }
  20958. _ee.emit('close');
  20959. this.emit(CLOSE$1, {
  20960. code: 0
  20961. });
  20962. }
  20963. /**
  20964. * 获取 client 列表中在线的 client,每次查询最多 20 个 clientId,超出部分会被忽略
  20965. * @param {String[]} clientIds 要查询的 client ids
  20966. * @return {Primse.<String[]>} 在线的 client ids
  20967. */
  20968. async ping(clientIds) {
  20969. this._debug('ping');
  20970. if (!(clientIds instanceof Array)) {
  20971. throw new TypeError(`clientIds ${clientIds} is not an Array`);
  20972. }
  20973. if (!clientIds.length) {
  20974. return Promise.resolve([]);
  20975. }
  20976. const command = new GenericCommand({
  20977. cmd: 'session',
  20978. op: 'query',
  20979. sessionMessage: new SessionCommand({
  20980. sessionPeerIds: clientIds
  20981. })
  20982. });
  20983. const resCommand = await this._send(command);
  20984. return resCommand.sessionMessage.onlineSessionPeerIds;
  20985. }
  20986. /**
  20987. * 获取某个特定的对话
  20988. * @param {String} id 对话 id,对应 _Conversation 表中的 objectId
  20989. * @param {Boolean} [noCache=false] 强制不从缓存中获取
  20990. * @return {Promise.<ConversationBase>} 如果 id 对应的对话不存在则返回 null
  20991. */
  20992. async getConversation(id, noCache = false) {
  20993. if (typeof id !== 'string') {
  20994. throw new TypeError(`${id} is not a String`);
  20995. }
  20996. if (!noCache) {
  20997. const cachedConversation = this._conversationCache.get(id);
  20998. if (cachedConversation) {
  20999. return cachedConversation;
  21000. }
  21001. }
  21002. if (isTemporaryConversatrionId(id)) {
  21003. return (await this._getTemporaryConversations([id]))[0] || null;
  21004. }
  21005. return this.getQuery().equalTo('objectId', id).find().then(conversations => conversations[0] || null);
  21006. }
  21007. /**
  21008. * 通过 id 批量获取某个特定的对话
  21009. * @since 3.4.0
  21010. * @param {String[]} ids 对话 id 列表,对应 _Conversation 表中的 objectId
  21011. * @param {Boolean} [noCache=false] 强制不从缓存中获取
  21012. * @return {Promise.<ConversationBase[]>} 如果 id 对应的对话不存在则返回 null
  21013. */
  21014. async getConversations(ids, noCache = false) {
  21015. const remoteConversationIds = noCache ? ids : ids.filter(id => this._conversationCache.get(id) === null);
  21016. if (remoteConversationIds.length) {
  21017. const remoteTemporaryConversationIds = remove_1(remoteConversationIds, isTemporaryConversatrionId);
  21018. const query = [];
  21019. if (remoteConversationIds.length) {
  21020. query.push(this.getQuery().containedIn('objectId', remoteConversationIds).limit(999).find());
  21021. }
  21022. if (remoteTemporaryConversationIds.length) {
  21023. const remoteTemporaryConversationsPromise = remoteTemporaryConversationIds.map(this._getTemporaryConversations.bind(this));
  21024. query.push(...remoteTemporaryConversationsPromise);
  21025. }
  21026. await Promise.all(query);
  21027. }
  21028. return ids.map(id => this._conversationCache.get(id));
  21029. }
  21030. async _getTemporaryConversations(ids) {
  21031. const command = new GenericCommand({
  21032. cmd: 'conv',
  21033. op: 'query',
  21034. convMessage: new ConvCommand({
  21035. tempConvIds: ids
  21036. })
  21037. });
  21038. const resCommand = await this._send(command);
  21039. return this._handleQueryResults(resCommand);
  21040. }
  21041. /**
  21042. * 构造一个 ConversationQuery 来查询对话
  21043. * @return {ConversationQuery.<PersistentConversation>}
  21044. */
  21045. getQuery() {
  21046. return new ConversationQuery(this);
  21047. }
  21048. /**
  21049. * 构造一个 ConversationQuery 来查询聊天室
  21050. * @return {ConversationQuery.<ChatRoom>}
  21051. */
  21052. getChatRoomQuery() {
  21053. return this.getQuery().equalTo('tr', true);
  21054. }
  21055. /**
  21056. * 构造一个 ConversationQuery 来查询服务号
  21057. * @return {ConversationQuery.<ServiceConversation>}
  21058. */
  21059. getServiceConversationQuery() {
  21060. return this.getQuery().equalTo('sys', true);
  21061. }
  21062. async _executeQuery(query) {
  21063. const queryJSON = query.toJSON();
  21064. queryJSON.where = new JsonObjectMessage({
  21065. data: JSON.stringify(encode(queryJSON.where))
  21066. });
  21067. const command = new GenericCommand({
  21068. cmd: 'conv',
  21069. op: 'query',
  21070. convMessage: new ConvCommand(queryJSON)
  21071. });
  21072. const resCommand = await this._send(command);
  21073. return this._handleQueryResults(resCommand);
  21074. }
  21075. async _handleQueryResults(resCommand) {
  21076. let conversations;
  21077. try {
  21078. conversations = decode(JSON.parse(resCommand.convMessage.results.data));
  21079. } catch (error) {
  21080. const commandString = JSON.stringify(trim(resCommand));
  21081. throw new Error(`Parse query result failed: ${error.message}. Command: ${commandString}`);
  21082. }
  21083. conversations = await Promise.all(conversations.map(this._parseConversationFromRawData.bind(this)));
  21084. return conversations.map(this._upsertConversationToCache.bind(this));
  21085. }
  21086. _upsertConversationToCache(fetchedConversation) {
  21087. let conversation = this._conversationCache.get(fetchedConversation.id);
  21088. if (!conversation) {
  21089. conversation = fetchedConversation;
  21090. this._debug('no match, set cache');
  21091. this._conversationCache.set(fetchedConversation.id, fetchedConversation);
  21092. } else {
  21093. this._debug('update cached conversation');
  21094. ['creator', 'createdAt', 'updatedAt', 'lastMessageAt', 'lastMessage', 'mutedMembers', 'members', '_attributes', 'transient', 'muted'].forEach(key => {
  21095. const value = fetchedConversation[key];
  21096. if (value !== undefined) conversation[key] = value;
  21097. });
  21098. if (conversation._reset) conversation._reset();
  21099. }
  21100. return conversation;
  21101. }
  21102. /**
  21103. * 反序列化消息,与 {@link Message#toFullJSON} 相对。
  21104. * @param {Object}
  21105. * @return {AVMessage} 解析后的消息
  21106. * @since 4.0.0
  21107. */
  21108. async parseMessage({
  21109. data,
  21110. bin = false,
  21111. ...properties
  21112. }) {
  21113. const content = bin ? base64Arraybuffer_2(data) : data;
  21114. const message = await this._messageParser.parse(content);
  21115. Object.assign(message, properties);
  21116. message._updateMentioned(this.id);
  21117. return message;
  21118. }
  21119. /**
  21120. * 反序列化对话,与 {@link Conversation#toFullJSON} 相对。
  21121. * @param {Object}
  21122. * @return {ConversationBase} 解析后的对话
  21123. * @since 4.0.0
  21124. */
  21125. async parseConversation({
  21126. id,
  21127. lastMessageAt,
  21128. lastMessage,
  21129. lastDeliveredAt,
  21130. lastReadAt,
  21131. unreadMessagesCount,
  21132. members,
  21133. mentioned,
  21134. ...properties
  21135. }) {
  21136. const conversationData = {
  21137. id,
  21138. lastMessageAt,
  21139. lastMessage,
  21140. lastDeliveredAt,
  21141. lastReadAt,
  21142. unreadMessagesCount,
  21143. members,
  21144. mentioned
  21145. };
  21146. if (lastMessage) {
  21147. conversationData.lastMessage = await this.parseMessage(lastMessage);
  21148. conversationData.lastMessage._setStatus(MessageStatus.SENT);
  21149. }
  21150. const {
  21151. transient,
  21152. system,
  21153. expiredAt
  21154. } = properties;
  21155. if (transient) return new ChatRoom(conversationData, properties, this);
  21156. if (system) return new ServiceConversation(conversationData, properties, this);
  21157. if (expiredAt || isTemporaryConversatrionId(id)) {
  21158. return new TemporaryConversation(conversationData, {
  21159. expiredAt
  21160. }, this);
  21161. }
  21162. return new Conversation(conversationData, properties, this);
  21163. }
  21164. async _parseConversationFromRawData(rawData) {
  21165. const data = keyRemap({
  21166. objectId: 'id',
  21167. lm: 'lastMessageAt',
  21168. m: 'members',
  21169. tr: 'transient',
  21170. sys: 'system',
  21171. c: 'creator',
  21172. mu: 'mutedMembers'
  21173. }, rawData);
  21174. if (data.msg) {
  21175. data.lastMessage = {
  21176. data: data.msg,
  21177. bin: data.bin,
  21178. from: data.msg_from,
  21179. id: data.msg_mid,
  21180. timestamp: data.msg_timestamp,
  21181. updatedAt: data.patch_timestamp
  21182. };
  21183. delete data.lastMessageFrom;
  21184. delete data.lastMessageId;
  21185. delete data.lastMessageTimestamp;
  21186. delete data.lastMessagePatchTimestamp;
  21187. }
  21188. const {
  21189. ttl
  21190. } = data;
  21191. if (ttl) data.expiredAt = Date.now() + ttl * 1000;
  21192. return this.parseConversation(data);
  21193. }
  21194. /**
  21195. * 创建一个对话
  21196. * @param {Object} options 除了下列字段外的其他字段将被视为对话的自定义属性
  21197. * @param {String[]} options.members 对话的初始成员列表,默认包含当前 client
  21198. * @param {String} [options.name] 对话的名字
  21199. * @param {Boolean} [options.unique=true] 唯一对话,当其为 true 时,如果当前已经有相同成员的对话存在则返回该对话,否则会创建新的对话
  21200. * @return {Promise.<Conversation>}
  21201. */
  21202. async createConversation({
  21203. members: m,
  21204. name,
  21205. transient,
  21206. unique = true,
  21207. _tempConv: tempConv,
  21208. _tempConvTTL: tempConvTTL,
  21209. ...properties
  21210. } = {}) {
  21211. if (!(transient || Array.isArray(m))) {
  21212. throw new TypeError(`conversation members ${m} is not an array`);
  21213. }
  21214. let members = new Set(m);
  21215. members.add(this.id);
  21216. members = Array.from(members).sort();
  21217. let attr = properties || {};
  21218. if (name) {
  21219. if (typeof name !== 'string') {
  21220. throw new TypeError(`conversation name ${name} is not a string`);
  21221. }
  21222. attr.name = name;
  21223. }
  21224. attr = new JsonObjectMessage({
  21225. data: JSON.stringify(encode(attr))
  21226. });
  21227. const startCommandJson = {
  21228. m: members,
  21229. attr,
  21230. transient,
  21231. unique,
  21232. tempConv,
  21233. tempConvTTL
  21234. };
  21235. const command = new GenericCommand({
  21236. cmd: 'conv',
  21237. op: 'start',
  21238. convMessage: new ConvCommand(startCommandJson)
  21239. });
  21240. if (this.options.conversationSignatureFactory) {
  21241. const params = [null, this._identity, members, 'create'];
  21242. const signatureResult = await runSignatureFactory(this.options.conversationSignatureFactory, params);
  21243. Object.assign(command.convMessage, keyRemap({
  21244. signature: 's',
  21245. timestamp: 't',
  21246. nonce: 'n'
  21247. }, signatureResult));
  21248. }
  21249. const {
  21250. convMessage: {
  21251. cid,
  21252. cdate,
  21253. tempConvTTL: ttl
  21254. }
  21255. } = await this._send(command);
  21256. const data = {
  21257. name,
  21258. transient,
  21259. unique,
  21260. id: cid,
  21261. createdAt: cdate,
  21262. updatedAt: cdate,
  21263. lastMessageAt: null,
  21264. creator: this.id,
  21265. members: transient ? [] : members,
  21266. ...properties
  21267. };
  21268. if (ttl) data.expiredAt = Date.now() + ttl * 1000;
  21269. const conversation = await this.parseConversation(data);
  21270. return this._upsertConversationToCache(conversation);
  21271. }
  21272. /**
  21273. * 创建一个聊天室
  21274. * @since 4.0.0
  21275. * @param {Object} options 除了下列字段外的其他字段将被视为对话的自定义属性
  21276. * @param {String} [options.name] 对话的名字
  21277. * @return {Promise.<ChatRoom>}
  21278. */
  21279. async createChatRoom(param) {
  21280. return this.createConversation({ ...param,
  21281. transient: true,
  21282. members: null,
  21283. unique: false,
  21284. _tempConv: false
  21285. });
  21286. }
  21287. /**
  21288. * 创建一个临时对话
  21289. * @since 4.0.0
  21290. * @param {Object} options
  21291. * @param {String[]} options.members 对话的初始成员列表,默认包含当前 client
  21292. * @param {String} [options.ttl] 对话存在时间,单位为秒,最大值与默认值均为 86400(一天),过期后该对话不再可用。
  21293. * @return {Promise.<TemporaryConversation>}
  21294. */
  21295. async createTemporaryConversation({
  21296. ttl: _tempConvTTL,
  21297. ...param
  21298. }) {
  21299. return this.createConversation({ ...param,
  21300. _tempConv: true,
  21301. _tempConvTTL
  21302. });
  21303. } // jsdoc-ignore-start
  21304. // jsdoc-ignore-end
  21305. _doSendRead() {
  21306. // if not connected, just skip everything
  21307. if (!this._connection.is('connected')) return;
  21308. const buffer = internal(this).readConversationsBuffer;
  21309. const conversations = Array.from(buffer);
  21310. if (!conversations.length) return;
  21311. const ids = conversations.map(conversation => {
  21312. if (!(conversation instanceof ConversationBase)) {
  21313. throw new TypeError(`${conversation} is not a Conversation`);
  21314. }
  21315. return conversation.id;
  21316. });
  21317. this._debug(`mark [${ids}] as read`);
  21318. buffer.clear();
  21319. this._sendReadCommand(conversations).catch(error => {
  21320. this._debug('send read failed: %O', error);
  21321. conversations.forEach(buffer.add.bind(buffer));
  21322. });
  21323. }
  21324. _sendReadCommand(conversations) {
  21325. return this._send(new GenericCommand({
  21326. cmd: 'read',
  21327. readMessage: new ReadCommand({
  21328. convs: conversations.map(conversation => new ReadTuple({
  21329. cid: conversation.id,
  21330. mid: conversation.lastMessage && conversation.lastMessage.from !== this.id ? conversation.lastMessage.id : undefined,
  21331. timestamp: (conversation.lastMessageAt || new Date()).getTime()
  21332. }))
  21333. })
  21334. }), false);
  21335. }
  21336. }, (_applyDecoratedDescriptor(_class$3.prototype, "_doSendAck", [_dec$2], Object.getOwnPropertyDescriptor(_class$3.prototype, "_doSendAck"), _class$3.prototype), _applyDecoratedDescriptor(_class$3.prototype, "_doSendRead", [_dec2], Object.getOwnPropertyDescriptor(_class$3.prototype, "_doSendRead"), _class$3.prototype)), _class$3));
  21337. /**
  21338. * 修改、撤回消息的原因
  21339. * @typedef PatchReason
  21340. * @type {Object}
  21341. * @property {number} code 负数为内置 code,正数为开发者在 hook 中自定义的 code。比如因为敏感词过滤被修改的 code 为 -4408。
  21342. * @property {string} [detail] 具体的原因说明。
  21343. */
  21344. const RECONNECT_ERROR = 'reconnecterror';
  21345. var CoreEvent = /*#__PURE__*/Object.freeze({
  21346. __proto__: null,
  21347. RECONNECT_ERROR: RECONNECT_ERROR,
  21348. DISCONNECT: DISCONNECT,
  21349. RECONNECT: RECONNECT,
  21350. RETRY: RETRY,
  21351. SCHEDULE: SCHEDULE,
  21352. OFFLINE: OFFLINE,
  21353. ONLINE: ONLINE
  21354. });
  21355. var _class$4;
  21356. let // jsdoc-ignore-end
  21357. BinaryMessage = IE10Compatible(_class$4 = class BinaryMessage extends Message {
  21358. /**
  21359. * 二进制消息
  21360. * @extends Message
  21361. * @param {ArrayBuffer} buffer
  21362. * @since 4.0.0
  21363. */
  21364. constructor(buffer) {
  21365. if (!(buffer instanceof ArrayBuffer)) {
  21366. throw new TypeError(`${buffer} is not an ArrayBuffer`);
  21367. }
  21368. super(buffer);
  21369. }
  21370. /**
  21371. * @type ArrayBuffer
  21372. */
  21373. get buffer() {
  21374. return this.content;
  21375. }
  21376. set buffer(buffer) {
  21377. this.content = buffer;
  21378. }
  21379. static validate(target) {
  21380. return target instanceof ArrayBuffer;
  21381. }
  21382. toJSON() {
  21383. return { ...super._toJSON(),
  21384. data: base64Arraybuffer_1(this.content)
  21385. };
  21386. }
  21387. toFullJSON() {
  21388. return { ...super.toFullJSON(),
  21389. bin: true,
  21390. data: base64Arraybuffer_1(this.content)
  21391. };
  21392. }
  21393. }) || _class$4;
  21394. var _dec$3, _class$5;
  21395. let // jsdoc-ignore-end
  21396. TextMessage = (_dec$3 = messageType(-1), _dec$3(_class$5 = IE10Compatible(_class$5 = class TextMessage extends TypedMessage {
  21397. /**
  21398. * 文类类型消息
  21399. * @extends TypedMessage
  21400. * @param {String} [text='']
  21401. * @throws {TypeError} text 不是 String 类型
  21402. */
  21403. constructor(text = '') {
  21404. if (typeof text !== 'string') {
  21405. throw new TypeError(`${text} is not a string`);
  21406. }
  21407. super();
  21408. this.setText(text);
  21409. }
  21410. }) || _class$5) || _class$5);
  21411. /**
  21412. * @name TYPE
  21413. * @memberof TextMessage
  21414. * @type Number
  21415. * @static
  21416. * @const
  21417. */
  21418. var _class$6;
  21419. const debug$c = browser('LC:MessageParser');
  21420. const tryParseJson = (target, key, descriptor) => {
  21421. const fn = descriptor.value; // eslint-disable-next-line no-param-reassign
  21422. descriptor.value = function wrapper(param) {
  21423. let content;
  21424. if (typeof param !== 'string') {
  21425. content = param;
  21426. } else {
  21427. try {
  21428. content = JSON.parse(param);
  21429. } catch (error) {
  21430. content = param;
  21431. }
  21432. }
  21433. return fn.call(this, content);
  21434. };
  21435. };
  21436. const applyPlugins = (target, key, descriptor) => {
  21437. const fn = descriptor.value; // eslint-disable-next-line no-param-reassign
  21438. descriptor.value = function wrapper(json) {
  21439. return Promise.resolve(json).then(applyMiddlewares(this._plugins.beforeMessageParse)).then(decoratedJson => fn.call(this, decoratedJson)).then(applyMiddlewares(this._plugins.afterMessageParse));
  21440. };
  21441. };
  21442. let MessageParser = (_class$6 = class MessageParser {
  21443. /**
  21444. * 消息解析器
  21445. * @param {Object} plugins 插件,插件的 messageClasses 会自动被注册,在解析时 beforeMessageParse 与 afterMessageParse Middleware 会被应用。
  21446. */
  21447. constructor(plugins = {}) {
  21448. this._plugins = plugins;
  21449. this._messageClasses = [];
  21450. this.register(plugins.messageClasses);
  21451. }
  21452. /**
  21453. * 注册消息类
  21454. *
  21455. * @param {Function | Function[]} messageClass 消息类,需要实现 {@link AVMessage} 接口,
  21456. * 建议继承自 {@link TypedMessage},也可以传入一个消息类数组。
  21457. * @throws {TypeError} 如果 messageClass 没有实现 {@link AVMessage} 接口则抛出异常
  21458. */
  21459. register(messageClasses) {
  21460. ensureArray(messageClasses).map(klass => this._register(klass));
  21461. }
  21462. _register(messageClass) {
  21463. if (messageClass && messageClass.parse && messageClass.prototype && messageClass.prototype.getPayload) {
  21464. this._messageClasses.unshift(messageClass);
  21465. } else {
  21466. throw new TypeError('Invalid messageClass');
  21467. }
  21468. } // jsdoc-ignore-start
  21469. // jsdoc-ignore-end
  21470. /**
  21471. * 解析消息内容
  21472. * @param {Object | string | any} target 消息内容,如果是字符串会尝试 parse 为 JSON。
  21473. * @return {AVMessage} 解析后的消息
  21474. * @throws {Error} 如果不匹配任何注册的消息则抛出异常
  21475. */
  21476. parse(content) {
  21477. debug$c('parsing message: %O', content); // eslint-disable-next-line
  21478. for (const Klass of this._messageClasses) {
  21479. const contentCopy = isPlainObject_1(content) ? { ...content
  21480. } : content;
  21481. let valid;
  21482. let result;
  21483. try {
  21484. valid = Klass.validate(contentCopy);
  21485. } catch (error) {// eslint-disable-line no-empty
  21486. }
  21487. if (valid) {
  21488. try {
  21489. result = Klass.parse(contentCopy);
  21490. } catch (error) {
  21491. console.warn('parsing a valid message content error', {
  21492. error,
  21493. Klass,
  21494. content: contentCopy
  21495. });
  21496. }
  21497. if (result !== undefined) {
  21498. debug$c('parse result: %O', result);
  21499. return result;
  21500. }
  21501. }
  21502. }
  21503. throw new Error('No Message Class matched');
  21504. }
  21505. }, (_applyDecoratedDescriptor(_class$6.prototype, "parse", [tryParseJson, applyPlugins], Object.getOwnPropertyDescriptor(_class$6.prototype, "parse"), _class$6.prototype)), _class$6);
  21506. /** @module leancloud-realtime */
  21507. const debug$d = browser('LC:IMPlugin');
  21508. /**
  21509. * 消息优先级枚举
  21510. * @enum {Number}
  21511. * @since 3.3.0
  21512. */
  21513. const MessagePriority = {
  21514. /** 高 */
  21515. HIGH: 1,
  21516. /** 普通 */
  21517. NORMAL: 2,
  21518. /** 低 */
  21519. LOW: 3
  21520. };
  21521. Object.freeze(MessagePriority);
  21522. /**
  21523. * 为 Conversation 定义一个新属性
  21524. * @param {String} prop 属性名
  21525. * @param {Object} [descriptor] 属性的描述符,参见 {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor#Description getOwnPropertyDescriptor#Description - MDN},默认为该属性名对应的 Conversation 自定义属性的 getter/setter
  21526. * @returns void
  21527. * @example
  21528. *
  21529. * conversation.get('type');
  21530. * conversation.set('type', 1);
  21531. *
  21532. * // equals to
  21533. * defineConversationProperty('type');
  21534. * conversation.type;
  21535. * conversation.type = 1;
  21536. */
  21537. const defineConversationProperty = (prop, descriptor = {
  21538. get() {
  21539. return this.get(prop);
  21540. },
  21541. set(value) {
  21542. this.set(prop, value);
  21543. }
  21544. }) => {
  21545. Object.defineProperty(Conversation.prototype, prop, descriptor);
  21546. };
  21547. const onRealtimeCreate = realtime => {
  21548. /* eslint-disable no-param-reassign */
  21549. const deviceId = v4_1();
  21550. realtime._IMClients = {};
  21551. realtime._IMClientsCreationCount = 0;
  21552. const messageParser = new MessageParser(realtime._plugins);
  21553. realtime._messageParser = messageParser;
  21554. const signAVUser = async user => realtime._request({
  21555. method: 'POST',
  21556. path: '/rtm/sign',
  21557. data: {
  21558. session_token: user.getSessionToken()
  21559. }
  21560. });
  21561. /**
  21562. * 注册消息类
  21563. *
  21564. * 在接收消息、查询消息时,会按照消息类注册顺序的逆序依次尝试解析消息内容
  21565. *
  21566. * @memberof Realtime
  21567. * @instance
  21568. * @param {Function | Function[]} messageClass 消息类,需要实现 {@link AVMessage} 接口,
  21569. * 建议继承自 {@link TypedMessage}
  21570. * @throws {TypeError} 如果 messageClass 没有实现 {@link AVMessage} 接口则抛出异常
  21571. */
  21572. const register = messageParser.register.bind(messageParser);
  21573. /**
  21574. * 创建一个即时通讯客户端,多次创建相同 id 的客户端会返回同一个实例
  21575. * @memberof Realtime
  21576. * @instance
  21577. * @param {String|AV.User} [identity] 客户端 identity,如果不指定该参数,服务端会随机生成一个字符串作为 identity,
  21578. * 如果传入一个已登录的 AV.User,则会使用该用户的 id 作为客户端 identity 登录。
  21579. * @param {Object} [options]
  21580. * @param {Function} [options.signatureFactory] open session 时的签名方法 // TODO need details
  21581. * @param {Function} [options.conversationSignatureFactory] 对话创建、增减成员操作时的签名方法
  21582. * @param {Function} [options.blacklistSignatureFactory] 黑名单操作时的签名方法
  21583. * @param {String} [options.tag] 客户端类型标记,以支持单点登录功能
  21584. * @param {String} [options.isReconnect=false] 单点登录时标记该次登录是不是应用启动时自动重新登录
  21585. * @return {Promise.<IMClient>}
  21586. */
  21587. const createIMClient = async (identity, {
  21588. tag,
  21589. isReconnect,
  21590. ...clientOptions
  21591. } = {}, lagecyTag) => {
  21592. let id;
  21593. const buildinOptions = {};
  21594. if (identity) {
  21595. if (typeof identity === 'string') {
  21596. id = identity;
  21597. } else if (identity.id && identity.getSessionToken) {
  21598. ({
  21599. id
  21600. } = identity);
  21601. const sessionToken = identity.getSessionToken();
  21602. if (!sessionToken) {
  21603. throw new Error('User must be authenticated');
  21604. }
  21605. buildinOptions.signatureFactory = signAVUser;
  21606. } else {
  21607. throw new TypeError('Identity must be a String or an AV.User');
  21608. }
  21609. if (realtime._IMClients[id] !== undefined) {
  21610. return realtime._IMClients[id];
  21611. }
  21612. }
  21613. if (lagecyTag) {
  21614. console.warn('DEPRECATION createIMClient tag param: Use options.tag instead.');
  21615. }
  21616. const _tag = tag || lagecyTag;
  21617. const promise = realtime._open().then(connection => {
  21618. const client = new IMClient(id, { ...buildinOptions,
  21619. ...clientOptions
  21620. }, {
  21621. _connection: connection,
  21622. _request: realtime._request.bind(realtime),
  21623. _messageParser: messageParser,
  21624. _plugins: realtime._plugins,
  21625. _identity: identity
  21626. });
  21627. connection.on(RECONNECT, () => client._open(realtime._options.appId, _tag, deviceId, true)
  21628. /**
  21629. * 客户端连接恢复正常,该事件通常在 {@link Realtime#event:RECONNECT} 之后发生
  21630. * @event IMClient#RECONNECT
  21631. * @see Realtime#event:RECONNECT
  21632. * @since 3.2.0
  21633. */
  21634. /**
  21635. * 客户端重新登录发生错误(网络连接已恢复,但重新登录错误)
  21636. * @event IMClient#RECONNECT_ERROR
  21637. * @since 3.2.0
  21638. */
  21639. .then(() => client.emit(RECONNECT), error => client.emit(RECONNECT_ERROR, error)));
  21640. internal(client)._eventemitter.on('beforeclose', () => {
  21641. delete realtime._IMClients[client.id];
  21642. if (realtime._firstIMClient === client) {
  21643. delete realtime._firstIMClient;
  21644. }
  21645. }, realtime);
  21646. internal(client)._eventemitter.on('close', () => {
  21647. realtime._deregister(client);
  21648. }, realtime);
  21649. return client._open(realtime._options.appId, _tag, deviceId, isReconnect).then(() => {
  21650. realtime._IMClients[client.id] = client;
  21651. realtime._IMClientsCreationCount += 1;
  21652. if (realtime._IMClientsCreationCount === 1) {
  21653. client._omitPeerId(true);
  21654. realtime._firstIMClient = client;
  21655. } else if (realtime._IMClientsCreationCount > 1 && realtime._firstIMClient) {
  21656. realtime._firstIMClient._omitPeerId(false);
  21657. }
  21658. realtime._register(client);
  21659. return client;
  21660. }).catch(error => {
  21661. delete realtime._IMClients[client.id];
  21662. throw error;
  21663. });
  21664. }).then(...finalize(() => {
  21665. realtime._deregisterPending(promise);
  21666. })).catch(error => {
  21667. delete realtime._IMClients[id];
  21668. throw error;
  21669. });
  21670. if (identity) {
  21671. realtime._IMClients[id] = promise;
  21672. }
  21673. realtime._registerPending(promise);
  21674. return promise;
  21675. };
  21676. Object.assign(realtime, {
  21677. register,
  21678. createIMClient
  21679. });
  21680. /* eslint-enable no-param-reassign */
  21681. };
  21682. const beforeCommandDispatch = (command, realtime) => {
  21683. const isIMCommand = command.service === null || command.service === 2;
  21684. if (!isIMCommand) return true;
  21685. const targetClient = command.peerId ? realtime._IMClients[command.peerId] : realtime._firstIMClient;
  21686. if (targetClient) {
  21687. Promise.resolve(targetClient).then(client => client._dispatchCommand(command)).catch(debug$d);
  21688. } else {
  21689. debug$d('[WARN] Unexpected message received without any live client match: %O', trim(command));
  21690. }
  21691. return false;
  21692. };
  21693. const IMPlugin = {
  21694. name: 'leancloud-realtime-plugin-im',
  21695. onRealtimeCreate,
  21696. beforeCommandDispatch,
  21697. messageClasses: [Message, BinaryMessage, RecalledMessage, TextMessage]
  21698. };
  21699. /** @module leancloud-realtime */
  21700. Realtime.defineConversationProperty = defineConversationProperty;
  21701. Realtime.__preRegisteredPlugins = [IMPlugin];
  21702. const Event = { ...CoreEvent,
  21703. ...IMEvent
  21704. };
  21705. /** core + plugins + platform adapters */
  21706. setAdapters({
  21707. WebSocket: lib_1,
  21708. request: lib_4
  21709. });
  21710. exports.BinaryMessage = BinaryMessage;
  21711. exports.ChatRoom = ChatRoom;
  21712. exports.Conversation = Conversation;
  21713. exports.ConversationMemberRole = ConversationMemberRole;
  21714. exports.ConversationQuery = ConversationQuery;
  21715. exports.ErrorCode = ErrorCode;
  21716. exports.Event = Event;
  21717. exports.EventEmitter = eventemitter3;
  21718. exports.IE10Compatible = IE10Compatible;
  21719. exports.IMPlugin = IMPlugin;
  21720. exports.Message = Message;
  21721. exports.MessageParser = MessageParser;
  21722. exports.MessagePriority = MessagePriority;
  21723. exports.MessageQueryDirection = MessageQueryDirection;
  21724. exports.MessageStatus = MessageStatus;
  21725. exports.Promise = polyfilledPromise;
  21726. exports.Protocals = message;
  21727. exports.Protocols = message;
  21728. exports.Realtime = Realtime;
  21729. exports.RecalledMessage = RecalledMessage;
  21730. exports.ServiceConversation = ServiceConversation;
  21731. exports.TemporaryConversation = TemporaryConversation;
  21732. exports.TextMessage = TextMessage;
  21733. exports.TypedMessage = TypedMessage;
  21734. exports.debug = debug$2;
  21735. exports.defineConversationProperty = defineConversationProperty;
  21736. exports.getAdapter = getAdapter;
  21737. exports.messageField = messageField;
  21738. exports.messageType = messageType;
  21739. exports.setAdapters = setAdapters;
  21740. Object.defineProperty(exports, '__esModule', { value: true });
  21741. })));
  21742. //# sourceMappingURL=im-weapp.js.map